diff options
author | Rich Felker <dalias@aerifal.cx> | 2015-02-07 14:01:34 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2015-02-07 14:01:34 -0500 |
commit | c63c98a6067030a25a42703db1209ccbcc74803a (patch) | |
tree | 7ffaee240a0cf9286d851a1681d974878b2cf091 /src | |
parent | e63833cd43a778f639e4fdf5d86cd5c526cc5db2 (diff) | |
download | musl-c63c98a6067030a25a42703db1209ccbcc74803a.tar.gz musl-c63c98a6067030a25a42703db1209ccbcc74803a.tar.bz2 musl-c63c98a6067030a25a42703db1209ccbcc74803a.tar.xz musl-c63c98a6067030a25a42703db1209ccbcc74803a.zip |
make getaddrinfo support SOCK_RAW and other socket types
all socket types are accepted at this point, but that may be changed
at a later time if the behavior is not meaningful for other types. as
before, omitting type (a value of 0) gives both UDP and TCP results,
and SOCK_DGRAM or SOCK_STREAM restricts to UDP or TCP, respectively.
for other socket types, the service name argument is required to be a
null pointer, and the protocol number provided by the caller is used.
Diffstat (limited to 'src')
-rw-r--r-- | src/network/getaddrinfo.c | 34 | ||||
-rw-r--r-- | src/network/getservbyname_r.c | 2 | ||||
-rw-r--r-- | src/network/lookup.h | 4 | ||||
-rw-r--r-- | src/network/lookup_serv.c | 36 |
4 files changed, 42 insertions, 34 deletions
diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c index d9913445..c88d558c 100644 --- a/src/network/getaddrinfo.c +++ b/src/network/getaddrinfo.c @@ -11,7 +11,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru struct address addrs[MAXADDRS]; char canon[256], *outcanon; int nservs, naddrs, nais, canon_len, i, j, k; - int family = AF_UNSPEC, flags = 0, proto = 0; + int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0; struct aibuf { struct addrinfo ai; union sa { @@ -24,6 +24,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru family = hint->ai_family; flags = hint->ai_flags; proto = hint->ai_protocol; + socktype = hint->ai_socktype; const int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_NUMERICSERV; @@ -38,35 +39,9 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru default: return EAI_FAMILY; } - - switch (hint->ai_socktype) { - case SOCK_STREAM: - switch (proto) { - case 0: - proto = IPPROTO_TCP; - case IPPROTO_TCP: - break; - default: - return EAI_SERVICE; - } - break; - case SOCK_DGRAM: - switch (proto) { - case 0: - proto = IPPROTO_UDP; - case IPPROTO_UDP: - break; - default: - return EAI_SERVICE; - } - case 0: - break; - default: - return EAI_SOCKTYPE; - } } - nservs = __lookup_serv(ports, serv, proto, flags); + nservs = __lookup_serv(ports, serv, proto, socktype, flags); if (nservs < 0) return nservs; naddrs = __lookup_name(addrs, canon, host, family, flags); @@ -87,8 +62,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++, k++) { out[k].ai = (struct addrinfo){ .ai_family = addrs[i].family, - .ai_socktype = ports[j].proto == IPPROTO_TCP - ? SOCK_STREAM : SOCK_DGRAM, + .ai_socktype = ports[j].socktype, .ai_protocol = ports[j].proto, .ai_addrlen = addrs[i].family == AF_INET ? sizeof(struct sockaddr_in) diff --git a/src/network/getservbyname_r.c b/src/network/getservbyname_r.c index 8cdf622c..056c2f33 100644 --- a/src/network/getservbyname_r.c +++ b/src/network/getservbyname_r.c @@ -26,7 +26,7 @@ int getservbyname_r(const char *name, const char *prots, else if (!strcmp(prots, "udp")) proto = IPPROTO_UDP; else return EINVAL; - cnt = __lookup_serv(servs, name, proto, 0); + cnt = __lookup_serv(servs, name, proto, 0, 0); if (cnt<0) switch (cnt) { case EAI_MEMORY: case EAI_SYSTEM: diff --git a/src/network/lookup.h b/src/network/lookup.h index 4e45d869..69419115 100644 --- a/src/network/lookup.h +++ b/src/network/lookup.h @@ -12,7 +12,7 @@ struct address { struct service { uint16_t port; - char proto; + unsigned char proto, socktype; }; /* The limit of 48 results is a non-sharp bound on the number of addresses @@ -21,7 +21,7 @@ struct service { #define MAXADDRS 48 #define MAXSERVS 2 -int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int flags); +int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags); int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags); int __lookup_ipliteral(struct address buf[static 1], const char *name, int family); diff --git a/src/network/lookup_serv.c b/src/network/lookup_serv.c index a9be0f3d..4faa5bc7 100644 --- a/src/network/lookup_serv.c +++ b/src/network/lookup_serv.c @@ -7,13 +7,43 @@ #include "lookup.h" #include "stdio_impl.h" -int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int flags) +int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags) { char line[128]; int cnt = 0; char *p, *z = ""; unsigned long port = 0; + switch (socktype) { + case SOCK_STREAM: + switch (proto) { + case 0: + proto = IPPROTO_TCP; + case IPPROTO_TCP: + break; + default: + return EAI_SERVICE; + } + break; + case SOCK_DGRAM: + switch (proto) { + case 0: + proto = IPPROTO_UDP; + case IPPROTO_UDP: + break; + default: + return EAI_SERVICE; + } + case 0: + break; + default: + if (name) return EAI_SERVICE; + buf[0].port = 0; + buf[0].proto = proto; + buf[0].socktype = socktype; + return 1; + } + if (name) { if (!*name) return EAI_SERVICE; port = strtoul(name, &z, 10); @@ -22,10 +52,12 @@ int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int pro if (port > 65535) return EAI_SERVICE; if (proto != IPPROTO_UDP) { buf[cnt].port = port; + buf[cnt].socktype = SOCK_STREAM; buf[cnt++].proto = IPPROTO_TCP; } if (proto != IPPROTO_TCP) { buf[cnt].port = port; + buf[cnt].socktype = SOCK_DGRAM; buf[cnt++].proto = IPPROTO_UDP; } return cnt; @@ -58,11 +90,13 @@ int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int pro if (!strncmp(z, "/udp", 4)) { if (proto == IPPROTO_TCP) continue; buf[cnt].port = port; + buf[cnt].socktype = SOCK_DGRAM; buf[cnt++].proto = IPPROTO_UDP; } if (!strncmp(z, "/tcp", 4)) { if (proto == IPPROTO_UDP) continue; buf[cnt].port = port; + buf[cnt].socktype = SOCK_STREAM; buf[cnt++].proto = IPPROTO_TCP; } } |