added several functions into Socket that accepts a length-bounded interface name
This commit is contained in:
		| @ -58,9 +58,12 @@ public: | |||||||
|  |  | ||||||
| 	qse_sck_hnd_t getHandle() const QSE_CPP_NOEXCEPT { return this->handle; } | 	qse_sck_hnd_t getHandle() const QSE_CPP_NOEXCEPT { return this->handle; } | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
|  |  | ||||||
| 	int getOption (int level, int optname, void* optval, qse_sck_len_t* optlen) QSE_CPP_NOEXCEPT; | 	int getOption (int level, int optname, void* optval, qse_sck_len_t* optlen) QSE_CPP_NOEXCEPT; | ||||||
| 	int setOption (int level, int optname, const void* optval, qse_sck_len_t optlen) QSE_CPP_NOEXCEPT; | 	int setOption (int level, int optname, const void* optval, qse_sck_len_t optlen) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
| 	int setDebug (int n) QSE_CPP_NOEXCEPT; | 	int setDebug (int n) QSE_CPP_NOEXCEPT; | ||||||
| 	int setReuseAddr (int n) QSE_CPP_NOEXCEPT; | 	int setReuseAddr (int n) QSE_CPP_NOEXCEPT; | ||||||
| 	int setReusePort (int n) QSE_CPP_NOEXCEPT; | 	int setReusePort (int n) QSE_CPP_NOEXCEPT; | ||||||
| @ -74,9 +77,11 @@ public: | |||||||
| 	int setOobInline (int n) QSE_CPP_NOEXCEPT; | 	int setOobInline (int n) QSE_CPP_NOEXCEPT; | ||||||
| 	int setIpv6Only (int n) QSE_CPP_NOEXCEPT; | 	int setIpv6Only (int n) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
| 	int shutdown (int how = 2) QSE_CPP_NOEXCEPT; | 	int shutdown (int how = 2) QSE_CPP_NOEXCEPT; | ||||||
| 	int connect (const SocketAddress& target) QSE_CPP_NOEXCEPT; | 	int connect (const SocketAddress& target) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
| 	int bind (const SocketAddress& target) QSE_CPP_NOEXCEPT; | 	int bind (const SocketAddress& target) QSE_CPP_NOEXCEPT; | ||||||
| 	// bind to the ip address of the interface  | 	// bind to the ip address of the interface  | ||||||
| 	int bindToIfceAddr (const qse_mchar_t* ifce, qse_uint16_t port) QSE_CPP_NOEXCEPT; | 	int bindToIfceAddr (const qse_mchar_t* ifce, qse_uint16_t port) QSE_CPP_NOEXCEPT; | ||||||
| @ -88,10 +93,12 @@ public: | |||||||
| 	// bind to the interface device | 	// bind to the interface device | ||||||
| 	int bindToIfce (const qse_wchar_t* ifce) QSE_CPP_NOEXCEPT; | 	int bindToIfce (const qse_wchar_t* ifce) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
|  |  | ||||||
| 	int listen (int backlog = 128) QSE_CPP_NOEXCEPT; | 	int listen (int backlog = 128) QSE_CPP_NOEXCEPT; | ||||||
| 	int accept (Socket* newsck, SocketAddress* newaddr, int traits = 0) QSE_CPP_NOEXCEPT; | 	int accept (Socket* newsck, SocketAddress* newaddr, int traits = 0) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
| 	// The send() functions sends data by attemping a single call to the  | 	// The send() functions sends data by attemping a single call to the  | ||||||
| 	// underlying system calls | 	// underlying system calls | ||||||
| 	qse_ssize_t send (const void* buf, qse_size_t len) QSE_CPP_NOEXCEPT; | 	qse_ssize_t send (const void* buf, qse_size_t len) QSE_CPP_NOEXCEPT; | ||||||
| @ -106,14 +113,21 @@ public: | |||||||
| 	qse_ssize_t receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT; | 	qse_ssize_t receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT; | ||||||
| 	qse_ssize_t receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT; | 	qse_ssize_t receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
| /* TODO: sendmsg, recvmsg */ | 	// --------------------------------------------------------------------  | ||||||
|  |  | ||||||
| 	int joinMulticastGroup (const SocketAddress& mcaddr, const SocketAddress& ifaddr) QSE_CPP_NOEXCEPT; | 	int joinMulticastGroup (const SocketAddress& mcaddr, const SocketAddress& ifaddr) QSE_CPP_NOEXCEPT; | ||||||
| 	int leaveMulticastGroup (const SocketAddress& mcaddr, const SocketAddress& ifaddr) QSE_CPP_NOEXCEPT; | 	int leaveMulticastGroup (const SocketAddress& mcaddr, const SocketAddress& ifaddr) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
|  |  | ||||||
| 	// utility functions to retrieve network configuration information. | 	// utility functions to retrieve network configuration information. | ||||||
| 	int getIfceIndex (const qse_mchar_t* name) QSE_CPP_NOEXCEPT; | 	int getIfceIndex (const qse_mchar_t* name) QSE_CPP_NOEXCEPT; | ||||||
| 	int getIfceIndex (const qse_wchar_t* name) QSE_CPP_NOEXCEPT; | 	int getIfceIndex (const qse_wchar_t* name) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	int getIfceIndex (const qse_mchar_t* name, qse_size_t len) QSE_CPP_NOEXCEPT; | ||||||
|  | 	int getIfceIndex (const qse_wchar_t* name, qse_size_t len) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
| 	// the following 6 functions are provided for backward compatibility. | 	// the following 6 functions are provided for backward compatibility. | ||||||
| 	// it is limited to a single address and they may suffer race condition. | 	// it is limited to a single address and they may suffer race condition. | ||||||
| 	// for example, you call getIfceAddress() followed by getIfceNetmask(). | 	// for example, you call getIfceAddress() followed by getIfceNetmask(). | ||||||
| @ -126,13 +140,22 @@ public: | |||||||
| 	int getIfceBroadcast (const qse_mchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT; | 	int getIfceBroadcast (const qse_mchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT; | ||||||
| 	int getIfceBroadcast (const qse_wchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT; | 	int getIfceBroadcast (const qse_wchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT; | ||||||
|  |  | ||||||
|  | 	int getIfceAddress (const qse_mchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT; | ||||||
|  | 	int getIfceAddress (const qse_wchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT; | ||||||
|  | 	int getIfceNetmask (const qse_mchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT; | ||||||
|  | 	int getIfceNetmask (const qse_wchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT; | ||||||
|  | 	int getIfceBroadcast (const qse_mchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT; | ||||||
|  | 	int getIfceBroadcast (const qse_wchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT; | ||||||
|  | 	// --------------------------------------------------------------------  | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
| 	qse_sck_hnd_t handle; | 	qse_sck_hnd_t handle; | ||||||
| 	int domain; | 	int domain; | ||||||
| 	ErrorCode errcode; | 	ErrorCode errcode; | ||||||
|  |  | ||||||
| 	void set_errcode_with_syserr (int syserr); | 	void set_errcode_with_syserr (int syserr); | ||||||
| 	int get_ifce_address (int cmd, const void* name, bool wchar, SocketAddress* addr); | 	int get_ifce_index (const void* name, qse_size_t len, bool wchar); | ||||||
|  | 	int get_ifce_address (int cmd, const void* name, qse_size_t len, bool wchar, SocketAddress* addr); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -741,46 +741,49 @@ int Socket::leaveMulticastGroup (const SocketAddress& mcaddr, const SocketAddres | |||||||
|  |  | ||||||
| int Socket::getIfceIndex (const qse_mchar_t* name) QSE_CPP_NOEXCEPT | int Socket::getIfceIndex (const qse_mchar_t* name) QSE_CPP_NOEXCEPT | ||||||
| { | { | ||||||
| #if defined(SIOCGIFINDEX) | 	return this->get_ifce_index(name, qse_mbslen(name), false); | ||||||
| 	struct ifreq ifr; |  | ||||||
|  |  | ||||||
| 	QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr)); |  | ||||||
| 	qse_size_t mlen = qse_mbsxcpy (ifr.ifr_name, QSE_COUNTOF(ifr.ifr_name), name); |  | ||||||
| 	if (name[mlen] != QSE_MT('\0'))  |  | ||||||
| 	{ |  | ||||||
| 		this->setErrorCode (E_EINVAL); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (::ioctl(this->handle, SIOCGIFINDEX, &ifr) == -1)  |  | ||||||
| 	{ |  | ||||||
| 		this->setErrorCode (syserr_to_errnum(errno)); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	#if defined(ifr_ifindex) |  | ||||||
| 	return ifr.ifr_ifindex; |  | ||||||
| 	#else |  | ||||||
| 	return ifr.ifr_index; |  | ||||||
| 	#endif |  | ||||||
| #else |  | ||||||
| 	this->setErrorCode (E_ENOIMPL); |  | ||||||
| 	return -1; |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int Socket::getIfceIndex (const qse_wchar_t* name) QSE_CPP_NOEXCEPT | int Socket::getIfceIndex (const qse_wchar_t* name) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_index(name, qse_wcslen(name), false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::getIfceIndex (const qse_mchar_t* name, qse_size_t len) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_index(name, len, false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::getIfceIndex (const qse_wchar_t* name, qse_size_t len) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_index(name, len, false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::get_ifce_index (const void* name, qse_size_t len, bool wchar) | ||||||
| { | { | ||||||
| #if defined(SIOCGIFINDEX) | #if defined(SIOCGIFINDEX) | ||||||
| 	struct ifreq ifr; | 	struct ifreq ifr; | ||||||
|  |  | ||||||
| 	QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr)); | 	QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr)); | ||||||
|  |  | ||||||
| 	qse_size_t wlen, mlen = QSE_COUNTOF(ifr.ifr_name); | 	if (wchar) | ||||||
| 	if (qse_wcstombs(name, &wlen, ifr.ifr_name, &mlen) <= -1 || name[wlen] != QSE_WT('\0'))  |  | ||||||
| 	{ | 	{ | ||||||
| 		this->setErrorCode (E_EINVAL); | 		qse_size_t wlen = len, mlen = QSE_COUNTOF(ifr.ifr_name) - 1; | ||||||
| 		return -1; | 		if (qse_wcsntombsn((const qse_wchar_t*)name, &wlen, ifr.ifr_name, &mlen) <= -1 || wlen != len) | ||||||
|  | 		{ | ||||||
|  | 			this->setErrorCode (E_EINVAL); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		ifr.ifr_name[mlen] = QSE_MT('\0'); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		qse_size_t mlen = qse_mbsxncpy(ifr.ifr_name, QSE_COUNTOF(ifr.ifr_name), (const qse_mchar_t*)name, len); | ||||||
|  | 		if (mlen != len) | ||||||
|  | 		{ | ||||||
|  | 			this->setErrorCode (E_EINVAL); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (::ioctl(this->handle, SIOCGIFINDEX, &ifr) == -1)  | 	if (::ioctl(this->handle, SIOCGIFINDEX, &ifr) == -1)  | ||||||
| @ -802,69 +805,70 @@ int Socket::getIfceIndex (const qse_wchar_t* name) QSE_CPP_NOEXCEPT | |||||||
|  |  | ||||||
| int Socket::getIfceAddress (const qse_mchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | int Socket::getIfceAddress (const qse_mchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
| { | { | ||||||
| #if defined(SIOCGIFADDR) | 	return this->get_ifce_address(SIOCGIFADDR, name, qse_mbslen(name), false, addr); | ||||||
| 	return this->get_ifce_address(SIOCGIFADDR, name, false, addr); |  | ||||||
| #else |  | ||||||
| 	this->setErrorCode (E_ENOIMPL); |  | ||||||
| 	return -1; |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int Socket::getIfceAddress (const qse_wchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | int Socket::getIfceAddress (const qse_wchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
| { | { | ||||||
| #if defined(SIOCGIFADDR) | 	return this->get_ifce_address(SIOCGIFADDR, name, qse_wcslen(name), true, addr); | ||||||
| 	return this->get_ifce_address(SIOCGIFADDR, name, true, addr); |  | ||||||
| #else |  | ||||||
| 	this->setErrorCode (E_ENOIMPL); |  | ||||||
| 	return -1; |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int Socket::getIfceNetmask(const qse_mchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | int Socket::getIfceNetmask(const qse_mchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
| { | { | ||||||
| #if defined(SIOCGIFNETMASK) | 	return this->get_ifce_address(SIOCGIFNETMASK, name, qse_mbslen(name), false, addr); | ||||||
| 	return this->get_ifce_address(SIOCGIFNETMASK, name, false, addr); |  | ||||||
| #else |  | ||||||
| 	this->setErrorCode (E_ENOIMPL); |  | ||||||
| 	return -1; |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int Socket::getIfceNetmask (const qse_wchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | int Socket::getIfceNetmask (const qse_wchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
| { | { | ||||||
| #if defined(SIOCGIFNETMASK) | 	return this->get_ifce_address(SIOCGIFNETMASK, name, qse_wcslen(name), true, addr); | ||||||
| 	return this->get_ifce_address(SIOCGIFNETMASK, name, true, addr); |  | ||||||
| #else |  | ||||||
| 	this->setErrorCode (E_ENOIMPL); |  | ||||||
| 	return -1; |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int Socket::getIfceBroadcast(const qse_mchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | int Socket::getIfceBroadcast(const qse_mchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
| { | { | ||||||
| #if defined(SIOCGIFBRDADDR) | 	return this->get_ifce_address(SIOCGIFBRDADDR, name, qse_mbslen(name), false, addr); | ||||||
| 	return this->get_ifce_address(SIOCGIFBRDADDR, name, false, addr); |  | ||||||
| #else |  | ||||||
| 	this->setErrorCode (E_ENOIMPL); |  | ||||||
| 	return -1; |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int Socket::getIfceBroadcast (const qse_wchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | int Socket::getIfceBroadcast (const qse_wchar_t* name, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
| { | { | ||||||
| #if defined(SIOCGIFBRDADDR) | 	return this->get_ifce_address(SIOCGIFBRDADDR, name, qse_wcslen(name), true, addr); | ||||||
| 	return this->get_ifce_address(SIOCGIFBRDADDR, name, true, addr); |  | ||||||
| #else |  | ||||||
| 	this->setErrorCode (E_ENOIMPL); |  | ||||||
| 	return -1; |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int Socket::get_ifce_address (int cmd, const void* name, bool wchar, SocketAddress* addr) | int Socket::getIfceAddress (const qse_mchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_address(SIOCGIFADDR, name, len, false, addr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::getIfceAddress (const qse_wchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_address(SIOCGIFADDR, name, len, true, addr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::getIfceNetmask(const qse_mchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_address(SIOCGIFNETMASK, name, len, false, addr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::getIfceNetmask (const qse_wchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_address(SIOCGIFNETMASK, name, len, true, addr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::getIfceBroadcast(const qse_mchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_address(SIOCGIFBRDADDR, name, len, false, addr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::getIfceBroadcast (const qse_wchar_t* name, qse_size_t len, SocketAddress* addr) QSE_CPP_NOEXCEPT | ||||||
|  | { | ||||||
|  | 	return this->get_ifce_address(SIOCGIFBRDADDR, name, len, true, addr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Socket::get_ifce_address (int cmd, const void* name, qse_size_t len, bool wchar, SocketAddress* addr) | ||||||
| { | { | ||||||
| 	struct ifreq ifr; | 	struct ifreq ifr; | ||||||
|  |  | ||||||
| 	QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr)); | 	QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr)); | ||||||
|  | #if 0 | ||||||
| 	if (wchar) | 	if (wchar) | ||||||
| 	{ | 	{ | ||||||
| 		qse_size_t wlen, mlen = QSE_COUNTOF(ifr.ifr_name); | 		qse_size_t wlen, mlen = QSE_COUNTOF(ifr.ifr_name); | ||||||
| @ -884,6 +888,27 @@ int Socket::get_ifce_address (int cmd, const void* name, bool wchar, SocketAddre | |||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | #else | ||||||
|  | 	if (wchar) | ||||||
|  | 	{ | ||||||
|  | 		qse_size_t wlen = len, mlen = QSE_COUNTOF(ifr.ifr_name) - 1; | ||||||
|  | 		if (qse_wcsntombsn((const qse_wchar_t*)name, &wlen, ifr.ifr_name, &mlen) <= -1 || wlen != len) | ||||||
|  | 		{ | ||||||
|  | 			this->setErrorCode (E_EINVAL); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		ifr.ifr_name[mlen] = QSE_MT('\0'); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		qse_size_t mlen = qse_mbsxncpy(ifr.ifr_name, QSE_COUNTOF(ifr.ifr_name), (const qse_mchar_t*)name, len); | ||||||
|  | 		if (mlen != len) | ||||||
|  | 		{ | ||||||
|  | 			this->setErrorCode (E_EINVAL); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #if defined(HAVE_GETIFADDRS) | #if defined(HAVE_GETIFADDRS) | ||||||
| 	struct ifaddrs* ifa; | 	struct ifaddrs* ifa; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user