1
/* Copyright (c) 1999-2012 Dovecot authors, see the included COPYING file */
3
#define _GNU_SOURCE /* For Linux's struct ucred */
5
#include "close-keep-errno.h"
6
#include "fd-set-nonblock.h"
15
#include <netinet/tcp.h>
17
# include <ucred.h> /* for getpeerucred() */
20
union sockaddr_union {
22
struct sockaddr_in sin;
24
struct sockaddr_in6 sin6;
28
union sockaddr_union_unix {
30
struct sockaddr_un un;
34
# define SIZEOF_SOCKADDR(so) ((so).sa.sa_family == AF_INET6 ? \
35
sizeof(so.sin6) : sizeof(so.sin))
37
# define SIZEOF_SOCKADDR(so) (sizeof(so.sin))
40
bool net_ip_compare(const struct ip_addr *ip1, const struct ip_addr *ip2)
42
return net_ip_cmp(ip1, ip2) == 0;
45
int net_ip_cmp(const struct ip_addr *ip1, const struct ip_addr *ip2)
47
if (ip1->family != ip2->family)
48
return ip1->family - ip2->family;
51
if (ip1->family == AF_INET6)
52
return memcmp(&ip1->u.ip6, &ip2->u.ip6, sizeof(ip1->u.ip6));
55
return memcmp(&ip1->u.ip4, &ip2->u.ip4, sizeof(ip1->u.ip4));
58
unsigned int net_ip_hash(const struct ip_addr *ip)
60
const unsigned char *p;
61
unsigned int len, g, h = 0;
64
if (ip->family == AF_INET6) {
65
p = ip->u.ip6.s6_addr;
66
len = sizeof(ip->u.ip6);
70
return ip->u.ip4.s_addr;
73
for (; len > 0; len--, p++) {
75
if ((g = h & 0xf0000000UL)) {
84
/* copy IP to sockaddr */
86
sin_set_ip(union sockaddr_union *so, const struct ip_addr *ip)
90
so->sin6.sin6_family = AF_INET6;
91
so->sin6.sin6_addr = in6addr_any;
93
so->sin.sin_family = AF_INET;
94
so->sin.sin_addr.s_addr = INADDR_ANY;
99
so->sin.sin_family = ip->family;
101
if (ip->family == AF_INET6)
102
memcpy(&so->sin6.sin6_addr, &ip->u.ip6, sizeof(ip->u.ip6));
105
memcpy(&so->sin.sin_addr, &ip->u.ip4, sizeof(ip->u.ip4));
109
sin_get_ip(const union sockaddr_union *so, struct ip_addr *ip)
111
/* IP structs may be sent across processes. Clear the whole struct
112
first to make sure it won't leak any data across processes. */
113
memset(ip, 0, sizeof(*ip));
115
ip->family = so->sin.sin_family;
118
if (ip->family == AF_INET6)
119
memcpy(&ip->u.ip6, &so->sin6.sin6_addr, sizeof(ip->u.ip6));
122
if (ip->family == AF_INET)
123
memcpy(&ip->u.ip4, &so->sin.sin_addr, sizeof(ip->u.ip4));
125
memset(&ip->u, 0, sizeof(ip->u));
128
static inline void sin_set_port(union sockaddr_union *so, unsigned int port)
131
if (so->sin.sin_family == AF_INET6)
132
so->sin6.sin6_port = htons((unsigned short) port);
135
so->sin.sin_port = htons((unsigned short) port);
138
static inline unsigned int sin_get_port(union sockaddr_union *so)
141
if (so->sin.sin_family == AF_INET6)
142
return ntohs(so->sin6.sin6_port);
144
if (so->sin.sin_family == AF_INET)
145
return ntohs(so->sin.sin_port);
152
net_connect_ip_full_freebsd(const struct ip_addr *ip, unsigned int port,
153
const struct ip_addr *my_ip, bool blocking);
155
static int net_connect_ip_full(const struct ip_addr *ip, unsigned int port,
156
const struct ip_addr *my_ip, bool blocking)
161
fd = net_connect_ip_full_freebsd(ip, port, my_ip, blocking);
162
if (fd != -1 || ++try == 5 ||
163
(errno != EADDRINUSE && errno != EACCES))
166
This may be just a temporary problem:
169
EACCES: pf may cause this if another connection used
170
the same port recently
175
/* then some kludging: */
176
#define net_connect_ip_full net_connect_ip_full_freebsd
179
static int net_connect_ip_full(const struct ip_addr *ip, unsigned int port,
180
const struct ip_addr *my_ip, bool blocking)
182
union sockaddr_union so;
183
int fd, ret, opt = 1;
185
if (my_ip != NULL && ip->family != my_ip->family) {
186
i_warning("net_connect_ip(): ip->family != my_ip->family");
190
/* create the socket */
191
memset(&so, 0, sizeof(so));
192
so.sin.sin_family = ip->family;
193
fd = socket(ip->family, SOCK_STREAM, 0);
196
i_error("socket() failed: %m");
200
/* set socket options */
201
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
202
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt));
204
net_set_nonblock(fd, TRUE);
206
/* set our own address */
208
sin_set_ip(&so, my_ip);
209
if (bind(fd, &so.sa, SIZEOF_SOCKADDR(so)) == -1) {
210
i_error("bind(%s) failed: %m", net_ip2addr(my_ip));
211
close_keep_errno(fd);
218
sin_set_port(&so, port);
219
ret = connect(fd, &so.sa, SIZEOF_SOCKADDR(so));
222
if (ret < 0 && errno != EINPROGRESS)
224
if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
227
close_keep_errno(fd);
234
# undef net_connect_ip_full
237
int net_connect_ip(const struct ip_addr *ip, unsigned int port,
238
const struct ip_addr *my_ip)
240
return net_connect_ip_full(ip, port, my_ip, FALSE);
243
int net_connect_ip_blocking(const struct ip_addr *ip, unsigned int port,
244
const struct ip_addr *my_ip)
246
return net_connect_ip_full(ip, port, my_ip, TRUE);
249
int net_try_bind(const struct ip_addr *ip)
251
union sockaddr_union so;
254
/* create the socket */
255
memset(&so, 0, sizeof(so));
256
so.sin.sin_family = ip->family;
257
fd = socket(ip->family, SOCK_STREAM, 0);
259
i_error("socket() failed: %m");
264
if (bind(fd, &so.sa, SIZEOF_SOCKADDR(so)) == -1) {
265
close_keep_errno(fd);
272
int net_connect_unix(const char *path)
274
union sockaddr_union_unix sa;
277
memset(&sa, 0, sizeof(sa));
278
sa.un.sun_family = AF_UNIX;
279
if (i_strocpy(sa.un.sun_path, path, sizeof(sa.un.sun_path)) < 0) {
285
/* create the socket */
286
fd = socket(PF_UNIX, SOCK_STREAM, 0);
288
i_error("socket(%s) failed: %m", path);
292
net_set_nonblock(fd, TRUE);
295
ret = connect(fd, &sa.sa, sizeof(sa));
296
if (ret < 0 && errno != EINPROGRESS) {
297
close_keep_errno(fd);
304
int net_connect_unix_with_retries(const char *path, unsigned int msecs)
306
struct timeval start, now;
309
if (gettimeofday(&start, NULL) < 0)
310
i_panic("gettimeofday() failed: %m");
313
fd = net_connect_unix(path);
314
if (fd != -1 || (errno != EAGAIN && errno != ECONNREFUSED))
317
/* busy. wait for a while. */
318
usleep(((rand() % 10) + 1) * 10000);
319
if (gettimeofday(&now, NULL) < 0)
320
i_panic("gettimeofday() failed: %m");
321
} while (timeval_diff_msecs(&now, &start) < (int)msecs);
325
void net_disconnect(int fd)
327
/* FreeBSD's close() fails with ECONNRESET if socket still has unsent
328
data in transmit buffer. We don't care. */
329
if (close(fd) < 0 && errno != ECONNRESET)
330
i_error("net_disconnect() failed: %m");
333
void net_set_nonblock(int fd, bool nonblock)
335
if (fd_set_nonblock(fd, nonblock) < 0)
336
i_fatal("fd_set_nonblock(%d) failed: %m", fd);
339
int net_set_cork(int fd ATTR_UNUSED, bool cork ATTR_UNUSED)
344
return setsockopt(fd, IPPROTO_TCP, TCP_CORK, &val, sizeof(val));
351
void net_get_ip_any4(struct ip_addr *ip)
353
ip->family = AF_INET;
354
ip->u.ip4.s_addr = INADDR_ANY;
357
void net_get_ip_any6(struct ip_addr *ip)
360
ip->family = AF_INET6;
361
ip->u.ip6 = in6addr_any;
363
memset(ip, 0, sizeof(struct ip_addr));
367
int net_listen(const struct ip_addr *my_ip, unsigned int *port, int backlog)
369
union sockaddr_union so;
370
int ret, fd, opt = 1;
373
memset(&so, 0, sizeof(so));
374
sin_set_port(&so, *port);
375
sin_set_ip(&so, my_ip);
377
/* create the socket */
378
fd = socket(so.sin.sin_family, SOCK_STREAM, 0);
380
if (fd == -1 && my_ip == NULL &&
381
(errno == EINVAL || errno == EAFNOSUPPORT)) {
382
/* IPv6 is not supported by OS */
383
so.sin.sin_family = AF_INET;
384
so.sin.sin_addr.s_addr = INADDR_ANY;
386
fd = socket(AF_INET, SOCK_STREAM, 0);
390
i_error("socket() failed: %m");
394
/* set socket options */
395
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
396
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt));
398
/* If using IPv6, bind only to IPv6 if possible. This avoids
399
ambiguities with IPv4-mapped IPv6 addresses. */
401
if (so.sin.sin_family == AF_INET6) {
403
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
406
/* specify the address/port we want to listen in */
407
ret = bind(fd, &so.sa, SIZEOF_SOCKADDR(so));
409
if (errno != EADDRINUSE) {
410
i_error("bind(%s, %u) failed: %m",
411
my_ip == NULL ? "" : net_ip2addr(my_ip), *port);
414
/* get the actual port we started listen */
415
len = SIZEOF_SOCKADDR(so);
416
ret = getsockname(fd, &so.sa, &len);
418
*port = sin_get_port(&so);
420
/* start listening */
421
if (listen(fd, backlog) >= 0)
424
if (errno != EADDRINUSE)
425
i_error("listen() failed: %m");
430
close_keep_errno(fd);
434
int net_listen_unix(const char *path, int backlog)
438
struct sockaddr_un un;
442
memset(&sa, 0, sizeof(sa));
443
sa.un.sun_family = AF_UNIX;
444
if (i_strocpy(sa.un.sun_path, path, sizeof(sa.un.sun_path)) < 0) {
450
/* create the socket */
451
fd = socket(PF_UNIX, SOCK_STREAM, 0);
453
i_error("socket() failed: %m");
458
if (bind(fd, &sa.sa, sizeof(sa)) < 0) {
459
if (errno != EADDRINUSE)
460
i_error("bind(%s) failed: %m", path);
462
/* start listening */
463
if (listen(fd, backlog) == 0)
466
if (errno != EADDRINUSE)
467
i_error("listen() failed: %m");
470
close_keep_errno(fd);
474
int net_listen_unix_unlink_stale(const char *path, int backlog)
479
while ((fd = net_listen_unix(path, backlog)) == -1) {
480
if (errno != EADDRINUSE || ++i == 2)
483
/* see if it really exists */
484
fd = net_connect_unix(path);
485
if (fd != -1 || errno != ECONNREFUSED) {
486
if (fd != -1) (void)close(fd);
491
/* delete and try again */
492
if (unlink(path) < 0 && errno != ENOENT) {
493
i_error("unlink(%s) failed: %m", path);
501
int net_accept(int fd, struct ip_addr *addr, unsigned int *port)
503
union sockaddr_union so;
509
addrlen = sizeof(so);
510
ret = accept(fd, &so.sa, &addrlen);
513
if (errno == EAGAIN || errno == ECONNABORTED)
518
if (so.sin.sin_family == AF_UNIX) {
520
memset(addr, 0, sizeof(*addr));
521
if (port != NULL) *port = 0;
523
if (addr != NULL) sin_get_ip(&so, addr);
524
if (port != NULL) *port = sin_get_port(&so);
529
ssize_t net_receive(int fd, void *buf, size_t len)
534
i_assert(len <= SSIZE_T_MAX);
536
ret = read(fd, buf, len);
543
if (unlikely(ret < 0)) {
544
if (errno == EINTR || errno == EAGAIN)
547
if (errno == ECONNRESET || errno == ETIMEDOUT) {
548
/* treat as disconnection */
556
ssize_t net_transmit(int fd, const void *data, size_t len)
561
i_assert(len <= SSIZE_T_MAX);
563
ret = send(fd, data, len, 0);
564
if (unlikely(ret == -1 && (errno == EINTR || errno == EAGAIN)))
567
if (unlikely(errno == EPIPE))
573
int net_gethostbyname(const char *addr, struct ip_addr **ips,
574
unsigned int *ips_count)
578
union sockaddr_union *so;
579
struct addrinfo hints, *ai, *origai;
590
memset(&hints, 0, sizeof(struct addrinfo));
591
hints.ai_socktype = SOCK_STREAM;
593
/* save error to host_error for later use */
594
host_error = getaddrinfo(addr, NULL, &hints, &ai);
598
/* get number of IPs */
600
for (count = 0; ai != NULL; ai = ai->ai_next)
604
*ips = t_malloc(sizeof(struct ip_addr) * count);
607
for (ai = origai; ai != NULL; ai = ai->ai_next, count++) {
608
so = (union sockaddr_union *) ai->ai_addr;
610
sin_get_ip(so, &(*ips)[count]);
612
freeaddrinfo(origai);
614
hp = gethostbyname(addr);
618
/* get number of IPs */
620
while (hp->h_addr_list[count] != NULL)
624
*ips = t_malloc(sizeof(struct ip_addr) * count);
629
(*ips)[count].family = AF_INET;
630
memcpy(&(*ips)[count].u.ip4, hp->h_addr_list[count],
631
sizeof((*ips)[count].u.ip4));
638
int net_getsockname(int fd, struct ip_addr *addr, unsigned int *port)
640
union sockaddr_union so;
645
addrlen = sizeof(so);
646
if (getsockname(fd, &so.sa, &addrlen) == -1)
648
if (so.sin.sin_family == AF_UNIX) {
650
memset(addr, 0, sizeof(*addr));
651
if (port != NULL) *port = 0;
653
if (addr != NULL) sin_get_ip(&so, addr);
654
if (port != NULL) *port = sin_get_port(&so);
659
int net_getpeername(int fd, struct ip_addr *addr, unsigned int *port)
661
union sockaddr_union so;
666
addrlen = sizeof(so);
667
if (getpeername(fd, &so.sa, &addrlen) == -1)
669
if (so.sin.sin_family == AF_UNIX) {
671
memset(addr, 0, sizeof(*addr));
672
if (port != NULL) *port = 0;
674
if (addr != NULL) sin_get_ip(&so, addr);
675
if (port != NULL) *port = sin_get_port(&so);
680
int net_getunixname(int fd, const char **name_r)
682
union sockaddr_union_unix so;
683
socklen_t addrlen = sizeof(so);
685
if (getsockname(fd, &so.sa, &addrlen) < 0)
687
if (so.un.sun_family != AF_UNIX) {
691
*name_r = t_strdup(so.un.sun_path);
695
int net_getunixcred(int fd, struct net_unix_cred *cred_r)
697
#if defined(HAVE_GETPEEREID)
698
/* OSX 10.4+, FreeBSD 4.6+, OpenBSD 3.0+, NetBSD 5.0+ */
699
if (getpeereid(fd, &cred_r->uid, &cred_r->gid) < 0) {
700
i_error("getpeereid() failed: %m");
704
#elif defined(SO_PEERCRED)
707
socklen_t len = sizeof(ucred);
709
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) {
710
i_error("getsockopt(SO_PEERCRED) failed: %m");
713
cred_r->uid = ucred.uid;
714
cred_r->gid = ucred.gid;
716
#elif defined(HAVE_GETPEERUCRED)
718
ucred_t *ucred = NULL;
720
if (getpeerucred(fd, &ucred) < 0) {
721
i_error("getpeerucred() failed: %m");
724
cred_r->uid = ucred_geteuid(ucred);
725
cred_r->gid = ucred_getrgid(ucred);
728
if (cred_r->uid == (uid_t)-1 ||
729
cred_r->gid == (gid_t)-1) {
740
const char *net_ip2addr(const struct ip_addr *ip)
743
char addr[MAX_IP_LEN+1];
745
addr[MAX_IP_LEN] = '\0';
746
if (inet_ntop(ip->family, &ip->u.ip6, addr, MAX_IP_LEN) == NULL)
749
return t_strdup(addr);
753
if (ip->family != AF_INET)
756
ip4 = ntohl(ip->u.ip4.s_addr);
757
return t_strdup_printf("%lu.%lu.%lu.%lu",
758
(ip4 & 0xff000000UL) >> 24,
759
(ip4 & 0x00ff0000) >> 16,
760
(ip4 & 0x0000ff00) >> 8,
765
int net_addr2ip(const char *addr, struct ip_addr *ip)
769
if (strchr(addr, ':') != NULL) {
771
ip->family = AF_INET6;
774
if (addr[0] == '[') {
775
/* allow [ipv6 addr] */
776
unsigned int len = strlen(addr);
777
if (addr[len-1] == ']')
778
addr = t_strndup(addr+1, len-2);
780
ret = inet_pton(AF_INET6, addr, &ip->u.ip6);
785
ip->u.ip4.s_addr = 0;
789
ip->family = AF_INET;
790
if (inet_aton(addr, &ip->u.ip4) == 0)
797
int net_ipv6_mapped_ipv4_convert(const struct ip_addr *src,
798
struct ip_addr *dest)
801
static uint8_t v4_prefix[] =
802
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
804
if (!IPADDR_IS_V6(src))
806
if (memcmp(src->u.ip6.s6_addr, v4_prefix, sizeof(v4_prefix)) != 0)
809
dest->family = AF_INET;
810
memcpy(&dest->u.ip6, &src->u.ip6.s6_addr[3*4], 4);
817
int net_geterror(int fd)
820
socklen_t len = sizeof(data);
822
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &data, &len) == -1)
828
const char *net_gethosterror(int error)
831
i_assert(error != 0);
833
return gai_strerror(error);
837
return "Host not found";
839
return "No IP address found for name";
841
return "A non-recoverable name server error occurred";
843
return "A temporary error on an authoritative name server";
851
int net_hosterror_notfound(int error)
854
#ifdef EAI_NODATA /* NODATA is depricated */
855
return error != 1 && (error == EAI_NONAME || error == EAI_NODATA);
857
return error != 1 && (error == EAI_NONAME);
860
return error == HOST_NOT_FOUND || error == NO_ADDRESS;
864
const char *net_getservbyport(unsigned short port)
866
struct servent *entry;
868
entry = getservbyport(htons(port), "tcp");
869
return entry == NULL ? NULL : entry->s_name;
872
bool is_ipv4_address(const char *addr)
874
while (*addr != '\0') {
875
if (*addr != '.' && !i_isdigit(*addr))
883
bool is_ipv6_address(const char *addr)
885
bool have_prefix = FALSE;
891
while (*addr != '\0') {
892
if (*addr != ':' && !i_isxdigit(*addr)) {
893
if (have_prefix && *addr == ']' && addr[1] == '\0')
903
int net_parse_range(const char *network, struct ip_addr *ip_r,
904
unsigned int *bits_r)
907
unsigned int bits, max_bits;
909
p = strchr(network, '/');
911
network = t_strdup_until(network, p++);
913
if (net_addr2ip(network, ip_r) < 0)
916
max_bits = IPADDR_BITS(ip_r);
918
/* full IP address must match */
921
/* get the network mask */
922
if (str_to_uint(p, &bits) < 0 || bits > max_bits)
929
bool net_is_in_network(const struct ip_addr *ip,
930
const struct ip_addr *net_ip, unsigned int bits)
932
struct ip_addr tmp_ip;
933
const uint32_t *ip1, *ip2;
934
uint32_t mask, i1, i2;
937
if (net_ipv6_mapped_ipv4_convert(ip, &tmp_ip) == 0) {
938
/* IPv4 address mapped disguised as IPv6 address */
942
if (IPADDR_IS_V4(ip) != IPADDR_IS_V4(net_ip)) {
943
/* one is IPv6 and one is IPv4 */
946
i_assert(IPADDR_IS_V6(ip) == IPADDR_IS_V6(net_ip));
948
if (IPADDR_IS_V4(ip)) {
949
ip1 = &ip->u.ip4.s_addr;
950
ip2 = &net_ip->u.ip4.s_addr;
953
ip1 = (const void *)&ip->u.ip6;
954
ip2 = (const void *)&net_ip->u.ip6;
956
/* shouldn't get here */
961
/* check first the full 32bit ints */
962
for (pos = 0, i = 0; pos + 32 <= bits; pos += 32, i++) {
963
if (ip1[i] != ip2[i])
969
/* check the last full bytes */
970
for (mask = 0xff000000; pos + 8 <= bits; pos += 8, mask >>= 8) {
971
if ((i1 & mask) != (i2 & mask))
975
/* check the last bits, they're reversed in bytes */
977
for (mask = 0x80000000 >> (pos % 32); bits > 0; bits--, mask >>= 1) {
978
if ((i1 & mask) != (i2 & mask))