mailing list of musl libc
 help / color / mirror / code / Atom feed
72276ddc6fd6692ca8b25102d12eb35482843d71 blob 3623 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 
#include <stdbool.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include "lookup.h"

int getaddrinfo(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict hint, struct addrinfo **restrict res)
{
	struct service ports[MAXSERVS];
	struct address addrs[MAXADDRS];
	char canon[256], *outcanon;
	int nservs, naddrs, nais, canon_len, i, j, k, fd, r;
	int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0;
	struct aibuf {
		struct addrinfo ai;
		union sa {
			struct sockaddr_in sin;
			struct sockaddr_in6 sin6;
		} sa;
	} *out;
	struct addrconfig {
		bool af_inet;
		bool af_inet6;
	} addrconfig;
	struct sockaddr_storage sas;

	if (!host && !serv) return EAI_NONAME;

	if (hint) {
		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;
		if ((flags & mask) != flags)
			return EAI_BADFLAGS;

		if (flags & AI_ADDRCONFIG) {
			*((struct sockaddr_in *)(&sas)) = (struct sockaddr_in){
				.sin_family = AF_INET,
				.sin_port = htons(42),
				.sin_addr.s_addr = INADDR_LOOPBACK,
			};
			addrconfig.af_inet = false;
			r = socket(AF_INET, SOCK_DGRAM, 0);
			if (-1 != r) {
				fd = r;
				r = connect(fd, (struct sockaddr *) & sas, sizeof( struct sockaddr_in ));
				addrconfig.af_inet = 0 == r;
				close(fd);
			}
			*((struct sockaddr_in6 *)(&sas)) = (struct sockaddr_in6){
				.sin6_family = AF_INET6,
				.sin6_port = htons(42),
				.sin6_addr = IN6ADDR_LOOPBACK_INIT,
			};
			addrconfig.af_inet6 = false;
			r = socket(AF_INET6, SOCK_DGRAM, 0);
			if (-1 != r) {
				fd = r;
				r = connect(fd, (struct sockaddr *) & sas, sizeof(struct sockaddr_in6));
				addrconfig.af_inet6 = 0 == r;
				close(fd);
			}
		}

		switch (family) {
		case AF_INET:
		case AF_INET6:
		case AF_UNSPEC:
			break;
		default:
			return EAI_FAMILY;
		}
	}

	nservs = __lookup_serv(ports, serv, proto, socktype, flags);
	if (nservs < 0) return nservs;

	naddrs = __lookup_name(addrs, canon, host, family, flags);
	if (naddrs < 0) return naddrs;

	nais = nservs * naddrs;
	canon_len = strlen(canon);
	out = calloc(1, nais * sizeof(*out) + canon_len + 1);
	if (!out) return EAI_MEMORY;

	if (canon_len) {
		outcanon = (void *)&out[nais];
		memcpy(outcanon, canon, canon_len+1);
	} else {
		outcanon = 0;
	}

	for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++) {
		switch (addrs[i].family) {
		case AF_INET:
			if ((flags & AI_ADDRCONFIG) && !addrconfig.af_inet) {
				nais--;
				continue;
			}
			out[k].sa.sin.sin_family = AF_INET;
			out[k].sa.sin.sin_port = htons(ports[j].port);
			memcpy(&out[k].sa.sin.sin_addr, &addrs[i].addr, 4);
			break;
		case AF_INET6:
			if ((flags & AI_ADDRCONFIG ) && !addrconfig.af_inet6) {
				nais--;
				continue;
			}
			out[k].sa.sin6.sin6_family = AF_INET6;
			out[k].sa.sin6.sin6_port = htons(ports[j].port);
			out[k].sa.sin6.sin6_scope_id = addrs[i].scopeid;
			memcpy(&out[k].sa.sin6.sin6_addr, &addrs[i].addr, 16);
			break;
		}
		out[k].ai = (struct addrinfo){
			.ai_family = addrs[i].family,
			.ai_socktype = ports[j].socktype,
			.ai_protocol = ports[j].proto,
			.ai_addrlen = addrs[i].family == AF_INET
				? sizeof(struct sockaddr_in)
				: sizeof(struct sockaddr_in6),
			.ai_addr = (void *)&out[k].sa,
			.ai_canonname = outcanon,
			.ai_next = &out[k+1].ai };
		k++;
	}
	if ( nais < 1 ) {
		free( out );
		return EAI_NONAME;
	}
	out[nais-1].ai.ai_next = 0;
	*res = &out->ai;
	return 0;
}
debug log:

solving 72276ddc ...
found 72276ddc in https://inbox.vuxu.org/musl/CAF4BF-T0QXYGHkb9FKXDhMb7m+juOac+Mp-z50WgSGEED5jojA@mail.gmail.com/
found b9439f77 in https://git.vuxu.org/mirror/musl/
preparing index
index prepared:
100644 b9439f776fcebf41e00ed1e6fff674b7a42ea1be	src/network/getaddrinfo.c

applying [1/1] https://inbox.vuxu.org/musl/CAF4BF-T0QXYGHkb9FKXDhMb7m+juOac+Mp-z50WgSGEED5jojA@mail.gmail.com/
diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c
index b9439f77..72276ddc 100644

Checking patch src/network/getaddrinfo.c...
Applied patch src/network/getaddrinfo.c cleanly.

index at:
100644 72276ddc6fd6692ca8b25102d12eb35482843d71	src/network/getaddrinfo.c

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).