]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/unbound/util/net_help.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / unbound / util / net_help.c
1 /*
2  * util/net_help.c - implementation of the network helper code
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * 
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 /**
36  * \file
37  * Implementation of net_help.h.
38  */
39
40 #include "config.h"
41 #include "util/net_help.h"
42 #include "util/log.h"
43 #include "util/data/dname.h"
44 #include "util/module.h"
45 #include "util/regional.h"
46 #include "ldns/parseutil.h"
47 #include "ldns/wire2str.h"
48 #include <fcntl.h>
49 #ifdef HAVE_OPENSSL_SSL_H
50 #include <openssl/ssl.h>
51 #endif
52 #ifdef HAVE_OPENSSL_ERR_H
53 #include <openssl/err.h>
54 #endif
55
56 /** max length of an IP address (the address portion) that we allow */
57 #define MAX_ADDR_STRLEN 128 /* characters */
58 /** default value for EDNS ADVERTISED size */
59 uint16_t EDNS_ADVERTISED_SIZE = 4096;
60
61 /** minimal responses when positive answer: default is no */
62 int MINIMAL_RESPONSES = 0;
63
64 /** rrset order roundrobin: default is no */
65 int RRSET_ROUNDROBIN = 0;
66
67 /* returns true is string addr is an ip6 specced address */
68 int
69 str_is_ip6(const char* str)
70 {
71         if(strchr(str, ':'))
72                 return 1;
73         else    return 0;
74 }
75
76 int 
77 fd_set_nonblock(int s) 
78 {
79 #ifdef HAVE_FCNTL
80         int flag;
81         if((flag = fcntl(s, F_GETFL)) == -1) {
82                 log_err("can't fcntl F_GETFL: %s", strerror(errno));
83                 flag = 0;
84         }
85         flag |= O_NONBLOCK;
86         if(fcntl(s, F_SETFL, flag) == -1) {
87                 log_err("can't fcntl F_SETFL: %s", strerror(errno));
88                 return 0;
89         }
90 #elif defined(HAVE_IOCTLSOCKET)
91         unsigned long on = 1;
92         if(ioctlsocket(s, FIONBIO, &on) != 0) {
93                 log_err("can't ioctlsocket FIONBIO on: %s", 
94                         wsa_strerror(WSAGetLastError()));
95         }
96 #endif
97         return 1;
98 }
99
100 int 
101 fd_set_block(int s) 
102 {
103 #ifdef HAVE_FCNTL
104         int flag;
105         if((flag = fcntl(s, F_GETFL)) == -1) {
106                 log_err("cannot fcntl F_GETFL: %s", strerror(errno));
107                 flag = 0;
108         }
109         flag &= ~O_NONBLOCK;
110         if(fcntl(s, F_SETFL, flag) == -1) {
111                 log_err("cannot fcntl F_SETFL: %s", strerror(errno));
112                 return 0;
113         }
114 #elif defined(HAVE_IOCTLSOCKET)
115         unsigned long off = 0;
116         if(ioctlsocket(s, FIONBIO, &off) != 0) {
117                 log_err("can't ioctlsocket FIONBIO off: %s", 
118                         wsa_strerror(WSAGetLastError()));
119         }
120 #endif  
121         return 1;
122 }
123
124 int 
125 is_pow2(size_t num)
126 {
127         if(num == 0) return 1;
128         return (num & (num-1)) == 0;
129 }
130
131 void* 
132 memdup(void* data, size_t len)
133 {
134         void* d;
135         if(!data) return NULL;
136         if(len == 0) return NULL;
137         d = malloc(len);
138         if(!d) return NULL;
139         memcpy(d, data, len);
140         return d;
141 }
142
143 void
144 log_addr(enum verbosity_value v, const char* str, 
145         struct sockaddr_storage* addr, socklen_t addrlen)
146 {
147         uint16_t port;
148         const char* family = "unknown";
149         char dest[100];
150         int af = (int)((struct sockaddr_in*)addr)->sin_family;
151         void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
152         if(verbosity < v)
153                 return;
154         switch(af) {
155                 case AF_INET: family="ip4"; break;
156                 case AF_INET6: family="ip6";
157                         sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
158                         break;
159                 case AF_LOCAL:
160                         dest[0]=0;
161                         (void)inet_ntop(af, sinaddr, dest,
162                                 (socklen_t)sizeof(dest));
163                         verbose(v, "%s local %s", str, dest);
164                         return; /* do not continue and try to get port */
165                 default: break;
166         }
167         if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
168                 (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest));
169         }
170         dest[sizeof(dest)-1] = 0;
171         port = ntohs(((struct sockaddr_in*)addr)->sin_port);
172         if(verbosity >= 4)
173                 verbose(v, "%s %s %s port %d (len %d)", str, family, dest, 
174                         (int)port, (int)addrlen);
175         else    verbose(v, "%s %s port %d", str, dest, (int)port);
176 }
177
178 int 
179 extstrtoaddr(const char* str, struct sockaddr_storage* addr,
180         socklen_t* addrlen)
181 {
182         char* s;
183         int port = UNBOUND_DNS_PORT;
184         if((s=strchr(str, '@'))) {
185                 char buf[MAX_ADDR_STRLEN];
186                 if(s-str >= MAX_ADDR_STRLEN) {
187                         return 0;
188                 }
189                 (void)strlcpy(buf, str, sizeof(buf));
190                 buf[s-str] = 0;
191                 port = atoi(s+1);
192                 if(port == 0 && strcmp(s+1,"0")!=0) {
193                         return 0;
194                 }
195                 return ipstrtoaddr(buf, port, addr, addrlen);
196         }
197         return ipstrtoaddr(str, port, addr, addrlen);
198 }
199
200
201 int 
202 ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
203         socklen_t* addrlen)
204 {
205         uint16_t p;
206         if(!ip) return 0;
207         p = (uint16_t) port;
208         if(str_is_ip6(ip)) {
209                 char buf[MAX_ADDR_STRLEN];
210                 char* s;
211                 struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
212                 *addrlen = (socklen_t)sizeof(struct sockaddr_in6);
213                 memset(sa, 0, *addrlen);
214                 sa->sin6_family = AF_INET6;
215                 sa->sin6_port = (in_port_t)htons(p);
216                 if((s=strchr(ip, '%'))) { /* ip6%interface, rfc 4007 */
217                         if(s-ip >= MAX_ADDR_STRLEN)
218                                 return 0;
219                         (void)strlcpy(buf, ip, sizeof(buf));
220                         buf[s-ip]=0;
221                         sa->sin6_scope_id = (uint32_t)atoi(s+1);
222                         ip = buf;
223                 }
224                 if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) {
225                         return 0;
226                 }
227         } else { /* ip4 */
228                 struct sockaddr_in* sa = (struct sockaddr_in*)addr;
229                 *addrlen = (socklen_t)sizeof(struct sockaddr_in);
230                 memset(sa, 0, *addrlen);
231                 sa->sin_family = AF_INET;
232                 sa->sin_port = (in_port_t)htons(p);
233                 if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) {
234                         return 0;
235                 }
236         }
237         return 1;
238 }
239
240 int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
241         socklen_t* addrlen, int* net)
242 {
243         char* s = NULL;
244         *net = (str_is_ip6(str)?128:32);
245         if((s=strchr(str, '/'))) {
246                 if(atoi(s+1) > *net) {
247                         log_err("netblock too large: %s", str);
248                         return 0;
249                 }
250                 *net = atoi(s+1);
251                 if(*net == 0 && strcmp(s+1, "0") != 0) {
252                         log_err("cannot parse netblock: '%s'", str);
253                         return 0;
254                 }
255                 if(!(s = strdup(str))) {
256                         log_err("out of memory");
257                         return 0;
258                 }
259                 *strchr(s, '/') = '\0';
260         }
261         if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) {
262                 free(s);
263                 log_err("cannot parse ip address: '%s'", str);
264                 return 0;
265         }
266         if(s) {
267                 free(s);
268                 addr_mask(addr, *addrlen, *net);
269         }
270         return 1;
271 }
272
273 void
274 log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, 
275         uint16_t type, uint16_t dclass)
276 {
277         char buf[LDNS_MAX_DOMAINLEN+1];
278         char t[12], c[12];
279         const char *ts, *cs; 
280         if(verbosity < v)
281                 return;
282         dname_str(name, buf);
283         if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG";
284         else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR";
285         else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR";
286         else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB";
287         else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA";
288         else if(type == LDNS_RR_TYPE_ANY) ts = "ANY";
289         else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name)
290                 ts = sldns_rr_descript(type)->_name;
291         else {
292                 snprintf(t, sizeof(t), "TYPE%d", (int)type);
293                 ts = t;
294         }
295         if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) &&
296                 sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name)
297                 cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name;
298         else {
299                 snprintf(c, sizeof(c), "CLASS%d", (int)dclass);
300                 cs = c;
301         }
302         log_info("%s %s %s %s", str, buf, ts, cs);
303 }
304
305 void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, 
306         struct sockaddr_storage* addr, socklen_t addrlen)
307 {
308         uint16_t port;
309         const char* family = "unknown_family ";
310         char namebuf[LDNS_MAX_DOMAINLEN+1];
311         char dest[100];
312         int af = (int)((struct sockaddr_in*)addr)->sin_family;
313         void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
314         if(verbosity < v)
315                 return;
316         switch(af) {
317                 case AF_INET: family=""; break;
318                 case AF_INET6: family="";
319                         sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
320                         break;
321                 case AF_LOCAL: family="local "; break;
322                 default: break;
323         }
324         if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
325                 (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest));
326         }
327         dest[sizeof(dest)-1] = 0;
328         port = ntohs(((struct sockaddr_in*)addr)->sin_port);
329         dname_str(zone, namebuf);
330         if(af != AF_INET && af != AF_INET6)
331                 verbose(v, "%s <%s> %s%s#%d (addrlen %d)",
332                         str, namebuf, family, dest, (int)port, (int)addrlen);
333         else    verbose(v, "%s <%s> %s%s#%d",
334                         str, namebuf, family, dest, (int)port);
335 }
336
337 void log_err_addr(const char* str, const char* err,
338         struct sockaddr_storage* addr, socklen_t addrlen)
339 {
340         uint16_t port;
341         char dest[100];
342         int af = (int)((struct sockaddr_in*)addr)->sin_family;
343         void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
344         if(af == AF_INET6)
345                 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
346         if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
347                 (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest));
348         }
349         dest[sizeof(dest)-1] = 0;
350         port = ntohs(((struct sockaddr_in*)addr)->sin_port);
351         if(verbosity >= 4)
352                 log_err("%s: %s for %s port %d (len %d)", str, err, dest,
353                         (int)port, (int)addrlen);
354         else    log_err("%s: %s for %s", str, err, dest);
355 }
356
357 int
358 sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1, 
359         struct sockaddr_storage* addr2, socklen_t len2)
360 {
361         struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
362         struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
363         struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
364         struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
365         if(len1 < len2)
366                 return -1;
367         if(len1 > len2)
368                 return 1;
369         log_assert(len1 == len2);
370         if( p1_in->sin_family < p2_in->sin_family)
371                 return -1;
372         if( p1_in->sin_family > p2_in->sin_family)
373                 return 1;
374         log_assert( p1_in->sin_family == p2_in->sin_family );
375         /* compare ip4 */
376         if( p1_in->sin_family == AF_INET ) {
377                 /* just order it, ntohs not required */
378                 if(p1_in->sin_port < p2_in->sin_port)
379                         return -1;
380                 if(p1_in->sin_port > p2_in->sin_port)
381                         return 1;
382                 log_assert(p1_in->sin_port == p2_in->sin_port);
383                 return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE);
384         } else if (p1_in6->sin6_family == AF_INET6) {
385                 /* just order it, ntohs not required */
386                 if(p1_in6->sin6_port < p2_in6->sin6_port)
387                         return -1;
388                 if(p1_in6->sin6_port > p2_in6->sin6_port)
389                         return 1;
390                 log_assert(p1_in6->sin6_port == p2_in6->sin6_port);
391                 return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, 
392                         INET6_SIZE);
393         } else {
394                 /* eek unknown type, perform this comparison for sanity. */
395                 return memcmp(addr1, addr2, len1);
396         }
397 }
398
399 int
400 sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, 
401         struct sockaddr_storage* addr2, socklen_t len2)
402 {
403         struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
404         struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
405         struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
406         struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
407         if(len1 < len2)
408                 return -1;
409         if(len1 > len2)
410                 return 1;
411         log_assert(len1 == len2);
412         if( p1_in->sin_family < p2_in->sin_family)
413                 return -1;
414         if( p1_in->sin_family > p2_in->sin_family)
415                 return 1;
416         log_assert( p1_in->sin_family == p2_in->sin_family );
417         /* compare ip4 */
418         if( p1_in->sin_family == AF_INET ) {
419                 return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE);
420         } else if (p1_in6->sin6_family == AF_INET6) {
421                 return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, 
422                         INET6_SIZE);
423         } else {
424                 /* eek unknown type, perform this comparison for sanity. */
425                 return memcmp(addr1, addr2, len1);
426         }
427 }
428
429 int
430 addr_is_ip6(struct sockaddr_storage* addr, socklen_t len)
431 {
432         if(len == (socklen_t)sizeof(struct sockaddr_in6) &&
433                 ((struct sockaddr_in6*)addr)->sin6_family == AF_INET6)
434                 return 1;
435         else    return 0;
436 }
437
438 void
439 addr_mask(struct sockaddr_storage* addr, socklen_t len, int net)
440 {
441         uint8_t mask[8] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
442         int i, max;
443         uint8_t* s;
444         if(addr_is_ip6(addr, len)) {
445                 s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr;
446                 max = 128;
447         } else {
448                 s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr;
449                 max = 32;
450         }
451         if(net >= max)
452                 return;
453         for(i=net/8+1; i<max/8; i++) {
454                 s[i] = 0;
455         }
456         s[net/8] &= mask[net&0x7];
457 }
458
459 int
460 addr_in_common(struct sockaddr_storage* addr1, int net1,
461         struct sockaddr_storage* addr2, int net2, socklen_t addrlen)
462 {
463         int min = (net1<net2)?net1:net2;
464         int i, to;
465         int match = 0;
466         uint8_t* s1, *s2;
467         if(addr_is_ip6(addr1, addrlen)) {
468                 s1 = (uint8_t*)&((struct sockaddr_in6*)addr1)->sin6_addr;
469                 s2 = (uint8_t*)&((struct sockaddr_in6*)addr2)->sin6_addr;
470                 to = 16;
471         } else {
472                 s1 = (uint8_t*)&((struct sockaddr_in*)addr1)->sin_addr;
473                 s2 = (uint8_t*)&((struct sockaddr_in*)addr2)->sin_addr;
474                 to = 4;
475         }
476         /* match = bits_in_common(s1, s2, to); */
477         for(i=0; i<to; i++) {
478                 if(s1[i] == s2[i]) {
479                         match += 8;
480                 } else {
481                         uint8_t z = s1[i]^s2[i];
482                         log_assert(z);
483                         while(!(z&0x80)) {
484                                 match++;
485                                 z<<=1;
486                         }
487                         break;
488                 }
489         }
490         if(match > min) match = min;
491         return match;
492 }
493
494 void 
495 addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen, 
496         char* buf, size_t len)
497 {
498         int af = (int)((struct sockaddr_in*)addr)->sin_family;
499         void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
500         if(addr_is_ip6(addr, addrlen))
501                 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
502         if(inet_ntop(af, sinaddr, buf, (socklen_t)len) == 0) {
503                 snprintf(buf, len, "(inet_ntop_error)");
504         }
505 }
506
507 int 
508 addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen)
509 {
510         /* prefix for ipv4 into ipv6 mapping is ::ffff:x.x.x.x */
511         const uint8_t map_prefix[16] = 
512                 {0,0,0,0,  0,0,0,0, 0,0,0xff,0xff, 0,0,0,0};
513         uint8_t* s;
514         if(!addr_is_ip6(addr, addrlen))
515                 return 0;
516         /* s is 16 octet ipv6 address string */
517         s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr;
518         return (memcmp(s, map_prefix, 12) == 0);
519 }
520
521 int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen)
522 {
523         int af = (int)((struct sockaddr_in*)addr)->sin_family;
524         void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
525         return af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in)
526                 && memcmp(sinaddr, "\377\377\377\377", 4) == 0;
527 }
528
529 int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen)
530 {
531         int af = (int)((struct sockaddr_in*)addr)->sin_family;
532         void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
533         void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr;
534         if(af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in)
535                 && memcmp(sinaddr, "\000\000\000\000", 4) == 0)
536                 return 1;
537         else if(af==AF_INET6 && addrlen>=(socklen_t)sizeof(struct sockaddr_in6)
538                 && memcmp(sin6addr, "\000\000\000\000\000\000\000\000"
539                 "\000\000\000\000\000\000\000\000", 16) == 0)
540                 return 1;
541         return 0;
542 }
543
544 void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr,
545         socklen_t len, struct regional* region)
546 {
547         struct sock_list* add = (struct sock_list*)regional_alloc(region,
548                 sizeof(*add) - sizeof(add->addr) + (size_t)len);
549         if(!add) {
550                 log_err("out of memory in socketlist insert");
551                 return;
552         }
553         log_assert(list);
554         add->next = *list;
555         add->len = len;
556         *list = add;
557         if(len) memmove(&add->addr, addr, len);
558 }
559
560 void sock_list_prepend(struct sock_list** list, struct sock_list* add)
561 {
562         struct sock_list* last = add;
563         if(!last) 
564                 return;
565         while(last->next)
566                 last = last->next;
567         last->next = *list;
568         *list = add;
569 }
570
571 int sock_list_find(struct sock_list* list, struct sockaddr_storage* addr,
572         socklen_t len)
573 {
574         while(list) {
575                 if(len == list->len) {
576                         if(len == 0 || sockaddr_cmp_addr(addr, len, 
577                                 &list->addr, list->len) == 0)
578                                 return 1;
579                 }
580                 list = list->next;
581         }
582         return 0;
583 }
584
585 void sock_list_merge(struct sock_list** list, struct regional* region,
586         struct sock_list* add)
587 {
588         struct sock_list* p;
589         for(p=add; p; p=p->next) {
590                 if(!sock_list_find(*list, &p->addr, p->len))
591                         sock_list_insert(list, &p->addr, p->len, region);
592         }
593 }
594
595 void
596 log_crypto_err(const char* str)
597 {
598 #ifdef HAVE_SSL
599         /* error:[error code]:[library name]:[function name]:[reason string] */
600         char buf[128];
601         unsigned long e;
602         ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
603         log_err("%s crypto %s", str, buf);
604         while( (e=ERR_get_error()) ) {
605                 ERR_error_string_n(e, buf, sizeof(buf));
606                 log_err("and additionally crypto %s", buf);
607         }
608 #else
609         (void)str;
610 #endif /* HAVE_SSL */
611 }
612
613 void* listen_sslctx_create(char* key, char* pem, char* verifypem)
614 {
615 #ifdef HAVE_SSL
616         SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
617         if(!ctx) {
618                 log_crypto_err("could not SSL_CTX_new");
619                 return NULL;
620         }
621         /* no SSLv2, SSLv3 because has defects */
622         if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){
623                 log_crypto_err("could not set SSL_OP_NO_SSLv2");
624                 SSL_CTX_free(ctx);
625                 return NULL;
626         }
627         if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)){
628                 log_crypto_err("could not set SSL_OP_NO_SSLv3");
629                 SSL_CTX_free(ctx);
630                 return NULL;
631         }
632         if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) {
633                 log_err("error for cert file: %s", pem);
634                 log_crypto_err("error in SSL_CTX use_certificate_file");
635                 SSL_CTX_free(ctx);
636                 return NULL;
637         }
638         if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
639                 log_err("error for private key file: %s", key);
640                 log_crypto_err("Error in SSL_CTX use_PrivateKey_file");
641                 SSL_CTX_free(ctx);
642                 return NULL;
643         }
644         if(!SSL_CTX_check_private_key(ctx)) {
645                 log_err("error for key file: %s", key);
646                 log_crypto_err("Error in SSL_CTX check_private_key");
647                 SSL_CTX_free(ctx);
648                 return NULL;
649         }
650
651         if(verifypem && verifypem[0]) {
652                 if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) {
653                         log_crypto_err("Error in SSL_CTX verify locations");
654                         SSL_CTX_free(ctx);
655                         return NULL;
656                 }
657                 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(
658                         verifypem));
659                 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
660         }
661         return ctx;
662 #else
663         (void)key; (void)pem; (void)verifypem;
664         return NULL;
665 #endif
666 }
667
668 void* connect_sslctx_create(char* key, char* pem, char* verifypem)
669 {
670 #ifdef HAVE_SSL
671         SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
672         if(!ctx) {
673                 log_crypto_err("could not allocate SSL_CTX pointer");
674                 return NULL;
675         }
676         if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)) {
677                 log_crypto_err("could not set SSL_OP_NO_SSLv2");
678                 SSL_CTX_free(ctx);
679                 return NULL;
680         }
681         if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)) {
682                 log_crypto_err("could not set SSL_OP_NO_SSLv3");
683                 SSL_CTX_free(ctx);
684                 return NULL;
685         }
686         if(key && key[0]) {
687                 if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) {
688                         log_err("error in client certificate %s", pem);
689                         log_crypto_err("error in certificate file");
690                         SSL_CTX_free(ctx);
691                         return NULL;
692                 }
693                 if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
694                         log_err("error in client private key %s", key);
695                         log_crypto_err("error in key file");
696                         SSL_CTX_free(ctx);
697                         return NULL;
698                 }
699                 if(!SSL_CTX_check_private_key(ctx)) {
700                         log_err("error in client key %s", key);
701                         log_crypto_err("error in SSL_CTX_check_private_key");
702                         SSL_CTX_free(ctx);
703                         return NULL;
704                 }
705         }
706         if(verifypem && verifypem[0]) {
707                 if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) {
708                         log_crypto_err("error in SSL_CTX verify");
709                         SSL_CTX_free(ctx);
710                         return NULL;
711                 }
712                 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
713         }
714         return ctx;
715 #else
716         (void)key; (void)pem; (void)verifypem;
717         return NULL;
718 #endif
719 }
720
721 void* incoming_ssl_fd(void* sslctx, int fd)
722 {
723 #ifdef HAVE_SSL
724         SSL* ssl = SSL_new((SSL_CTX*)sslctx);
725         if(!ssl) {
726                 log_crypto_err("could not SSL_new");
727                 return NULL;
728         }
729         SSL_set_accept_state(ssl);
730         (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
731         if(!SSL_set_fd(ssl, fd)) {
732                 log_crypto_err("could not SSL_set_fd");
733                 SSL_free(ssl);
734                 return NULL;
735         }
736         return ssl;
737 #else
738         (void)sslctx; (void)fd;
739         return NULL;
740 #endif
741 }
742
743 void* outgoing_ssl_fd(void* sslctx, int fd)
744 {
745 #ifdef HAVE_SSL
746         SSL* ssl = SSL_new((SSL_CTX*)sslctx);
747         if(!ssl) {
748                 log_crypto_err("could not SSL_new");
749                 return NULL;
750         }
751         SSL_set_connect_state(ssl);
752         (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
753         if(!SSL_set_fd(ssl, fd)) {
754                 log_crypto_err("could not SSL_set_fd");
755                 SSL_free(ssl);
756                 return NULL;
757         }
758         return ssl;
759 #else
760         (void)sslctx; (void)fd;
761         return NULL;
762 #endif
763 }
764
765 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
766 /** global lock list for openssl locks */
767 static lock_basic_t *ub_openssl_locks = NULL;
768
769 /** callback that gets thread id for openssl */
770 static unsigned long
771 ub_crypto_id_cb(void)
772 {
773         return (unsigned long)ub_thread_self();
774 }
775
776 static void
777 ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file),
778         int ATTR_UNUSED(line))
779 {
780         if((mode&CRYPTO_LOCK)) {
781                 lock_basic_lock(&ub_openssl_locks[type]);
782         } else {
783                 lock_basic_unlock(&ub_openssl_locks[type]);
784         }
785 }
786 #endif /* OPENSSL_THREADS */
787
788 int ub_openssl_lock_init(void)
789 {
790 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
791         int i;
792         ub_openssl_locks = (lock_basic_t*)malloc(
793                 sizeof(lock_basic_t)*CRYPTO_num_locks());
794         if(!ub_openssl_locks)
795                 return 0;
796         for(i=0; i<CRYPTO_num_locks(); i++) {
797                 lock_basic_init(&ub_openssl_locks[i]);
798         }
799         CRYPTO_set_id_callback(&ub_crypto_id_cb);
800         CRYPTO_set_locking_callback(&ub_crypto_lock_cb);
801 #endif /* OPENSSL_THREADS */
802         return 1;
803 }
804
805 void ub_openssl_lock_delete(void)
806 {
807 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
808         int i;
809         if(!ub_openssl_locks)
810                 return;
811         CRYPTO_set_id_callback(NULL);
812         CRYPTO_set_locking_callback(NULL);
813         for(i=0; i<CRYPTO_num_locks(); i++) {
814                 lock_basic_destroy(&ub_openssl_locks[i]);
815         }
816         free(ub_openssl_locks);
817 #endif /* OPENSSL_THREADS */
818 }
819