mirror of
https://github.com/fluencelabs/musl
synced 2025-05-29 15:41:36 +00:00
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.
This commit is contained in:
parent
e63833cd43
commit
c63c98a606
@ -11,7 +11,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru
|
|||||||
struct address addrs[MAXADDRS];
|
struct address addrs[MAXADDRS];
|
||||||
char canon[256], *outcanon;
|
char canon[256], *outcanon;
|
||||||
int nservs, naddrs, nais, canon_len, i, j, k;
|
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 aibuf {
|
||||||
struct addrinfo ai;
|
struct addrinfo ai;
|
||||||
union sa {
|
union sa {
|
||||||
@ -24,6 +24,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru
|
|||||||
family = hint->ai_family;
|
family = hint->ai_family;
|
||||||
flags = hint->ai_flags;
|
flags = hint->ai_flags;
|
||||||
proto = hint->ai_protocol;
|
proto = hint->ai_protocol;
|
||||||
|
socktype = hint->ai_socktype;
|
||||||
|
|
||||||
const int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST |
|
const int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST |
|
||||||
AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_NUMERICSERV;
|
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:
|
default:
|
||||||
return EAI_FAMILY;
|
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;
|
if (nservs < 0) return nservs;
|
||||||
|
|
||||||
naddrs = __lookup_name(addrs, canon, host, family, flags);
|
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++) {
|
for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++, k++) {
|
||||||
out[k].ai = (struct addrinfo){
|
out[k].ai = (struct addrinfo){
|
||||||
.ai_family = addrs[i].family,
|
.ai_family = addrs[i].family,
|
||||||
.ai_socktype = ports[j].proto == IPPROTO_TCP
|
.ai_socktype = ports[j].socktype,
|
||||||
? SOCK_STREAM : SOCK_DGRAM,
|
|
||||||
.ai_protocol = ports[j].proto,
|
.ai_protocol = ports[j].proto,
|
||||||
.ai_addrlen = addrs[i].family == AF_INET
|
.ai_addrlen = addrs[i].family == AF_INET
|
||||||
? sizeof(struct sockaddr_in)
|
? sizeof(struct sockaddr_in)
|
||||||
|
@ -26,7 +26,7 @@ int getservbyname_r(const char *name, const char *prots,
|
|||||||
else if (!strcmp(prots, "udp")) proto = IPPROTO_UDP;
|
else if (!strcmp(prots, "udp")) proto = IPPROTO_UDP;
|
||||||
else return EINVAL;
|
else return EINVAL;
|
||||||
|
|
||||||
cnt = __lookup_serv(servs, name, proto, 0);
|
cnt = __lookup_serv(servs, name, proto, 0, 0);
|
||||||
if (cnt<0) switch (cnt) {
|
if (cnt<0) switch (cnt) {
|
||||||
case EAI_MEMORY:
|
case EAI_MEMORY:
|
||||||
case EAI_SYSTEM:
|
case EAI_SYSTEM:
|
||||||
|
@ -12,7 +12,7 @@ struct address {
|
|||||||
|
|
||||||
struct service {
|
struct service {
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
char proto;
|
unsigned char proto, socktype;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The limit of 48 results is a non-sharp bound on the number of addresses
|
/* 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 MAXADDRS 48
|
||||||
#define MAXSERVS 2
|
#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_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);
|
int __lookup_ipliteral(struct address buf[static 1], const char *name, int family);
|
||||||
|
|
||||||
|
@ -7,13 +7,43 @@
|
|||||||
#include "lookup.h"
|
#include "lookup.h"
|
||||||
#include "stdio_impl.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];
|
char line[128];
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
char *p, *z = "";
|
char *p, *z = "";
|
||||||
unsigned long port = 0;
|
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) {
|
||||||
if (!*name) return EAI_SERVICE;
|
if (!*name) return EAI_SERVICE;
|
||||||
port = strtoul(name, &z, 10);
|
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 (port > 65535) return EAI_SERVICE;
|
||||||
if (proto != IPPROTO_UDP) {
|
if (proto != IPPROTO_UDP) {
|
||||||
buf[cnt].port = port;
|
buf[cnt].port = port;
|
||||||
|
buf[cnt].socktype = SOCK_STREAM;
|
||||||
buf[cnt++].proto = IPPROTO_TCP;
|
buf[cnt++].proto = IPPROTO_TCP;
|
||||||
}
|
}
|
||||||
if (proto != IPPROTO_TCP) {
|
if (proto != IPPROTO_TCP) {
|
||||||
buf[cnt].port = port;
|
buf[cnt].port = port;
|
||||||
|
buf[cnt].socktype = SOCK_DGRAM;
|
||||||
buf[cnt++].proto = IPPROTO_UDP;
|
buf[cnt++].proto = IPPROTO_UDP;
|
||||||
}
|
}
|
||||||
return cnt;
|
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 (!strncmp(z, "/udp", 4)) {
|
||||||
if (proto == IPPROTO_TCP) continue;
|
if (proto == IPPROTO_TCP) continue;
|
||||||
buf[cnt].port = port;
|
buf[cnt].port = port;
|
||||||
|
buf[cnt].socktype = SOCK_DGRAM;
|
||||||
buf[cnt++].proto = IPPROTO_UDP;
|
buf[cnt++].proto = IPPROTO_UDP;
|
||||||
}
|
}
|
||||||
if (!strncmp(z, "/tcp", 4)) {
|
if (!strncmp(z, "/tcp", 4)) {
|
||||||
if (proto == IPPROTO_UDP) continue;
|
if (proto == IPPROTO_UDP) continue;
|
||||||
buf[cnt].port = port;
|
buf[cnt].port = port;
|
||||||
|
buf[cnt].socktype = SOCK_STREAM;
|
||||||
buf[cnt++].proto = IPPROTO_TCP;
|
buf[cnt++].proto = IPPROTO_TCP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user