12 #include "../../stdafx.h" 
   17 #include "../../debug.h" 
   19 #include "../../safeguards.h" 
   41   switch (this->
address.ss_family) {
 
   44       return ntohs(((
const struct sockaddr_in *)&this->
address)->sin_port);
 
   47       return ntohs(((
const struct sockaddr_in6 *)&this->
address)->sin6_port);
 
   60   switch (this->
address.ss_family) {
 
   63       ((
struct sockaddr_in*)&this->
address)->sin_port = htons(port);
 
   67       ((
struct sockaddr_in6*)&this->
address)->sin6_port = htons(port);
 
   83   if (this->
GetAddress()->ss_family == AF_INET6) buffer = 
strecpy(buffer, 
"[", last);
 
   85   if (this->
GetAddress()->ss_family == AF_INET6) buffer = 
strecpy(buffer, 
"]", last);
 
   90     switch (this->
address.ss_family) {
 
   91       case AF_INET:  family = 
'4'; 
break;
 
   92       case AF_INET6: family = 
'6'; 
break;
 
   93       default:       family = 
'?'; 
break;
 
   95     seprintf(buffer, last, 
" (IPv%c)", family);
 
  121   return !INVALID_SOCKET;
 
  152   return this->
address.ss_family == family;
 
  166   int cidr = this->
address.ss_family == AF_INET ? 32 : 128;
 
  171   char *chr_cidr = strchr(netmask, 
'/');
 
  172   if (chr_cidr != NULL) {
 
  173     int tmp_cidr = atoi(chr_cidr + 1);
 
  176     if (tmp_cidr > 0 || tmp_cidr < cidr) cidr = tmp_cidr;
 
  190   switch (this->
address.ss_family) {
 
  192       ip = (uint32*)&((
struct sockaddr_in*)&this->
address)->sin_addr.s_addr;
 
  193       mask = (uint32*)&((
struct sockaddr_in*)&mask_address.
address)->sin_addr.s_addr;
 
  197       ip = (uint32*)&((
struct sockaddr_in6*)&this->
address)->sin6_addr;
 
  198       mask = (uint32*)&((
struct sockaddr_in6*)&mask_address.
address)->sin6_addr;
 
  206     uint32 msk = cidr >= 32 ? (uint32)-1 : htonl(-(1 << (32 - cidr)));
 
  207     if ((*mask++ & msk) != (*ip++ & msk)) 
return false;
 
  227   struct addrinfo hints;
 
  228   memset(&hints, 0, 
sizeof (hints));
 
  229   hints.ai_family   = family;
 
  230   hints.ai_flags    = flags;
 
  231   hints.ai_socktype = socktype;
 
  237   bool reset_hostname = 
false;
 
  242     reset_hostname = 
true;
 
  243     int fam = this->
address.ss_family;
 
  244     if (fam == AF_UNSPEC) fam = family;
 
  250   if (reset_hostname) 
strecpy(this->hostname, 
"", 
lastof(this->hostname));
 
  254       DEBUG(net, 0, 
"getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s failed: %s",
 
  257     return INVALID_SOCKET;
 
  260   SOCKET sock = INVALID_SOCKET;
 
  261   for (
struct addrinfo *runp = ai; runp != NULL; runp = runp->ai_next) {
 
  265     if (sockets != NULL) {
 
  267       if (sockets->
Contains(address)) 
continue;
 
  270     if (sock == INVALID_SOCKET) 
continue;
 
  272     if (sockets == NULL) {
 
  274       assert(
sizeof(this->
address) >= runp->ai_addrlen);
 
  275       memcpy(&this->
address, runp->ai_addr, runp->ai_addrlen);
 
  280     (*sockets)[addr] = sock;
 
  281     sock = INVALID_SOCKET;
 
  299   SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
 
  300   if (sock == INVALID_SOCKET) {
 
  301     DEBUG(net, 1, 
"[%s] could not create %s socket: %s", type, family, strerror(errno));
 
  302     return INVALID_SOCKET;
 
  305   if (!
SetNoDelay(sock)) 
DEBUG(net, 1, 
"[%s] setting TCP_NODELAY failed", type);
 
  307   if (connect(sock, runp->ai_addr, (
int)runp->ai_addrlen) != 0) {
 
  308     DEBUG(net, 1, 
"[%s] could not connect %s socket: %s", type, family, strerror(errno));
 
  310     return INVALID_SOCKET;
 
  316   DEBUG(net, 1, 
"[%s] connected to %s", type, address);
 
  343   SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
 
  344   if (sock == INVALID_SOCKET) {
 
  345     DEBUG(net, 0, 
"[%s] could not create %s socket on port %s: %s", type, family, address, strerror(errno));
 
  346     return INVALID_SOCKET;
 
  349   if (runp->ai_socktype == SOCK_STREAM && !
SetNoDelay(sock)) {
 
  350     DEBUG(net, 3, 
"[%s] setting TCP_NODELAY failed for port %s", type, address);
 
  355   if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (
const char*)&on, 
sizeof(on)) == -1) {
 
  356     DEBUG(net, 3, 
"[%s] could not set reusable %s sockets for port %s: %s", type, family, address, strerror(errno));
 
  360   if (runp->ai_family == AF_INET6 &&
 
  361       setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (
const char*)&on, 
sizeof(on)) == -1) {
 
  362     DEBUG(net, 3, 
"[%s] could not disable IPv4 over IPv6 on port %s: %s", type, address, strerror(errno));
 
  366   if (bind(sock, runp->ai_addr, (
int)runp->ai_addrlen) != 0) {
 
  367     DEBUG(net, 1, 
"[%s] could not bind on %s port %s: %s", type, family, address, strerror(errno));
 
  369     return INVALID_SOCKET;
 
  372   if (runp->ai_socktype != SOCK_DGRAM && listen(sock, 1) != 0) {
 
  373     DEBUG(net, 1, 
"[%s] could not listen at %s port %s: %s", type, family, address, strerror(errno));
 
  375     return INVALID_SOCKET;
 
  379   if (!
SetNonBlocking(sock)) 
DEBUG(net, 0, 
"[%s] setting non-blocking mode failed for %s port %s", type, family, address);
 
  381   DEBUG(net, 1, 
"[%s] listening on %s port %s", type, family, address);
 
  392   assert(sockets != NULL);
 
  415     case SOCK_STREAM: 
return "tcp";
 
  416     case SOCK_DGRAM:  
return "udp";
 
  417     default:          
return "unsupported";
 
  430     case AF_UNSPEC: 
return "either IPv4 or IPv6";
 
  431     case AF_INET:   
return "IPv4";
 
  432     case AF_INET6:  
return "IPv6";
 
  433     default:        
return "unsupported";