added several functions into Socket that accepts a length-bounded interface name

This commit is contained in:
hyung-hwan 2018-10-19 08:28:12 +00:00
parent 1456f94bd1
commit 5e35f69abb
2 changed files with 118 additions and 70 deletions

View File

@ -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);
}; };

View File

@ -741,47 +741,50 @@ 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')) {
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); this->setErrorCode (E_EINVAL);
return -1; 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;