10 #define SHUT_RDWR SD_BOTH
15 #include <netinet/in.h>
16 #include <sys/socket.h>
17 #include <arpa/inet.h>
28 return ip.find(
':') != std::string::npos?IpVersion::IPV6:IpVersion::IPV4;
57 sinLen =
sizeof(sinIPV4);
58 memset(&sinIPV4, 0, sinLen);
59 sinIPV4.sin_family = AF_INET;
60 sinIPV4.sin_port = htons(
port);
61 sinIPV4.sin_addr.s_addr = inet_addr(
ip.c_str());
67 sinLen =
sizeof(sinIPV6);
68 memset(&sinIPV6, 0, sinLen);
69 sinIPV6.sin6_family = AF_INET6;
70 sinIPV6.sin6_port = htons(
port);
71 inet_pton(AF_INET6,
ip.c_str(), &sinIPV6.sin6_addr);
78 if (::
bind(
descriptor, (
const struct sockaddr*)sin, sinLen) == -1) {
79 std::string msg =
"Could not bind socket: ";
81 msg+= to_string(WSAGetLastError());
83 msg+= strerror(errno);
95 long unsigned int mode = 1;
96 if (ioctlsocket(
descriptor, FIONBIO, &mode) != 0) {
97 std::string msg =
"Could not set socket non blocked: ";
98 msg+= to_string(WSAGetLastError());
105 std::string msg =
"Could not get socket file descriptor settings: ";
106 msg+= strerror(errno);
111 if (fcntl(
descriptor, F_SETFL, fdc | O_NONBLOCK) == -1) {
112 std::string msg =
"Could not set socket non blocked: ";
113 msg+= strerror(errno);
132 #if defined(__MINGW32__) && !defined(__MINGW64__)
134 #define NS_INADDRSZ 4
135 #define NS_IN6ADDRSZ 16
139 int inet_pton4(
const char* src,
void* dst) {
140 uint8_t tmp[NS_INADDRSZ], *tp;
147 while ((ch = *src++) !=
'\0') {
148 if (ch >=
'0' && ch <=
'9') {
149 uint32_t n = *tp * 10 + (ch -
'0');
151 if (saw_digit && *tp == 0)
163 }
else if (ch ==
'.' && saw_digit) {
174 memcpy(dst, tmp, NS_INADDRSZ);
180 int inet_pton6(
int af,
const char* src,
void* dst) {
181 static const char xdigits[] =
"0123456789abcdef";
182 uint8_t tmp[NS_IN6ADDRSZ];
184 uint8_t *tp = (uint8_t*) memset(tmp,
'\0', NS_IN6ADDRSZ);
185 uint8_t *endp = tp + NS_IN6ADDRSZ;
186 uint8_t *colonp = NULL;
194 const char *curtok = src;
198 while ((ch = tolower(*src++)) !=
'\0') {
199 const char *pch = strchr(xdigits, ch);
202 val |= (pch - xdigits);
215 }
else if (*src ==
'\0') {
218 if (tp + NS_INT16SZ > endp)
220 *tp++ = (uint8_t) (val >> 8) & 0xff;
221 *tp++ = (uint8_t) val & 0xff;
226 if (ch ==
'.' && ((tp + NS_INADDRSZ) <= endp)
227 && inet_pton4(curtok, (
char*) tp) > 0) {
235 if (tp + NS_INT16SZ > endp)
237 *tp++ = (uint8_t) (val >> 8) & 0xff;
238 *tp++ = (uint8_t) val & 0xff;
240 if (colonp != NULL) {
245 const int n = tp - colonp;
250 for (
int i = 1; i <= n; i++) {
251 endp[-i] = colonp[n - i];
259 memcpy(dst, tmp, NS_IN6ADDRSZ);
280 size_t strlcpy(
char* __restrict dst,
const char* __restrict src,
size_t siz)
289 if ((*d++ = *s++) ==
'\0')
303 return (s - src - 1);
307 char* inet_ntop4(
const void* src,
char* dst,
size_t size) {
308 static const char fmt[128] =
"%u.%u.%u.%u";
309 char tmp[
sizeof "255.255.255.255"];
313 std::sprintf(tmp, fmt, ((uint8_t*)src)[0], ((uint8_t*)src)[1], ((uint8_t*)src)[2], ((uint8_t*)src)[3]);
314 if (l <= 0 || (socklen_t) l >= size) {
317 strlcpy(dst, tmp, size);
322 char* inet_ntop6(
int af,
const void* src,
char* dst,
size_t size)
331 char tmp[
sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
335 u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
343 memset(words,
'\0',
sizeof words);
344 for (i = 0; i < NS_IN6ADDRSZ; i++)
345 words[i / 2] |= (((uint8_t*)src)[i] << ((1 - (i % 2)) << 3));
350 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
353 cur.base = i, cur.len = 1;
357 if (cur.base != -1) {
358 if (best.base == -1 || cur.len > best.len)
364 if (cur.base != -1) {
365 if (best.base == -1 || cur.len > best.len)
368 if (best.base != -1 && best.len < 2)
375 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
377 if (best.base != -1 && i >= best.base && i < (best.base + best.len)) {
386 if (i == 6 && best.base == 0
387 && (best.len == 6 || (best.len == 7 && words[7] != 0x0001)
388 || (best.len == 5 && words[5] == 0xffff))) {
389 if (!inet_ntop4(src + 12, tp,
sizeof tmp - (tp - tmp)))
394 tp += std::sprintf(tp,
"%x", words[i]);
398 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
405 if ((socklen_t) (tp - tmp) > size) {
Base class of network sockets.
void bind(const string &ip, const unsigned int port)
Binds a socket to local ip and port.
virtual void close()
Closes the socket.
virtual void shutdown()
shuts socket down for reading and writing
static IpVersion determineIpVersion(const string &ip)
Determine IP version.
const string & getAddress()
returns the end points ip address
void setNonBlocked()
sets the socket non blocked
const unsigned int getPort()
returns the end points port
virtual ~NetworkSocket()
public destructor
NetworkSocket()
Protected constructor.