Mercurial > dovecot > core-2.2
annotate src/lib/net.c @ 21892:22c5f005625a
lib: Increase net_connect*() EADDRNOTAVAIL retries to 20
4 is too little, since on busy systems it's sometimes failing. These calls
should be pretty cheap, so lets try if 20 is enough.
It would be nice if this was configurable, but the only practical way right
now would be to use environment variable, which is a bit ugly. We could
try it next if 20 is still not enough.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Tue, 04 Apr 2017 13:28:44 +0300 |
parents | 59437f8764c6 |
children | 7d5634889da8 |
rev | line source |
---|---|
19552
0f22db71df7a
global: freshen copyright
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19534
diff
changeset
|
1 /* Copyright (c) 1999-2016 Dovecot authors, see the included COPYING file */ |
0 | 2 |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
3 #define _GNU_SOURCE /* For Linux's struct ucred */ |
0 | 4 #include "lib.h" |
3621
3ae2df67459c
Added fd_set_nonblock() and changed net_set_nonblock() to use it.
Timo Sirainen <tss@iki.fi>
parents:
3577
diff
changeset
|
5 #include "fd-set-nonblock.h" |
10158
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
6 #include "time-util.h" |
15187
02451e967a06
Renamed network.[ch] to net.[ch].
Timo Sirainen <tss@iki.fi>
parents:
14691
diff
changeset
|
7 #include "net.h" |
0 | 8 |
9 #include <unistd.h> | |
10 #include <fcntl.h> | |
11 #include <ctype.h> | |
12 #include <sys/un.h> | |
13 #include <netinet/tcp.h> | |
14233
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
14 #if defined(HAVE_UCRED_H) |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
15 # include <ucred.h> /* for getpeerucred() */ |
14233
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
16 #elif defined(HAVE_SYS_UCRED_H) |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
17 # include <sys/ucred.h> /* for FreeBSD struct xucred */ |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
18 #endif |
0 | 19 |
20 union sockaddr_union { | |
21 struct sockaddr sa; | |
22 struct sockaddr_in sin; | |
23 #ifdef HAVE_IPV6 | |
24 struct sockaddr_in6 sin6; | |
25 #endif | |
26 }; | |
27 | |
13363 | 28 union sockaddr_union_unix { |
29 struct sockaddr sa; | |
13557 | 30 struct sockaddr_un un; |
13363 | 31 }; |
32 | |
0 | 33 #ifdef HAVE_IPV6 |
34 # define SIZEOF_SOCKADDR(so) ((so).sa.sa_family == AF_INET6 ? \ | |
35 sizeof(so.sin6) : sizeof(so.sin)) | |
36 #else | |
37 # define SIZEOF_SOCKADDR(so) (sizeof(so.sin)) | |
38 #endif | |
39 | |
16276
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
40 #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && !defined(HAVE_GETPEERUCRED) && defined(MSG_WAITALL) && defined(LOCAL_CREDS) |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
41 # define NEEDS_LOCAL_CREDS 1 |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
42 #endif |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
43 |
20823
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
44 /* If connect() fails with EADDRNOTAVAIL (or some others on FreeBSD), retry it |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
45 this many times. |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
46 |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
47 This is needed on busy systems kernel may assign the same source port to two |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
48 sockets at bind() stage, which is what we generally want to allow more than |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
49 64k outgoing connections to different destinations. However, at bind() stage |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
50 the kernel doesn't know the destination yet. So it's possible that it |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
51 assigns the same source port to two (or more) sockets that have the same |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
52 destination IP+port as well. In this case connect() will fail with |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
53 EADDRNOTAVAIL. We'll need to retry this and hope that the next attempt won't |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
54 conflict. */ |
21892
22c5f005625a
lib: Increase net_connect*() EADDRNOTAVAIL retries to 20
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21389
diff
changeset
|
55 #define MAX_CONNECT_RETRIES 20 |
20823
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
56 |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
57 bool net_ip_compare(const struct ip_addr *ip1, const struct ip_addr *ip2) |
0 | 58 { |
10789 | 59 return net_ip_cmp(ip1, ip2) == 0; |
60 } | |
61 | |
62 int net_ip_cmp(const struct ip_addr *ip1, const struct ip_addr *ip2) | |
63 { | |
0 | 64 if (ip1->family != ip2->family) |
10789 | 65 return ip1->family - ip2->family; |
0 | 66 |
67 #ifdef HAVE_IPV6 | |
10789 | 68 if (ip1->family == AF_INET6) |
69 return memcmp(&ip1->u.ip6, &ip2->u.ip6, sizeof(ip1->u.ip6)); | |
0 | 70 #endif |
71 | |
10789 | 72 return memcmp(&ip1->u.ip4, &ip2->u.ip4, sizeof(ip1->u.ip4)); |
0 | 73 } |
74 | |
5865 | 75 unsigned int net_ip_hash(const struct ip_addr *ip) |
76 { | |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
77 const unsigned char *p; |
5865 | 78 unsigned int len, g, h = 0; |
79 | |
80 #ifdef HAVE_IPV6 | |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
81 if (ip->family == AF_INET6) { |
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
82 p = ip->u.ip6.s6_addr; |
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
83 len = sizeof(ip->u.ip6); |
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
84 } else |
5865 | 85 #endif |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
86 { |
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
87 return ip->u.ip4.s_addr; |
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
88 } |
5865 | 89 |
90 for (; len > 0; len--, p++) { | |
91 h = (h << 4) + *p; | |
92 if ((g = h & 0xf0000000UL)) { | |
93 h = h ^ (g >> 24); | |
94 h = h ^ g; | |
95 } | |
96 } | |
97 | |
98 return h; | |
99 } | |
0 | 100 |
101 /* copy IP to sockaddr */ | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
102 static inline void |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
103 sin_set_ip(union sockaddr_union *so, const struct ip_addr *ip) |
0 | 104 { |
105 if (ip == NULL) { | |
106 #ifdef HAVE_IPV6 | |
107 so->sin6.sin6_family = AF_INET6; | |
108 so->sin6.sin6_addr = in6addr_any; | |
109 #else | |
110 so->sin.sin_family = AF_INET; | |
111 so->sin.sin_addr.s_addr = INADDR_ANY; | |
112 #endif | |
113 return; | |
114 } | |
115 | |
116 so->sin.sin_family = ip->family; | |
117 #ifdef HAVE_IPV6 | |
118 if (ip->family == AF_INET6) | |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
119 memcpy(&so->sin6.sin6_addr, &ip->u.ip6, sizeof(ip->u.ip6)); |
0 | 120 else |
121 #endif | |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
122 memcpy(&so->sin.sin_addr, &ip->u.ip4, sizeof(ip->u.ip4)); |
0 | 123 } |
124 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
125 static inline void |
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
126 sin_get_ip(const union sockaddr_union *so, struct ip_addr *ip) |
0 | 127 { |
12138
e403f4dc95ea
Make sure no data is leaked across processes via struct ip_addr fields.
Timo Sirainen <tss@iki.fi>
parents:
11926
diff
changeset
|
128 /* IP structs may be sent across processes. Clear the whole struct |
e403f4dc95ea
Make sure no data is leaked across processes via struct ip_addr fields.
Timo Sirainen <tss@iki.fi>
parents:
11926
diff
changeset
|
129 first to make sure it won't leak any data across processes. */ |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
130 i_zero(ip); |
12138
e403f4dc95ea
Make sure no data is leaked across processes via struct ip_addr fields.
Timo Sirainen <tss@iki.fi>
parents:
11926
diff
changeset
|
131 |
0 | 132 ip->family = so->sin.sin_family; |
133 | |
134 #ifdef HAVE_IPV6 | |
135 if (ip->family == AF_INET6) | |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
136 memcpy(&ip->u.ip6, &so->sin6.sin6_addr, sizeof(ip->u.ip6)); |
0 | 137 else |
138 #endif | |
3400
ddfa507bb74f
Don't return random data if net_getpeername() or net_getsockname() is used
Timo Sirainen <tss@iki.fi>
parents:
3373
diff
changeset
|
139 if (ip->family == AF_INET) |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
140 memcpy(&ip->u.ip4, &so->sin.sin_addr, sizeof(ip->u.ip4)); |
3400
ddfa507bb74f
Don't return random data if net_getpeername() or net_getsockname() is used
Timo Sirainen <tss@iki.fi>
parents:
3373
diff
changeset
|
141 else |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
142 i_zero(&ip->u); |
0 | 143 } |
144 | |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
145 static inline void sin_set_port(union sockaddr_union *so, in_port_t port) |
0 | 146 { |
147 #ifdef HAVE_IPV6 | |
148 if (so->sin.sin_family == AF_INET6) | |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
149 so->sin6.sin6_port = htons(port); |
0 | 150 else |
151 #endif | |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
152 so->sin.sin_port = htons(port); |
0 | 153 } |
154 | |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
155 static inline in_port_t sin_get_port(union sockaddr_union *so) |
0 | 156 { |
157 #ifdef HAVE_IPV6 | |
158 if (so->sin.sin_family == AF_INET6) | |
159 return ntohs(so->sin6.sin6_port); | |
160 #endif | |
3400
ddfa507bb74f
Don't return random data if net_getpeername() or net_getsockname() is used
Timo Sirainen <tss@iki.fi>
parents:
3373
diff
changeset
|
161 if (so->sin.sin_family == AF_INET) |
ddfa507bb74f
Don't return random data if net_getpeername() or net_getsockname() is used
Timo Sirainen <tss@iki.fi>
parents:
3373
diff
changeset
|
162 return ntohs(so->sin.sin_port); |
ddfa507bb74f
Don't return random data if net_getpeername() or net_getsockname() is used
Timo Sirainen <tss@iki.fi>
parents:
3373
diff
changeset
|
163 |
ddfa507bb74f
Don't return random data if net_getpeername() or net_getsockname() is used
Timo Sirainen <tss@iki.fi>
parents:
3373
diff
changeset
|
164 return 0; |
0 | 165 } |
166 | |
20823
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
167 static int net_connect_ip_once(const struct ip_addr *ip, in_port_t port, |
17883
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
168 const struct ip_addr *my_ip, int sock_type, bool blocking) |
0 | 169 { |
170 union sockaddr_union so; | |
171 int fd, ret, opt = 1; | |
172 | |
173 if (my_ip != NULL && ip->family != my_ip->family) { | |
174 i_warning("net_connect_ip(): ip->family != my_ip->family"); | |
175 my_ip = NULL; | |
176 } | |
177 | |
178 /* create the socket */ | |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
179 i_zero(&so); |
0 | 180 so.sin.sin_family = ip->family; |
17883
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
181 fd = socket(ip->family, sock_type, 0); |
0 | 182 |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
183 if (fd == -1) { |
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
184 i_error("socket() failed: %m"); |
0 | 185 return -1; |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
186 } |
0 | 187 |
188 /* set socket options */ | |
17459
e279bd060c28
lib: Added (void) prefixes to some setsockopt() calls which we don't care if they fail.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
189 (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); |
17883
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
190 if (sock_type == SOCK_STREAM) |
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
191 (void)setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); |
11794
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
192 if (!blocking) |
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
193 net_set_nonblock(fd, TRUE); |
0 | 194 |
195 /* set our own address */ | |
196 if (my_ip != NULL) { | |
197 sin_set_ip(&so, my_ip); | |
198 if (bind(fd, &so.sa, SIZEOF_SOCKADDR(so)) == -1) { | |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
199 i_error("bind(%s) failed: %m", net_ip2addr(my_ip)); |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
200 i_close_fd(&fd); |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
201 return -1; |
0 | 202 } |
203 } | |
204 | |
205 /* connect */ | |
206 sin_set_ip(&so, ip); | |
207 sin_set_port(&so, port); | |
208 ret = connect(fd, &so.sa, SIZEOF_SOCKADDR(so)); | |
209 | |
210 #ifndef WIN32 | |
211 if (ret < 0 && errno != EINPROGRESS) | |
212 #else | |
213 if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) | |
214 #endif | |
215 { | |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
216 i_close_fd(&fd); |
0 | 217 return -1; |
218 } | |
219 | |
220 return fd; | |
221 } | |
20823
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
222 |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
223 static int net_connect_ip_full(const struct ip_addr *ip, in_port_t port, |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
224 const struct ip_addr *my_ip, int sock_type, |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
225 bool blocking) |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
226 { |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
227 int fd, try; |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
228 |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
229 for (try = 0;;) { |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
230 fd = net_connect_ip_once(ip, port, my_ip, sock_type, blocking); |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
231 if (fd != -1 || try++ >= MAX_CONNECT_RETRIES || |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
232 (errno != EADDRNOTAVAIL |
11879
4fb7e5327efc
net_connect_ip*(): Fixed FreeBSD kludging.
Timo Sirainen <tss@iki.fi>
parents:
11794
diff
changeset
|
233 #ifdef __FreeBSD__ |
20823
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
234 /* busy */ |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
235 && errno != EADDRINUSE |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
236 /* pf may cause this if another connection used |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
237 the same port recently */ |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
238 && errno != EACCES |
11879
4fb7e5327efc
net_connect_ip*(): Fixed FreeBSD kludging.
Timo Sirainen <tss@iki.fi>
parents:
11794
diff
changeset
|
239 #endif |
20823
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
240 )) |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
241 break; |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
242 } |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
243 return fd; |
06fd5e4f123e
lib: If connect() fails with EADDRNOTAVAIL, retry it 4 more times.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20351
diff
changeset
|
244 } |
0 | 245 |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
246 int net_connect_ip(const struct ip_addr *ip, in_port_t port, |
11794
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
247 const struct ip_addr *my_ip) |
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
248 { |
17883
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
249 return net_connect_ip_full(ip, port, my_ip, SOCK_STREAM, FALSE); |
11794
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
250 } |
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
251 |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
252 int net_connect_ip_blocking(const struct ip_addr *ip, in_port_t port, |
11794
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
253 const struct ip_addr *my_ip) |
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
254 { |
17883
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
255 return net_connect_ip_full(ip, port, my_ip, SOCK_STREAM, TRUE); |
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
256 } |
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
257 |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
258 int net_connect_udp(const struct ip_addr *ip, in_port_t port, |
17883
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
259 const struct ip_addr *my_ip) |
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
260 { |
95ac50948e39
lib: Added support for connecting UDP sockets.
Stephan Bosch <stephan@rename-it.nl>
parents:
17461
diff
changeset
|
261 return net_connect_ip_full(ip, port, my_ip, SOCK_DGRAM, FALSE); |
11794
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
262 } |
5ea9394b5ced
liblib: Added net_connect_ip_blocking().
Timo Sirainen <tss@iki.fi>
parents:
11564
diff
changeset
|
263 |
11340 | 264 int net_try_bind(const struct ip_addr *ip) |
265 { | |
266 union sockaddr_union so; | |
267 int fd; | |
268 | |
269 /* create the socket */ | |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
270 i_zero(&so); |
11340 | 271 so.sin.sin_family = ip->family; |
272 fd = socket(ip->family, SOCK_STREAM, 0); | |
273 if (fd == -1) { | |
274 i_error("socket() failed: %m"); | |
275 return -1; | |
276 } | |
277 | |
278 sin_set_ip(&so, ip); | |
279 if (bind(fd, &so.sa, SIZEOF_SOCKADDR(so)) == -1) { | |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
280 i_close_fd(&fd); |
11340 | 281 return -1; |
282 } | |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
283 i_close_fd(&fd); |
11340 | 284 return 0; |
285 } | |
286 | |
0 | 287 int net_connect_unix(const char *path) |
288 { | |
13557 | 289 union sockaddr_union_unix sa; |
0 | 290 int fd, ret; |
291 | |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
292 i_zero(&sa); |
5985
8ae4b8d78a25
More union usage to avoid casting.
Timo Sirainen <tss@iki.fi>
parents:
5984
diff
changeset
|
293 sa.un.sun_family = AF_UNIX; |
6422
18173a52f721
Renamed strocpy() to i_strocpy().
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
294 if (i_strocpy(sa.un.sun_path, path, sizeof(sa.un.sun_path)) < 0) { |
0 | 295 /* too long path */ |
15601
e4cc3f2b66e3
net_connect_unix(): If path is too long, return ENAMETOOLONG if it's available.
Timo Sirainen <tss@iki.fi>
parents:
14387
diff
changeset
|
296 #ifdef ENAMETOOLONG |
e4cc3f2b66e3
net_connect_unix(): If path is too long, return ENAMETOOLONG if it's available.
Timo Sirainen <tss@iki.fi>
parents:
14387
diff
changeset
|
297 errno = ENAMETOOLONG; |
e4cc3f2b66e3
net_connect_unix(): If path is too long, return ENAMETOOLONG if it's available.
Timo Sirainen <tss@iki.fi>
parents:
14387
diff
changeset
|
298 #else |
0 | 299 errno = EINVAL; |
15601
e4cc3f2b66e3
net_connect_unix(): If path is too long, return ENAMETOOLONG if it's available.
Timo Sirainen <tss@iki.fi>
parents:
14387
diff
changeset
|
300 #endif |
0 | 301 return -1; |
302 } | |
303 | |
304 /* create the socket */ | |
305 fd = socket(PF_UNIX, SOCK_STREAM, 0); | |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
306 if (fd == -1) { |
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
307 i_error("socket(%s) failed: %m", path); |
0 | 308 return -1; |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
309 } |
0 | 310 |
3076
8d15fea729c2
Use nonblocking connecting for unix sockets.
Timo Sirainen <tss@iki.fi>
parents:
3075
diff
changeset
|
311 net_set_nonblock(fd, TRUE); |
8d15fea729c2
Use nonblocking connecting for unix sockets.
Timo Sirainen <tss@iki.fi>
parents:
3075
diff
changeset
|
312 |
0 | 313 /* connect */ |
5985
8ae4b8d78a25
More union usage to avoid casting.
Timo Sirainen <tss@iki.fi>
parents:
5984
diff
changeset
|
314 ret = connect(fd, &sa.sa, sizeof(sa)); |
0 | 315 if (ret < 0 && errno != EINPROGRESS) { |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
316 i_close_fd(&fd); |
0 | 317 return -1; |
318 } | |
319 | |
16276
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
320 #ifdef NEEDS_LOCAL_CREDS |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
321 { |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
322 int on = 1; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
323 if (setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof on)) { |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
324 i_error("setsockopt(LOCAL_CREDS) failed: %m"); |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
325 return -1; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
326 } |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
327 } |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
328 #endif |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
329 |
0 | 330 return fd; |
331 } | |
332 | |
10158
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
333 int net_connect_unix_with_retries(const char *path, unsigned int msecs) |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
334 { |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
335 struct timeval start, now; |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
336 int fd; |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
337 |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
338 if (gettimeofday(&start, NULL) < 0) |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
339 i_panic("gettimeofday() failed: %m"); |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
340 |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
341 do { |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
342 fd = net_connect_unix(path); |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
343 if (fd != -1 || (errno != EAGAIN && errno != ECONNREFUSED)) |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
344 break; |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
345 |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
346 /* busy. wait for a while. */ |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
347 usleep(((rand() % 10) + 1) * 10000); |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
348 if (gettimeofday(&now, NULL) < 0) |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
349 i_panic("gettimeofday() failed: %m"); |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
350 } while (timeval_diff_msecs(&now, &start) < (int)msecs); |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
351 return fd; |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
352 } |
1bc88aa1373f
Added net_connect_unix_with_retries().
Timo Sirainen <tss@iki.fi>
parents:
9843
diff
changeset
|
353 |
0 | 354 void net_disconnect(int fd) |
355 { | |
11564
c24ee1ebb159
net_disconnect(): Ignore ECONNRESET error.
Timo Sirainen <tss@iki.fi>
parents:
11448
diff
changeset
|
356 /* FreeBSD's close() fails with ECONNRESET if socket still has unsent |
c24ee1ebb159
net_disconnect(): Ignore ECONNRESET error.
Timo Sirainen <tss@iki.fi>
parents:
11448
diff
changeset
|
357 data in transmit buffer. We don't care. */ |
c24ee1ebb159
net_disconnect(): Ignore ECONNRESET error.
Timo Sirainen <tss@iki.fi>
parents:
11448
diff
changeset
|
358 if (close(fd) < 0 && errno != ECONNRESET) |
388
792fc5b3daa4
Send error message if close() fails in net_disconnect().
Timo Sirainen <tss@iki.fi>
parents:
349
diff
changeset
|
359 i_error("net_disconnect() failed: %m"); |
0 | 360 } |
361 | |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
362 void net_set_nonblock(int fd, bool nonblock) |
0 | 363 { |
14634
a65006d95d53
fd_set_nonblock() API changed to i_fatal() on failure.
Timo Sirainen <tss@iki.fi>
parents:
14629
diff
changeset
|
364 fd_set_nonblock(fd, nonblock); |
0 | 365 } |
366 | |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5985
diff
changeset
|
367 int net_set_cork(int fd ATTR_UNUSED, bool cork ATTR_UNUSED) |
0 | 368 { |
369 #ifdef TCP_CORK | |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
370 int val = cork; |
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
371 |
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
372 return setsockopt(fd, IPPROTO_TCP, TCP_CORK, &val, sizeof(val)); |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
373 #else |
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
374 errno = ENOPROTOOPT; |
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
375 return -1; |
0 | 376 #endif |
377 } | |
378 | |
21041
13a159cfd232
lib: Created net_set_tcp_nodelay(), which enables the TCP_NODELAY socket option.
Stephan Bosch <stephan@dovecot.fi>
parents:
20823
diff
changeset
|
379 int net_set_tcp_nodelay(int fd, bool nodelay) |
13a159cfd232
lib: Created net_set_tcp_nodelay(), which enables the TCP_NODELAY socket option.
Stephan Bosch <stephan@dovecot.fi>
parents:
20823
diff
changeset
|
380 { |
13a159cfd232
lib: Created net_set_tcp_nodelay(), which enables the TCP_NODELAY socket option.
Stephan Bosch <stephan@dovecot.fi>
parents:
20823
diff
changeset
|
381 int val = nodelay; |
13a159cfd232
lib: Created net_set_tcp_nodelay(), which enables the TCP_NODELAY socket option.
Stephan Bosch <stephan@dovecot.fi>
parents:
20823
diff
changeset
|
382 |
13a159cfd232
lib: Created net_set_tcp_nodelay(), which enables the TCP_NODELAY socket option.
Stephan Bosch <stephan@dovecot.fi>
parents:
20823
diff
changeset
|
383 return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); |
13a159cfd232
lib: Created net_set_tcp_nodelay(), which enables the TCP_NODELAY socket option.
Stephan Bosch <stephan@dovecot.fi>
parents:
20823
diff
changeset
|
384 } |
13a159cfd232
lib: Created net_set_tcp_nodelay(), which enables the TCP_NODELAY socket option.
Stephan Bosch <stephan@dovecot.fi>
parents:
20823
diff
changeset
|
385 |
20351
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
386 int net_set_send_buffer_size(int fd, size_t size) |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
387 { |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
388 int opt; |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
389 |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
390 if (size > INT_MAX) { |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
391 errno = EINVAL; |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
392 return -1; |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
393 } |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
394 opt = (int)size; |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
395 return setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)); |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
396 } |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
397 |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
398 int net_set_recv_buffer_size(int fd, size_t size) |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
399 { |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
400 int opt; |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
401 |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
402 if (size > INT_MAX) { |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
403 errno = EINVAL; |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
404 return -1; |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
405 } |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
406 opt = (int)size; |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
407 return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)); |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
408 } |
f3e249261abd
lib: Implemented net_set_send_buffer_size() and net_set_recv_buffer_size().
Stephan Bosch <stephan@dovecot.fi>
parents:
19680
diff
changeset
|
409 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
410 void net_get_ip_any4(struct ip_addr *ip) |
780
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
411 { |
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
412 ip->family = AF_INET; |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
413 ip->u.ip4.s_addr = INADDR_ANY; |
780
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
414 } |
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
415 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
416 void net_get_ip_any6(struct ip_addr *ip) |
780
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
417 { |
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
418 #ifdef HAVE_IPV6 |
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
419 ip->family = AF_INET6; |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
420 ip->u.ip6 = in6addr_any; |
780
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
421 #else |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
422 memset(ip, 0, sizeof(struct ip_addr)); |
780
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
423 #endif |
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
424 } |
1cc947617c8b
imap_listen and imaps_listen accepts now "*" as "all IPv4 interfaces" and
Timo Sirainen <tss@iki.fi>
parents:
680
diff
changeset
|
425 |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
426 int net_listen(const struct ip_addr *my_ip, in_port_t *port, int backlog) |
0 | 427 { |
16822
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
428 enum net_listen_flags flags = 0; |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
429 |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
430 return net_listen_full(my_ip, port, &flags, backlog); |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
431 } |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
432 |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
433 int net_listen_full(const struct ip_addr *my_ip, in_port_t *port, |
16822
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
434 enum net_listen_flags *flags, int backlog) |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
435 { |
0 | 436 union sockaddr_union so; |
437 int ret, fd, opt = 1; | |
438 socklen_t len; | |
439 | |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
440 i_zero(&so); |
0 | 441 sin_set_port(&so, *port); |
442 sin_set_ip(&so, my_ip); | |
443 | |
444 /* create the socket */ | |
445 fd = socket(so.sin.sin_family, SOCK_STREAM, 0); | |
446 #ifdef HAVE_IPV6 | |
12563
cde0d403c6ff
net_listen(): If IPv6 isn't supported, don't fallback to IPv4 if my_ip is given.
Timo Sirainen <tss@iki.fi>
parents:
12138
diff
changeset
|
447 if (fd == -1 && my_ip == NULL && |
cde0d403c6ff
net_listen(): If IPv6 isn't supported, don't fallback to IPv4 if my_ip is given.
Timo Sirainen <tss@iki.fi>
parents:
12138
diff
changeset
|
448 (errno == EINVAL || errno == EAFNOSUPPORT)) { |
0 | 449 /* IPv6 is not supported by OS */ |
450 so.sin.sin_family = AF_INET; | |
451 so.sin.sin_addr.s_addr = INADDR_ANY; | |
452 | |
453 fd = socket(AF_INET, SOCK_STREAM, 0); | |
454 } | |
455 #endif | |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
456 if (fd == -1) { |
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
457 i_error("socket() failed: %m"); |
0 | 458 return -1; |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
459 } |
0 | 460 |
461 /* set socket options */ | |
17459
e279bd060c28
lib: Added (void) prefixes to some setsockopt() calls which we don't care if they fail.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
462 (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); |
e279bd060c28
lib: Added (void) prefixes to some setsockopt() calls which we don't care if they fail.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
463 (void)setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); |
0 | 464 |
16822
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
465 if ((*flags & NET_LISTEN_FLAG_REUSEPORT) != 0) { |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
466 #ifdef SO_REUSEPORT |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
467 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
468 &opt, sizeof(opt)) < 0) |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
469 #endif |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
470 *flags &= ~NET_LISTEN_FLAG_REUSEPORT; |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
471 } |
6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
Timo Sirainen <tss@iki.fi>
parents:
16806
diff
changeset
|
472 |
7274
da971cec0395
[::] listens only for IPv6 addresses now. This gets rid of IPv4-mapped IPv6
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
473 /* If using IPv6, bind only to IPv6 if possible. This avoids |
da971cec0395
[::] listens only for IPv6 addresses now. This gets rid of IPv4-mapped IPv6
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
474 ambiguities with IPv4-mapped IPv6 addresses. */ |
3373
690dcc51cdc1
if using IPv6, bind both on the IPv4 and IPv6 addresses if IPV6_V6ONLY is
Timo Sirainen <tss@iki.fi>
parents:
3076
diff
changeset
|
475 #ifdef IPV6_V6ONLY |
690dcc51cdc1
if using IPv6, bind both on the IPv4 and IPv6 addresses if IPV6_V6ONLY is
Timo Sirainen <tss@iki.fi>
parents:
3076
diff
changeset
|
476 if (so.sin.sin_family == AF_INET6) { |
7274
da971cec0395
[::] listens only for IPv6 addresses now. This gets rid of IPv4-mapped IPv6
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
477 opt = 1; |
17459
e279bd060c28
lib: Added (void) prefixes to some setsockopt() calls which we don't care if they fail.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
478 (void)setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); |
3373
690dcc51cdc1
if using IPv6, bind both on the IPv4 and IPv6 addresses if IPV6_V6ONLY is
Timo Sirainen <tss@iki.fi>
parents:
3076
diff
changeset
|
479 } |
690dcc51cdc1
if using IPv6, bind both on the IPv4 and IPv6 addresses if IPV6_V6ONLY is
Timo Sirainen <tss@iki.fi>
parents:
3076
diff
changeset
|
480 #endif |
0 | 481 /* specify the address/port we want to listen in */ |
482 ret = bind(fd, &so.sa, SIZEOF_SOCKADDR(so)); | |
3537
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
483 if (ret < 0) { |
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
484 if (errno != EADDRINUSE) { |
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
485 i_error("bind(%s, %u) failed: %m", |
14387
cd7e15b2d575
net_listen(): If bind(ip=any) fails with non-EADDRINUSE, don't crash.
Timo Sirainen <tss@iki.fi>
parents:
14377
diff
changeset
|
486 my_ip == NULL ? "" : net_ip2addr(my_ip), *port); |
3537
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
487 } |
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
488 } else { |
0 | 489 /* get the actual port we started listen */ |
490 len = SIZEOF_SOCKADDR(so); | |
491 ret = getsockname(fd, &so.sa, &len); | |
492 if (ret >= 0) { | |
493 *port = sin_get_port(&so); | |
494 | |
495 /* start listening */ | |
3075
9cb91ed5a110
Added backlog parameter for net_listen*().
Timo Sirainen <tss@iki.fi>
parents:
2639
diff
changeset
|
496 if (listen(fd, backlog) >= 0) |
3537
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
497 return fd; |
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
498 |
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
499 if (errno != EADDRINUSE) |
5ff3b88db948
net_listen(): Print bind() errors only if it's not EADDRINUSE. Also do the
Timo Sirainen <tss@iki.fi>
parents:
3523
diff
changeset
|
500 i_error("listen() failed: %m"); |
0 | 501 } |
502 } | |
503 | |
504 /* error */ | |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
505 i_close_fd(&fd); |
0 | 506 return -1; |
507 } | |
508 | |
3075
9cb91ed5a110
Added backlog parameter for net_listen*().
Timo Sirainen <tss@iki.fi>
parents:
2639
diff
changeset
|
509 int net_listen_unix(const char *path, int backlog) |
0 | 510 { |
5985
8ae4b8d78a25
More union usage to avoid casting.
Timo Sirainen <tss@iki.fi>
parents:
5984
diff
changeset
|
511 union { |
8ae4b8d78a25
More union usage to avoid casting.
Timo Sirainen <tss@iki.fi>
parents:
5984
diff
changeset
|
512 struct sockaddr sa; |
8ae4b8d78a25
More union usage to avoid casting.
Timo Sirainen <tss@iki.fi>
parents:
5984
diff
changeset
|
513 struct sockaddr_un un; |
8ae4b8d78a25
More union usage to avoid casting.
Timo Sirainen <tss@iki.fi>
parents:
5984
diff
changeset
|
514 } sa; |
0 | 515 int fd; |
516 | |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
517 i_zero(&sa); |
5985
8ae4b8d78a25
More union usage to avoid casting.
Timo Sirainen <tss@iki.fi>
parents:
5984
diff
changeset
|
518 sa.un.sun_family = AF_UNIX; |
6422
18173a52f721
Renamed strocpy() to i_strocpy().
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
519 if (i_strocpy(sa.un.sun_path, path, sizeof(sa.un.sun_path)) < 0) { |
0 | 520 /* too long path */ |
16806
07cc79e0041d
net_listen_unix(): If path is too long, return EOVERFLOW instead of EINVAL.
Timo Sirainen <tss@iki.fi>
parents:
16666
diff
changeset
|
521 errno = EOVERFLOW; |
0 | 522 return -1; |
523 } | |
524 | |
525 /* create the socket */ | |
526 fd = socket(PF_UNIX, SOCK_STREAM, 0); | |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
527 if (fd == -1) { |
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
528 i_error("socket() failed: %m"); |
0 | 529 return -1; |
3523
d1ed3b3548db
Added some more error messages. Also if net_connect_ip() gives my_ip
Timo Sirainen <tss@iki.fi>
parents:
3400
diff
changeset
|
530 } |
0 | 531 |
16276
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
532 #ifdef NEEDS_LOCAL_CREDS |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
533 { |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
534 int on = 1; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
535 if (setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof on)) { |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
536 i_error("setsockopt(LOCAL_CREDS) failed: %m"); |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
537 return -1; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
538 } |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
539 } |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
540 #endif |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
541 |
0 | 542 /* bind */ |
5985
8ae4b8d78a25
More union usage to avoid casting.
Timo Sirainen <tss@iki.fi>
parents:
5984
diff
changeset
|
543 if (bind(fd, &sa.sa, sizeof(sa)) < 0) { |
3545
0b6539bc22b9
Don't log extra bind() errors for net_listen_unix() either
Timo Sirainen <tss@iki.fi>
parents:
3537
diff
changeset
|
544 if (errno != EADDRINUSE) |
0b6539bc22b9
Don't log extra bind() errors for net_listen_unix() either
Timo Sirainen <tss@iki.fi>
parents:
3537
diff
changeset
|
545 i_error("bind(%s) failed: %m", path); |
0b6539bc22b9
Don't log extra bind() errors for net_listen_unix() either
Timo Sirainen <tss@iki.fi>
parents:
3537
diff
changeset
|
546 } else { |
0 | 547 /* start listening */ |
3075
9cb91ed5a110
Added backlog parameter for net_listen*().
Timo Sirainen <tss@iki.fi>
parents:
2639
diff
changeset
|
548 if (listen(fd, backlog) == 0) |
0 | 549 return fd; |
3545
0b6539bc22b9
Don't log extra bind() errors for net_listen_unix() either
Timo Sirainen <tss@iki.fi>
parents:
3537
diff
changeset
|
550 |
0b6539bc22b9
Don't log extra bind() errors for net_listen_unix() either
Timo Sirainen <tss@iki.fi>
parents:
3537
diff
changeset
|
551 if (errno != EADDRINUSE) |
0b6539bc22b9
Don't log extra bind() errors for net_listen_unix() either
Timo Sirainen <tss@iki.fi>
parents:
3537
diff
changeset
|
552 i_error("listen() failed: %m"); |
0 | 553 } |
554 | |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
555 i_close_fd(&fd); |
0 | 556 return -1; |
557 } | |
558 | |
8219
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
559 int net_listen_unix_unlink_stale(const char *path, int backlog) |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
560 { |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
561 unsigned int i = 0; |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
562 int fd; |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
563 |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
564 while ((fd = net_listen_unix(path, backlog)) == -1) { |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
565 if (errno != EADDRINUSE || ++i == 2) |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
566 return -1; |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
567 |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
568 /* see if it really exists */ |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
569 fd = net_connect_unix(path); |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
570 if (fd != -1 || errno != ECONNREFUSED) { |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
571 if (fd != -1) i_close_fd(&fd); |
8219
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
572 errno = EADDRINUSE; |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
573 return -1; |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
574 } |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
575 |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
576 /* delete and try again */ |
19136
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
19041
diff
changeset
|
577 if (i_unlink_if_exists(path) < 0) { |
8219
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
578 errno = EADDRINUSE; |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
579 return -1; |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
580 } |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
581 } |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
582 return fd; |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
583 } |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7919
diff
changeset
|
584 |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
585 int net_accept(int fd, struct ip_addr *addr_r, in_port_t *port_r) |
0 | 586 { |
587 union sockaddr_union so; | |
588 int ret; | |
589 socklen_t addrlen; | |
590 | |
591 i_assert(fd >= 0); | |
592 | |
593 addrlen = sizeof(so); | |
594 ret = accept(fd, &so.sa, &addrlen); | |
595 | |
680
84e398270f7f
net_accept() returns now -2 for fatal failures.
Timo Sirainen <tss@iki.fi>
parents:
628
diff
changeset
|
596 if (ret < 0) { |
5358
a977ad033903
net_listen_unix() API changed a bit. -1 is now returned for errors that can
Timo Sirainen <tss@iki.fi>
parents:
4745
diff
changeset
|
597 if (errno == EAGAIN || errno == ECONNABORTED) |
a977ad033903
net_listen_unix() API changed a bit. -1 is now returned for errors that can
Timo Sirainen <tss@iki.fi>
parents:
4745
diff
changeset
|
598 return -1; |
a977ad033903
net_listen_unix() API changed a bit. -1 is now returned for errors that can
Timo Sirainen <tss@iki.fi>
parents:
4745
diff
changeset
|
599 else |
680
84e398270f7f
net_accept() returns now -2 for fatal failures.
Timo Sirainen <tss@iki.fi>
parents:
628
diff
changeset
|
600 return -2; |
84e398270f7f
net_accept() returns now -2 for fatal failures.
Timo Sirainen <tss@iki.fi>
parents:
628
diff
changeset
|
601 } |
11926
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
602 if (so.sin.sin_family == AF_UNIX) { |
14629
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14576
diff
changeset
|
603 if (addr_r != NULL) |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
604 i_zero(addr_r); |
14629
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14576
diff
changeset
|
605 if (port_r != NULL) *port_r = 0; |
11926
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
606 } else { |
14629
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14576
diff
changeset
|
607 if (addr_r != NULL) sin_get_ip(&so, addr_r); |
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14576
diff
changeset
|
608 if (port_r != NULL) *port_r = sin_get_port(&so); |
11926
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
609 } |
0 | 610 return ret; |
611 } | |
612 | |
183
4a7ab9e94f25
size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents:
159
diff
changeset
|
613 ssize_t net_receive(int fd, void *buf, size_t len) |
0 | 614 { |
183
4a7ab9e94f25
size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents:
159
diff
changeset
|
615 ssize_t ret; |
0 | 616 |
617 i_assert(fd >= 0); | |
183
4a7ab9e94f25
size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents:
159
diff
changeset
|
618 i_assert(len <= SSIZE_T_MAX); |
0 | 619 |
3681
771cd6776d4b
Use read() instead of recv() in net_receive(), so it works even with
Timo Sirainen <tss@iki.fi>
parents:
3621
diff
changeset
|
620 ret = read(fd, buf, len); |
781
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
621 if (ret == 0) { |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
622 /* disconnected */ |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
623 errno = 0; |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
624 return -2; |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
625 } |
0 | 626 |
6825
85385079b044
Use likely() and unlikely() macros to make commonly checked error handling
Timo Sirainen <tss@iki.fi>
parents:
6666
diff
changeset
|
627 if (unlikely(ret < 0)) { |
781
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
628 if (errno == EINTR || errno == EAGAIN) |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
629 return 0; |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
630 |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
631 if (errno == ECONNRESET || errno == ETIMEDOUT) { |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
632 /* treat as disconnection */ |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
633 return -2; |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
634 } |
9cb7022749e7
net_receive, net_transmit: Return -2 for regular disconnection errors. Don't
Timo Sirainen <tss@iki.fi>
parents:
780
diff
changeset
|
635 } |
0 | 636 |
637 return ret; | |
638 } | |
639 | |
183
4a7ab9e94f25
size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents:
159
diff
changeset
|
640 ssize_t net_transmit(int fd, const void *data, size_t len) |
0 | 641 { |
183
4a7ab9e94f25
size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents:
159
diff
changeset
|
642 ssize_t ret; |
0 | 643 |
644 i_assert(fd >= 0); | |
183
4a7ab9e94f25
size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents:
159
diff
changeset
|
645 i_assert(len <= SSIZE_T_MAX); |
0 | 646 |
64
83ae914a583a
added t_strdup_noconst() which can be used instead of (char *) t_strdup().
Timo Sirainen <tss@iki.fi>
parents:
34
diff
changeset
|
647 ret = send(fd, data, len, 0); |
17120
93cf0434dda4
net_transmit() may have wrongly returned EPIPE error.
Timo Sirainen <tss@iki.fi>
parents:
16822
diff
changeset
|
648 if (ret == -1) { |
93cf0434dda4
net_transmit() may have wrongly returned EPIPE error.
Timo Sirainen <tss@iki.fi>
parents:
16822
diff
changeset
|
649 if (errno == EINTR || errno == EAGAIN) |
93cf0434dda4
net_transmit() may have wrongly returned EPIPE error.
Timo Sirainen <tss@iki.fi>
parents:
16822
diff
changeset
|
650 return 0; |
93cf0434dda4
net_transmit() may have wrongly returned EPIPE error.
Timo Sirainen <tss@iki.fi>
parents:
16822
diff
changeset
|
651 if (errno == EPIPE) |
93cf0434dda4
net_transmit() may have wrongly returned EPIPE error.
Timo Sirainen <tss@iki.fi>
parents:
16822
diff
changeset
|
652 return -2; |
93cf0434dda4
net_transmit() may have wrongly returned EPIPE error.
Timo Sirainen <tss@iki.fi>
parents:
16822
diff
changeset
|
653 } |
0 | 654 return ret; |
655 } | |
656 | |
4745
7ee0bb1b2d97
Changed ips_count to unsigned int in net_gethostbyname(). Also removed
Timo Sirainen <tss@iki.fi>
parents:
4699
diff
changeset
|
657 int net_gethostbyname(const char *addr, struct ip_addr **ips, |
7ee0bb1b2d97
Changed ips_count to unsigned int in net_gethostbyname(). Also removed
Timo Sirainen <tss@iki.fi>
parents:
4699
diff
changeset
|
658 unsigned int *ips_count) |
0 | 659 { |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
660 /* @UNSAFE */ |
0 | 661 #ifdef HAVE_IPV6 |
662 union sockaddr_union *so; | |
663 struct addrinfo hints, *ai, *origai; | |
19312
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
664 struct ip_addr ip; |
0 | 665 int host_error; |
666 #else | |
667 struct hostent *hp; | |
668 #endif | |
669 int count; | |
670 | |
671 *ips = NULL; | |
672 *ips_count = 0; | |
673 | |
674 #ifdef HAVE_IPV6 | |
19312
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
675 /* support [ipv6] style addresses here so they work globally */ |
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
676 if (addr[0] == '[' && net_addr2ip(addr, &ip) == 0) { |
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
677 *ips_count = 1; |
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
678 *ips = t_new(struct ip_addr, 1); |
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
679 **ips = ip; |
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
680 return 0; |
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
681 } |
c5c34c02fda3
lib: net_gethostbyname() now supports [ipv6] style bracketed addresses.
Timo Sirainen <tss@iki.fi>
parents:
19191
diff
changeset
|
682 |
0 | 683 memset(&hints, 0, sizeof(struct addrinfo)); |
684 hints.ai_socktype = SOCK_STREAM; | |
685 | |
686 /* save error to host_error for later use */ | |
687 host_error = getaddrinfo(addr, NULL, &hints, &ai); | |
688 if (host_error != 0) | |
689 return host_error; | |
690 | |
691 /* get number of IPs */ | |
692 origai = ai; | |
693 for (count = 0; ai != NULL; ai = ai->ai_next) | |
694 count++; | |
695 | |
696 *ips_count = count; | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
697 *ips = t_malloc(sizeof(struct ip_addr) * count); |
0 | 698 |
699 count = 0; | |
700 for (ai = origai; ai != NULL; ai = ai->ai_next, count++) { | |
701 so = (union sockaddr_union *) ai->ai_addr; | |
702 | |
2113
c5817f302aa6
net_gethostbyname() was broken with IPv6 enabled (wasn't really used with
Timo Sirainen <tss@iki.fi>
parents:
2098
diff
changeset
|
703 sin_get_ip(so, &(*ips)[count]); |
0 | 704 } |
705 freeaddrinfo(origai); | |
706 #else | |
707 hp = gethostbyname(addr); | |
708 if (hp == NULL) | |
709 return h_errno; | |
710 | |
711 /* get number of IPs */ | |
712 count = 0; | |
713 while (hp->h_addr_list[count] != NULL) | |
714 count++; | |
715 | |
716 *ips_count = count; | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
807
diff
changeset
|
717 *ips = t_malloc(sizeof(struct ip_addr) * count); |
0 | 718 |
719 while (count > 0) { | |
720 count--; | |
721 | |
722 (*ips)[count].family = AF_INET; | |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
723 memcpy(&(*ips)[count].u.ip4, hp->h_addr_list[count], |
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
724 sizeof((*ips)[count].u.ip4)); |
0 | 725 } |
726 #endif | |
727 | |
728 return 0; | |
729 } | |
730 | |
16575
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
731 int net_gethostbyaddr(const struct ip_addr *ip, const char **name_r) |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
732 { |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
733 union sockaddr_union so; |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
734 socklen_t addrlen = sizeof(so); |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
735 char hbuf[NI_MAXHOST]; |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
736 int ret; |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
737 |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
738 i_zero(&so); |
16575
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
739 sin_set_ip(&so, ip); |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
740 ret = getnameinfo(&so.sa, addrlen, hbuf, sizeof(hbuf), NULL, 0, |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
741 NI_NAMEREQD); |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
742 if (ret != 0) |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
743 return ret; |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
744 |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
745 *name_r = t_strdup(hbuf); |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
746 return 0; |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
747 } |
eaa712530f3f
Added net_gethostbyaddr() for DNS PTR lookups.
Timo Sirainen <tss@iki.fi>
parents:
16277
diff
changeset
|
748 |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
749 int net_getsockname(int fd, struct ip_addr *addr, in_port_t *port) |
0 | 750 { |
751 union sockaddr_union so; | |
752 socklen_t addrlen; | |
753 | |
754 i_assert(fd >= 0); | |
755 | |
756 addrlen = sizeof(so); | |
4018
989dd95aa8b9
Enable -Wstrict-aliasing=2 warning and fixed a couple of warnings it gave.
Timo Sirainen <tss@iki.fi>
parents:
4011
diff
changeset
|
757 if (getsockname(fd, &so.sa, &addrlen) == -1) |
0 | 758 return -1; |
11926
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
759 if (so.sin.sin_family == AF_UNIX) { |
12138
e403f4dc95ea
Make sure no data is leaked across processes via struct ip_addr fields.
Timo Sirainen <tss@iki.fi>
parents:
11926
diff
changeset
|
760 if (addr != NULL) |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
761 i_zero(addr); |
11926
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
762 if (port != NULL) *port = 0; |
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
763 } else { |
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
764 if (addr != NULL) sin_get_ip(&so, addr); |
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
765 if (port != NULL) *port = sin_get_port(&so); |
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
766 } |
0 | 767 return 0; |
768 } | |
769 | |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
770 int net_getpeername(int fd, struct ip_addr *addr, in_port_t *port) |
2098 | 771 { |
772 union sockaddr_union so; | |
773 socklen_t addrlen; | |
774 | |
775 i_assert(fd >= 0); | |
776 | |
777 addrlen = sizeof(so); | |
4018
989dd95aa8b9
Enable -Wstrict-aliasing=2 warning and fixed a couple of warnings it gave.
Timo Sirainen <tss@iki.fi>
parents:
4011
diff
changeset
|
778 if (getpeername(fd, &so.sa, &addrlen) == -1) |
2098 | 779 return -1; |
11926
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
780 if (so.sin.sin_family == AF_UNIX) { |
12138
e403f4dc95ea
Make sure no data is leaked across processes via struct ip_addr fields.
Timo Sirainen <tss@iki.fi>
parents:
11926
diff
changeset
|
781 if (addr != NULL) |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
782 i_zero(addr); |
11926
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
783 if (port != NULL) *port = 0; |
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
784 } else { |
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
785 if (addr != NULL) sin_get_ip(&so, addr); |
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
786 if (port != NULL) *port = sin_get_port(&so); |
10c4c9d5fb5b
net_accept(), net_getsock/peername(): Return UNIX sockets with family=port=0.
Timo Sirainen <tss@iki.fi>
parents:
11879
diff
changeset
|
787 } |
2098 | 788 return 0; |
789 } | |
790 | |
9843 | 791 int net_getunixname(int fd, const char **name_r) |
792 { | |
13363 | 793 union sockaddr_union_unix so; |
794 socklen_t addrlen = sizeof(so); | |
9843 | 795 |
13363 | 796 if (getsockname(fd, &so.sa, &addrlen) < 0) |
9843 | 797 return -1; |
13557 | 798 if (so.un.sun_family != AF_UNIX) { |
9843 | 799 errno = ENOTSOCK; |
800 return -1; | |
801 } | |
13557 | 802 *name_r = t_strdup(so.un.sun_path); |
9843 | 803 return 0; |
804 } | |
805 | |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
806 int net_getunixcred(int fd, struct net_unix_cred *cred_r) |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
807 { |
14233
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
808 #if defined(SO_PEERCRED) |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
809 # if defined(HAVE_STRUCT_SOCKPEERCRED) |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
810 /* OpenBSD (may also provide getpeereid, but we also want pid) */ |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
811 struct sockpeercred ucred; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
812 # else |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
813 /* Linux */ |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
814 struct ucred ucred; |
14233
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
815 # endif |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
816 socklen_t len = sizeof(ucred); |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
817 |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
818 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) { |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
819 i_error("getsockopt(SO_PEERCRED) failed: %m"); |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
820 return -1; |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
821 } |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
822 cred_r->uid = ucred.uid; |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
823 cred_r->gid = ucred.gid; |
14233
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
824 cred_r->pid = ucred.pid; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
825 return 0; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
826 #elif defined(LOCAL_PEEREID) |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
827 /* NetBSD (may also provide getpeereid, but we also want pid) */ |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
828 struct unpcbid ucred; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
829 socklen_t len = sizeof(ucred); |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
830 |
16276
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
831 if (getsockopt(fd, 0, LOCAL_PEEREID, &ucred, &len) < 0) { |
14233
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
832 i_error("getsockopt(LOCAL_PEEREID) failed: %m"); |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
833 return -1; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
834 } |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
835 |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
836 cred_r->uid = ucred.unp_euid; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
837 cred_r->gid = ucred.unp_egid; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
838 cred_r->pid = ucred.unp_pid; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
839 return 0; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
840 #elif defined(HAVE_GETPEEREID) |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
841 /* OSX 10.4+, FreeBSD 4.6+, OpenBSD 3.0+, NetBSD 5.0+ */ |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
842 if (getpeereid(fd, &cred_r->uid, &cred_r->gid) < 0) { |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
843 i_error("getpeereid() failed: %m"); |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
844 return -1; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
845 } |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
846 cred_r->pid = (pid_t)-1; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
847 return 0; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
848 #elif defined(LOCAL_PEERCRED) |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
849 /* Older FreeBSD */ |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
850 struct xucred ucred; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
851 socklen_t len = sizeof(ucred); |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
852 |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
853 if (getsockopt(fd, 0, LOCAL_PEERCRED, &ucred, &len) < 0) { |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
854 i_error("getsockopt(LOCAL_PEERCRED) failed: %m"); |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
855 return -1; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
856 } |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
857 |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
858 if (ucred.cr_version != XUCRED_VERSION) { |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
859 errno = EINVAL; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
860 return -1; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
861 } |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
862 |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
863 cred_r->uid = ucred.cr_uid; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
864 cred_r->gid = ucred.cr_gid; |
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
865 cred_r->pid = (pid_t)-1; |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
866 return 0; |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
867 #elif defined(HAVE_GETPEERUCRED) |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
868 /* Solaris */ |
14377
98fd46f8d1ab
net_getunixcred(): Fixed Solaris to use getpeerucred() properly.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
869 ucred_t *ucred = NULL; |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
870 |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
871 if (getpeerucred(fd, &ucred) < 0) { |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
872 i_error("getpeerucred() failed: %m"); |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
873 return -1; |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
874 } |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
875 cred_r->uid = ucred_geteuid(ucred); |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
876 cred_r->gid = ucred_getrgid(ucred); |
14233
80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
877 cred_r->pid = ucred_getpid(ucred); |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
878 ucred_free(ucred); |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
879 |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
880 if (cred_r->uid == (uid_t)-1 || |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
881 cred_r->gid == (gid_t)-1) { |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
882 errno = EINVAL; |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
883 return -1; |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
884 } |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
885 return 0; |
16276
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
886 #elif NEEDS_LOCAL_CREDS |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
887 /* NetBSD < 5 */ |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
888 int i, n, on; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
889 struct iovec iov; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
890 struct msghdr msg; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
891 struct { |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
892 struct cmsghdr ch; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
893 char buf[110]; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
894 } cdata; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
895 struct sockcred *sc; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
896 |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
897 iov.iov_base = (char *)&on; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
898 iov.iov_len = 1; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
899 |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
900 sc = (struct sockcred *)cdata.buf; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
901 sc->sc_uid = sc->sc_euid = sc->sc_gid = sc->sc_egid = -1; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
902 memset(&cdata.ch, 0, sizeof cdata.ch); |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
903 |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
904 memset(&msg, 0, sizeof msg); |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
905 |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
906 msg.msg_iov = &iov; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
907 msg.msg_iovlen = 1; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
908 msg.msg_control = &cdata; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
909 msg.msg_controllen = sizeof(cdata.ch) + sizeof(cdata.buf); |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
910 |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
911 for (i = 0; i < 10; i++) { |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
912 n = recvmsg(fd, &msg, MSG_WAITALL | MSG_PEEK); |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
913 if (n >= 0 || errno != EAGAIN) |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
914 break; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
915 usleep(100); |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
916 } |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
917 if (n < 0) { |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
918 i_error("recvmsg() failed: %m"); |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
919 return -1; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
920 } |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
921 cred_r->uid = sc->sc_euid; |
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
922 cred_r->gid = sc->sc_egid; |
16277
c802c0b960e2
net_getunixcred(): Fix to previous NetBSD<5 support: return pid as -1.
Timo Sirainen <tss@iki.fi>
parents:
16276
diff
changeset
|
923 cred_r->pid = (pid_t)-1; |
16276
d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Timo Sirainen <tss@iki.fi>
parents:
16043
diff
changeset
|
924 return 0; |
12887
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
925 #else |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
926 errno = EINVAL; |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
927 return -1; |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
928 #endif |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
929 } |
352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
930 |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
931 const char *net_ip2addr(const struct ip_addr *ip) |
0 | 932 { |
933 #ifdef HAVE_IPV6 | |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
934 char addr[MAX_IP_LEN+1]; |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
935 |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
936 addr[MAX_IP_LEN] = '\0'; |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
937 if (inet_ntop(ip->family, &ip->u.ip6, addr, MAX_IP_LEN) == NULL) |
16666
58be84a381e5
net_ip2addr() changed to return "" instead of NULL on failure.
Timo Sirainen <tss@iki.fi>
parents:
16647
diff
changeset
|
938 return ""; |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
939 |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
940 return t_strdup(addr); |
0 | 941 #else |
942 unsigned long ip4; | |
943 | |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
944 if (ip->family != AF_INET) |
16666
58be84a381e5
net_ip2addr() changed to return "" instead of NULL on failure.
Timo Sirainen <tss@iki.fi>
parents:
16647
diff
changeset
|
945 return ""; |
0 | 946 |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
947 ip4 = ntohl(ip->u.ip4.s_addr); |
805
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
948 return t_strdup_printf("%lu.%lu.%lu.%lu", |
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
949 (ip4 & 0xff000000UL) >> 24, |
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
950 (ip4 & 0x00ff0000) >> 16, |
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
951 (ip4 & 0x0000ff00) >> 8, |
5ac361acb316
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
Timo Sirainen <tss@iki.fi>
parents:
781
diff
changeset
|
952 (ip4 & 0x000000ff)); |
0 | 953 #endif |
954 } | |
955 | |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
956 int net_addr2ip(const char *addr, struct ip_addr *ip) |
0 | 957 { |
11448
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
958 int ret; |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
959 |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
960 if (strchr(addr, ':') != NULL) { |
0 | 961 /* IPv6 */ |
962 #ifdef HAVE_IPV6 | |
11448
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
963 T_BEGIN { |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
964 if (addr[0] == '[') { |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
965 /* allow [ipv6 addr] */ |
21322
5ab8dc1a4a6f
global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21097
diff
changeset
|
966 size_t len = strlen(addr); |
11448
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
967 if (addr[len-1] == ']') |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
968 addr = t_strndup(addr+1, len-2); |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
969 } |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
970 ret = inet_pton(AF_INET6, addr, &ip->u.ip6); |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
971 } T_END; |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
972 if (ret == 0) |
0 | 973 return -1; |
974 #else | |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
975 ip->u.ip4.s_addr = 0; |
0 | 976 #endif |
18500
4903ab967807
lib: net_addr2ip() sets the family now only after address is successfully converted.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
977 ip->family = AF_INET6; |
0 | 978 } else { |
979 /* IPv4 */ | |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
980 if (inet_aton(addr, &ip->u.ip4) == 0) |
0 | 981 return -1; |
18500
4903ab967807
lib: net_addr2ip() sets the family now only after address is successfully converted.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
982 ip->family = AF_INET; |
0 | 983 } |
984 return 0; | |
985 } | |
986 | |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
987 int net_str2port(const char *str, in_port_t *port_r) |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
988 { |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
989 uintmax_t l; |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
990 |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
991 if (str_to_uintmax(str, &l) < 0) |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
992 return -1; |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
993 |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
994 if (l == 0 || l > (in_port_t)-1) |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
995 return -1; |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
996 *port_r = (in_port_t)l; |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
997 return 0; |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
998 } |
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
999 |
19041
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1000 int net_str2port_zero(const char *str, in_port_t *port_r) |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1001 { |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1002 uintmax_t l; |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1003 |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1004 if (str_to_uintmax(str, &l) < 0) |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1005 return -1; |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1006 |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1007 if (l > (in_port_t)-1) |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1008 return -1; |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1009 *port_r = (in_port_t)l; |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1010 return 0; |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1011 } |
c53ccafc4a8e
Earlier in_port_t fix created problems with service listener configuration.
Stephan Bosch <stephan@rename-it.nl>
parents:
19035
diff
changeset
|
1012 |
19680
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1013 int net_str2hostport(const char *str, in_port_t default_port, |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1014 const char **host_r, in_port_t *port_r) |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1015 { |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1016 const char *p, *host; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1017 in_port_t port; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1018 |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1019 if (str[0] == '[') { |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1020 /* [IPv6] address, possibly followed by :port */ |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1021 p = strchr(str, ']'); |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1022 if (p == NULL) |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1023 return -1; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1024 host = t_strdup_until(str+1, p++); |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1025 } else { |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1026 p = strchr(str, ':'); |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1027 if (p == NULL || strchr(p+1, ':') != NULL) { |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1028 /* host or IPv6 address */ |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1029 *host_r = str; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1030 *port_r = default_port; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1031 return 0; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1032 } |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1033 host = t_strdup_until(str, p); |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1034 } |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1035 if (p[0] == '\0') { |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1036 *host_r = host; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1037 *port_r = default_port; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1038 return 0; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1039 } |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1040 if (p[0] != ':') |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1041 return -1; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1042 if (net_str2port(p+1, &port) < 0) |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1043 return -1; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1044 *host_r = host; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1045 *port_r = port; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1046 return 0; |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1047 } |
55831f9d2e66
lib: Added net_str2hostport()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
1048 |
21097 | 1049 int net_ipport2str(const struct ip_addr *ip, in_port_t port, const char **str_r) |
1050 { | |
1051 if (!IPADDR_IS_V4(ip) && !IPADDR_IS_V6(ip)) return -1; | |
1052 | |
1053 *str_r = t_strdup_printf("%s%s%s:%u", | |
1054 IPADDR_IS_V6(ip) ? "[" : "", | |
1055 net_ip2addr(ip), | |
1056 IPADDR_IS_V6(ip) ? "]" : "", | |
1057 port); | |
1058 return 0; | |
1059 } | |
1060 | |
4684
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1061 int net_ipv6_mapped_ipv4_convert(const struct ip_addr *src, |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1062 struct ip_addr *dest) |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1063 { |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1064 #ifdef HAVE_IPV6 |
4699
9e4cc68b71b2
Fix net_ipv6_mapped_ipv4_convert() to be actually portable.
Timo Sirainen <tss@iki.fi>
parents:
4684
diff
changeset
|
1065 static uint8_t v4_prefix[] = |
9e4cc68b71b2
Fix net_ipv6_mapped_ipv4_convert() to be actually portable.
Timo Sirainen <tss@iki.fi>
parents:
4684
diff
changeset
|
1066 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; |
9e4cc68b71b2
Fix net_ipv6_mapped_ipv4_convert() to be actually portable.
Timo Sirainen <tss@iki.fi>
parents:
4684
diff
changeset
|
1067 |
4684
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1068 if (!IPADDR_IS_V6(src)) |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1069 return -1; |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
1070 if (memcmp(src->u.ip6.s6_addr, v4_prefix, sizeof(v4_prefix)) != 0) |
4684
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1071 return -1; |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1072 |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1073 dest->family = AF_INET; |
5984
74a6130211c2
Changed struct ip_addr to use union for ipv4/ipv6 structs so we don't have
Timo Sirainen <tss@iki.fi>
parents:
5865
diff
changeset
|
1074 memcpy(&dest->u.ip6, &src->u.ip6.s6_addr[3*4], 4); |
4684
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1075 return 0; |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1076 #else |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1077 return -1; |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1078 #endif |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1079 } |
4f1df4b90500
Added net_ipv6_mapped_ipv4_convert().
Timo Sirainen <tss@iki.fi>
parents:
4018
diff
changeset
|
1080 |
0 | 1081 int net_geterror(int fd) |
1082 { | |
1083 int data; | |
1084 socklen_t len = sizeof(data); | |
1085 | |
17461
2e239d925c09
lib: Changed net_geterror() to return errno instead of -1 if getsockopt() fails.
Timo Sirainen <tss@iki.fi>
parents:
17459
diff
changeset
|
1086 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &data, &len) == -1) { |
2e239d925c09
lib: Changed net_geterror() to return errno instead of -1 if getsockopt() fails.
Timo Sirainen <tss@iki.fi>
parents:
17459
diff
changeset
|
1087 /* we're now really returning the getsockopt()'s error code |
2e239d925c09
lib: Changed net_geterror() to return errno instead of -1 if getsockopt() fails.
Timo Sirainen <tss@iki.fi>
parents:
17459
diff
changeset
|
1088 instead of the socket's, but normally we should never get |
2e239d925c09
lib: Changed net_geterror() to return errno instead of -1 if getsockopt() fails.
Timo Sirainen <tss@iki.fi>
parents:
17459
diff
changeset
|
1089 here anyway. */ |
2e239d925c09
lib: Changed net_geterror() to return errno instead of -1 if getsockopt() fails.
Timo Sirainen <tss@iki.fi>
parents:
17459
diff
changeset
|
1090 return errno; |
2e239d925c09
lib: Changed net_geterror() to return errno instead of -1 if getsockopt() fails.
Timo Sirainen <tss@iki.fi>
parents:
17459
diff
changeset
|
1091 } |
0 | 1092 |
1093 return data; | |
1094 } | |
1095 | |
1096 const char *net_gethosterror(int error) | |
1097 { | |
1098 #ifdef HAVE_IPV6 | |
1099 i_assert(error != 0); | |
1100 | |
1101 return gai_strerror(error); | |
1102 #else | |
1103 switch (error) { | |
1104 case HOST_NOT_FOUND: | |
1105 return "Host not found"; | |
1106 case NO_ADDRESS: | |
1107 return "No IP address found for name"; | |
1108 case NO_RECOVERY: | |
6666 | 1109 return "A non-recoverable name server error occurred"; |
0 | 1110 case TRY_AGAIN: |
1111 return "A temporary error on an authoritative name server"; | |
16647
dc60e46f0cb5
net_gethosterror(): Never return NULL.
Timo Sirainen <tss@iki.fi>
parents:
16575
diff
changeset
|
1112 default: |
dc60e46f0cb5
net_gethosterror(): Never return NULL.
Timo Sirainen <tss@iki.fi>
parents:
16575
diff
changeset
|
1113 return t_strdup_printf("Unknown error %d", error); |
0 | 1114 } |
1115 #endif | |
1116 } | |
1117 | |
1118 int net_hosterror_notfound(int error) | |
1119 { | |
1120 #ifdef HAVE_IPV6 | |
1915
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1871
diff
changeset
|
1121 #ifdef EAI_NODATA /* NODATA is depricated */ |
0 | 1122 return error != 1 && (error == EAI_NONAME || error == EAI_NODATA); |
1123 #else | |
1915
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1871
diff
changeset
|
1124 return error != 1 && (error == EAI_NONAME); |
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1871
diff
changeset
|
1125 #endif |
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1871
diff
changeset
|
1126 #else |
0 | 1127 return error == HOST_NOT_FOUND || error == NO_ADDRESS; |
1128 #endif | |
1129 } | |
1130 | |
19035
aabfe48db1cf
Changed type of internet port values to in_port_t everywhere.
Stephan Bosch <stephan@rename-it.nl>
parents:
18500
diff
changeset
|
1131 const char *net_getservbyport(in_port_t port) |
0 | 1132 { |
1133 struct servent *entry; | |
1134 | |
349 | 1135 entry = getservbyport(htons(port), "tcp"); |
0 | 1136 return entry == NULL ? NULL : entry->s_name; |
1137 } | |
1138 | |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
1139 bool is_ipv4_address(const char *addr) |
0 | 1140 { |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
1141 while (*addr != '\0') { |
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
1142 if (*addr != '.' && !i_isdigit(*addr)) |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
1143 return FALSE; |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
1144 addr++; |
0 | 1145 } |
1146 | |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
1147 return TRUE; |
0 | 1148 } |
1149 | |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
1150 bool is_ipv6_address(const char *addr) |
0 | 1151 { |
11448
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1152 bool have_prefix = FALSE; |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1153 |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1154 if (*addr == '[') { |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1155 have_prefix = TRUE; |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1156 addr++; |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1157 } |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
1158 while (*addr != '\0') { |
11448
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1159 if (*addr != ':' && !i_isxdigit(*addr)) { |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1160 if (have_prefix && *addr == ']' && addr[1] == '\0') |
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1161 break; |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
1162 return FALSE; |
11448
bdb46ba87203
Added support for [] around ipv6 addresses everywhere.
Timo Sirainen <tss@iki.fi>
parents:
11340
diff
changeset
|
1163 } |
1485
8c28289a15a1
s/host/addr/ in a few network functions
Timo Sirainen <tss@iki.fi>
parents:
1268
diff
changeset
|
1164 addr++; |
0 | 1165 } |
1166 | |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3681
diff
changeset
|
1167 return TRUE; |
0 | 1168 } |
7517
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1169 |
7919
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1170 int net_parse_range(const char *network, struct ip_addr *ip_r, |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1171 unsigned int *bits_r) |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1172 { |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1173 const char *p; |
11086
260e190306b0
Started using str_to_*() functions instead of libc's ones.
Timo Sirainen <tss@iki.fi>
parents:
10789
diff
changeset
|
1174 unsigned int bits, max_bits; |
7919
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1175 |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1176 p = strchr(network, '/'); |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1177 if (p != NULL) |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1178 network = t_strdup_until(network, p++); |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1179 |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1180 if (net_addr2ip(network, ip_r) < 0) |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1181 return -1; |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1182 |
13290
d473660bc54d
liblib: Added IPADDR_BITS() macro.
Timo Sirainen <tss@iki.fi>
parents:
12887
diff
changeset
|
1183 max_bits = IPADDR_BITS(ip_r); |
7919
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1184 if (p == NULL) { |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1185 /* full IP address must match */ |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1186 bits = max_bits; |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1187 } else { |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1188 /* get the network mask */ |
11086
260e190306b0
Started using str_to_*() functions instead of libc's ones.
Timo Sirainen <tss@iki.fi>
parents:
10789
diff
changeset
|
1189 if (str_to_uint(p, &bits) < 0 || bits > max_bits) |
7919
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1190 return -1; |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1191 } |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1192 *bits_r = bits; |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1193 return 0; |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1194 } |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1195 |
7517
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1196 bool net_is_in_network(const struct ip_addr *ip, |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1197 const struct ip_addr *net_ip, unsigned int bits) |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1198 { |
7919
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1199 struct ip_addr tmp_ip; |
7517
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1200 const uint32_t *ip1, *ip2; |
7520
85203e817f90
net_is_in_network(): Fixed to work with big endian machines.
Timo Sirainen <tss@iki.fi>
parents:
7517
diff
changeset
|
1201 uint32_t mask, i1, i2; |
7517
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1202 unsigned int pos, i; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1203 |
7919
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1204 if (net_ipv6_mapped_ipv4_convert(ip, &tmp_ip) == 0) { |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1205 /* IPv4 address mapped disguised as IPv6 address */ |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1206 ip = &tmp_ip; |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1207 } |
423b8e3fedbb
Created net_parse_range() from auth code.
Timo Sirainen <tss@iki.fi>
parents:
7520
diff
changeset
|
1208 |
19534
25e892203e2b
lib: Fixed assert-crash with net_is_in_network(family=ipv6, family=0, ..)
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19312
diff
changeset
|
1209 if (ip->family == 0 || net_ip->family == 0) { |
16043
790bb5dfadc6
net_is_in_network(): Don't assert-crash with invalid IP.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
1210 /* non-IPv4/IPv6 address (e.g. UNIX socket) never matches |
790bb5dfadc6
net_is_in_network(): Don't assert-crash with invalid IP.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
1211 anything */ |
790bb5dfadc6
net_is_in_network(): Don't assert-crash with invalid IP.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
1212 return FALSE; |
790bb5dfadc6
net_is_in_network(): Don't assert-crash with invalid IP.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
1213 } |
7517
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1214 if (IPADDR_IS_V4(ip) != IPADDR_IS_V4(net_ip)) { |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1215 /* one is IPv6 and one is IPv4 */ |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1216 return FALSE; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1217 } |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1218 i_assert(IPADDR_IS_V6(ip) == IPADDR_IS_V6(net_ip)); |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1219 |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1220 if (IPADDR_IS_V4(ip)) { |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1221 ip1 = &ip->u.ip4.s_addr; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1222 ip2 = &net_ip->u.ip4.s_addr; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1223 } else { |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1224 #ifdef HAVE_IPV6 |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1225 ip1 = (const void *)&ip->u.ip6; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1226 ip2 = (const void *)&net_ip->u.ip6; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1227 #else |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1228 /* shouldn't get here */ |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1229 return FALSE; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1230 #endif |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1231 } |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1232 |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1233 /* check first the full 32bit ints */ |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1234 for (pos = 0, i = 0; pos + 32 <= bits; pos += 32, i++) { |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1235 if (ip1[i] != ip2[i]) |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1236 return FALSE; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1237 } |
7520
85203e817f90
net_is_in_network(): Fixed to work with big endian machines.
Timo Sirainen <tss@iki.fi>
parents:
7517
diff
changeset
|
1238 i1 = htonl(ip1[i]); |
85203e817f90
net_is_in_network(): Fixed to work with big endian machines.
Timo Sirainen <tss@iki.fi>
parents:
7517
diff
changeset
|
1239 i2 = htonl(ip2[i]); |
7517
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1240 |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1241 /* check the last full bytes */ |
7520
85203e817f90
net_is_in_network(): Fixed to work with big endian machines.
Timo Sirainen <tss@iki.fi>
parents:
7517
diff
changeset
|
1242 for (mask = 0xff000000; pos + 8 <= bits; pos += 8, mask >>= 8) { |
85203e817f90
net_is_in_network(): Fixed to work with big endian machines.
Timo Sirainen <tss@iki.fi>
parents:
7517
diff
changeset
|
1243 if ((i1 & mask) != (i2 & mask)) |
7517
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1244 return FALSE; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1245 } |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1246 |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1247 /* check the last bits, they're reversed in bytes */ |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1248 bits -= pos; |
7520
85203e817f90
net_is_in_network(): Fixed to work with big endian machines.
Timo Sirainen <tss@iki.fi>
parents:
7517
diff
changeset
|
1249 for (mask = 0x80000000 >> (pos % 32); bits > 0; bits--, mask >>= 1) { |
85203e817f90
net_is_in_network(): Fixed to work with big endian machines.
Timo Sirainen <tss@iki.fi>
parents:
7517
diff
changeset
|
1250 if ((i1 & mask) != (i2 & mask)) |
7517
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1251 return FALSE; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1252 } |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1253 return TRUE; |
e0007da64cdc
Moved net_is_in_network() to lib/network.c.
Timo Sirainen <tss@iki.fi>
parents:
7274
diff
changeset
|
1254 } |