X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Fnet.c;h=866e1362da1a4e06a72838d903f7e1c6828dd8ec;hb=d1a6180d8b1dd4b41c1348ec6f84fde7d74d8cdf;hp=410da9661cb7be27bbf18174674a6311c30c7da2;hpb=336539c2c447adabe67af86007b630c5f17bfab1;p=doldaconnect.git diff --git a/daemon/net.c b/daemon/net.c index 410da96..866e136 100644 --- a/daemon/net.c +++ b/daemon/net.c @@ -55,6 +55,12 @@ static struct configvar myvars[] = /* Only for direct mode */ {CONF_VAR_IPV4, "visibleipv4", {.ipv4 = {0}}}, {CONF_VAR_STRING, "publicif", {.str = L""}}, + /* Diffserv should be supported on IPv4, too, but I don't know the + * API to do that. */ + {CONF_VAR_INT, "diffserv-mincost", {.num = 0}}, + {CONF_VAR_INT, "diffserv-maxrel", {.num = 0}}, + {CONF_VAR_INT, "diffserv-maxtp", {.num = 0}}, + {CONF_VAR_INT, "diffserv-mindelay", {.num = 0}}, {CONF_VAR_END} }; @@ -84,7 +90,7 @@ int getpublicaddr(int af, struct sockaddr **addr, socklen_t *lenbuf) *lenbuf = sizeof(*ipv4); return(0); } - if((pif = icwcstombs(confgetstr("net", "publicif"), NULL)) == NULL) + if((pif = icswcstombs(confgetstr("net", "publicif"), NULL, NULL)) == NULL) { flog(LOG_ERR, "could not convert net.publicif into local charset: %s", strerror(errno)); return(-1); @@ -122,12 +128,14 @@ int getpublicaddr(int af, struct sockaddr **addr, socklen_t *lenbuf) memcpy(ipv4, &ifr->ifr_addr, sizeof(ifr->ifr_addr)); } else { free(ipv4); + free(conf.ifc_buf); flog(LOG_WARNING, "could not locate an unambiguous interface for determining your public IP address - set net.publicif"); errno = ENFILE; /* XXX: There's no appropriate one for this... */ return(-1); } } } + free(conf.ifc_buf); close(sock); if(ipv4 != NULL) { @@ -854,16 +862,72 @@ int pollsocks(int timeout) int socksettos(struct socket *sk, int tos) { + int buf; + if(sk->family == AF_INET) { - if(setsockopt(sk->fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0) + switch(tos) + { + case 0: + buf = 0; + break; + case SOCK_TOS_MINCOST: + buf = 0x02; + break; + case SOCK_TOS_MAXREL: + buf = 0x04; + break; + case SOCK_TOS_MAXTP: + buf = 0x08; + break; + case SOCK_TOS_MINDELAY: + buf = 0x10; + break; + default: + flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos); + return(-1); + } + if(setsockopt(sk->fd, SOL_IP, IP_TOS, &buf, sizeof(buf)) < 0) { flog(LOG_WARNING, "could not set sock TOS to %i: %s", tos, strerror(errno)); return(-1); } return(0); } - /* XXX: How does the IPv6 traffic class work? */ + if(sk->family == AF_INET6) + { + switch(tos) + { + case 0: + buf = 0; + case SOCK_TOS_MINCOST: + buf = confgetint("net", "diffserv-mincost"); + break; + case SOCK_TOS_MAXREL: + buf = confgetint("net", "diffserv-maxrel"); + break; + case SOCK_TOS_MAXTP: + buf = confgetint("net", "diffserv-maxtp"); + break; + case SOCK_TOS_MINDELAY: + buf = confgetint("net", "diffserv-mindelay"); + break; + default: + flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos); + return(-1); + } + /* + On Linux, the API IPv6 flow label management doesn't seem to + be entirely complete, so I guess this will have to wait. + + if(setsockopt(...) < 0) + { + flog(LOG_WARNING, "could not set sock traffic class to %i: %s", tos, strerror(errno)); + return(-1); + } + */ + return(0); + } flog(LOG_WARNING, "could not set TOS on sock of family %i", sk->family); return(1); } @@ -1060,7 +1124,7 @@ char *formataddress(struct sockaddr *arg, socklen_t arglen) ipv6 = (struct sockaddr_in6 *)arg; if(inet_ntop(AF_INET6, &ipv6->sin6_addr, buf, sizeof(buf)) == NULL) return(NULL); - ret = sprintf2("%s:%i", buf, (int)ntohs(ipv6->sin6_port)); + ret = sprintf2("[%s]:%i", buf, (int)ntohs(ipv6->sin6_port)); break; #endif default: