summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-02-07 14:01:34 -0500
committerRich Felker <dalias@aerifal.cx>2015-02-07 14:01:34 -0500
commitc63c98a6067030a25a42703db1209ccbcc74803a (patch)
tree7ffaee240a0cf9286d851a1681d974878b2cf091 /src/network
parente63833cd43a778f639e4fdf5d86cd5c526cc5db2 (diff)
downloadmusl-c63c98a6067030a25a42703db1209ccbcc74803a.tar.gz
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/network')
-rw-r--r--src/network/getaddrinfo.c34
-rw-r--r--src/network/getservbyname_r.c2
-rw-r--r--src/network/lookup.h4
-rw-r--r--src/network/lookup_serv.c36
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;
}
}