]>
git.saurik.com Git - apple/network_cmds.git/blob - unbound/util/net_help.c
ad69488d9fff150c00fdb11afbc81167d838488f
2 * util/net_help.c - implementation of the network helper code
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
6 * This software is open source.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
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.
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.
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.
37 * Implementation of net_help.h.
41 #include "util/net_help.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"
49 #ifdef HAVE_OPENSSL_SSL_H
50 #include <openssl/ssl.h>
52 #ifdef HAVE_OPENSSL_ERR_H
53 #include <openssl/err.h>
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;
61 /** minimal responses when positive answer: default is no */
62 int MINIMAL_RESPONSES
= 0;
64 /** rrset order roundrobin: default is no */
65 int RRSET_ROUNDROBIN
= 0;
67 /* returns true is string addr is an ip6 specced address */
69 str_is_ip6(const char* str
)
77 fd_set_nonblock(int s
)
81 if((flag
= fcntl(s
, F_GETFL
)) == -1) {
82 log_err("can't fcntl F_GETFL: %s", strerror(errno
));
86 if(fcntl(s
, F_SETFL
, flag
) == -1) {
87 log_err("can't fcntl F_SETFL: %s", strerror(errno
));
90 #elif defined(HAVE_IOCTLSOCKET)
92 if(ioctlsocket(s
, FIONBIO
, &on
) != 0) {
93 log_err("can't ioctlsocket FIONBIO on: %s",
94 wsa_strerror(WSAGetLastError()));
105 if((flag
= fcntl(s
, F_GETFL
)) == -1) {
106 log_err("cannot fcntl F_GETFL: %s", strerror(errno
));
110 if(fcntl(s
, F_SETFL
, flag
) == -1) {
111 log_err("cannot fcntl F_SETFL: %s", strerror(errno
));
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()));
127 if(num
== 0) return 1;
128 return (num
& (num
-1)) == 0;
132 memdup(void* data
, size_t len
)
135 if(!data
) return NULL
;
136 if(len
== 0) return NULL
;
139 memcpy(d
, data
, len
);
144 log_addr(enum verbosity_value v
, const char* str
,
145 struct sockaddr_storage
* addr
, socklen_t addrlen
)
148 const char* family
= "unknown";
150 int af
= (int)((struct sockaddr_in
*)addr
)->sin_family
;
151 void* sinaddr
= &((struct sockaddr_in
*)addr
)->sin_addr
;
155 case AF_INET
: family
="ip4"; break;
156 case AF_INET6
: family
="ip6";
157 sinaddr
= &((struct sockaddr_in6
*)addr
)->sin6_addr
;
159 case AF_UNIX
: family
="unix"; break;
162 if(inet_ntop(af
, sinaddr
, dest
, (socklen_t
)sizeof(dest
)) == 0) {
163 (void)strlcpy(dest
, "(inet_ntop error)", sizeof(dest
));
165 dest
[sizeof(dest
)-1] = 0;
166 port
= ntohs(((struct sockaddr_in
*)addr
)->sin_port
);
168 verbose(v
, "%s %s %s port %d (len %d)", str
, family
, dest
,
169 (int)port
, (int)addrlen
);
170 else verbose(v
, "%s %s port %d", str
, dest
, (int)port
);
174 extstrtoaddr(const char* str
, struct sockaddr_storage
* addr
,
178 int port
= UNBOUND_DNS_PORT
;
179 if((s
=strchr(str
, '@'))) {
180 char buf
[MAX_ADDR_STRLEN
];
181 if(s
-str
>= MAX_ADDR_STRLEN
) {
184 (void)strlcpy(buf
, str
, sizeof(buf
));
187 if(port
== 0 && strcmp(s
+1,"0")!=0) {
190 return ipstrtoaddr(buf
, port
, addr
, addrlen
);
192 return ipstrtoaddr(str
, port
, addr
, addrlen
);
197 ipstrtoaddr(const char* ip
, int port
, struct sockaddr_storage
* addr
,
204 char buf
[MAX_ADDR_STRLEN
];
206 struct sockaddr_in6
* sa
= (struct sockaddr_in6
*)addr
;
207 *addrlen
= (socklen_t
)sizeof(struct sockaddr_in6
);
208 memset(sa
, 0, *addrlen
);
209 sa
->sin6_family
= AF_INET6
;
210 sa
->sin6_port
= (in_port_t
)htons(p
);
211 if((s
=strchr(ip
, '%'))) { /* ip6%interface, rfc 4007 */
212 if(s
-ip
>= MAX_ADDR_STRLEN
)
214 (void)strlcpy(buf
, ip
, sizeof(buf
));
216 sa
->sin6_scope_id
= (uint32_t)atoi(s
+1);
219 if(inet_pton((int)sa
->sin6_family
, ip
, &sa
->sin6_addr
) <= 0) {
223 struct sockaddr_in
* sa
= (struct sockaddr_in
*)addr
;
224 *addrlen
= (socklen_t
)sizeof(struct sockaddr_in
);
225 memset(sa
, 0, *addrlen
);
226 sa
->sin_family
= AF_INET
;
227 sa
->sin_port
= (in_port_t
)htons(p
);
228 if(inet_pton((int)sa
->sin_family
, ip
, &sa
->sin_addr
) <= 0) {
235 int netblockstrtoaddr(const char* str
, int port
, struct sockaddr_storage
* addr
,
236 socklen_t
* addrlen
, int* net
)
239 *net
= (str_is_ip6(str
)?128:32);
240 if((s
=strchr(str
, '/'))) {
241 if(atoi(s
+1) > *net
) {
242 log_err("netblock too large: %s", str
);
246 if(*net
== 0 && strcmp(s
+1, "0") != 0) {
247 log_err("cannot parse netblock: '%s'", str
);
250 if(!(s
= strdup(str
))) {
251 log_err("out of memory");
254 *strchr(s
, '/') = '\0';
256 if(!ipstrtoaddr(s
?s
:str
, port
, addr
, addrlen
)) {
258 log_err("cannot parse ip address: '%s'", str
);
263 addr_mask(addr
, *addrlen
, *net
);
269 log_nametypeclass(enum verbosity_value v
, const char* str
, uint8_t* name
,
270 uint16_t type
, uint16_t dclass
)
272 char buf
[LDNS_MAX_DOMAINLEN
+1];
277 dname_str(name
, buf
);
278 if(type
== LDNS_RR_TYPE_TSIG
) ts
= "TSIG";
279 else if(type
== LDNS_RR_TYPE_IXFR
) ts
= "IXFR";
280 else if(type
== LDNS_RR_TYPE_AXFR
) ts
= "AXFR";
281 else if(type
== LDNS_RR_TYPE_MAILB
) ts
= "MAILB";
282 else if(type
== LDNS_RR_TYPE_MAILA
) ts
= "MAILA";
283 else if(type
== LDNS_RR_TYPE_ANY
) ts
= "ANY";
284 else if(sldns_rr_descript(type
) && sldns_rr_descript(type
)->_name
)
285 ts
= sldns_rr_descript(type
)->_name
;
287 snprintf(t
, sizeof(t
), "TYPE%d", (int)type
);
290 if(sldns_lookup_by_id(sldns_rr_classes
, (int)dclass
) &&
291 sldns_lookup_by_id(sldns_rr_classes
, (int)dclass
)->name
)
292 cs
= sldns_lookup_by_id(sldns_rr_classes
, (int)dclass
)->name
;
294 snprintf(c
, sizeof(c
), "CLASS%d", (int)dclass
);
297 log_info("%s %s %s %s", str
, buf
, ts
, cs
);
300 void log_name_addr(enum verbosity_value v
, const char* str
, uint8_t* zone
,
301 struct sockaddr_storage
* addr
, socklen_t addrlen
)
304 const char* family
= "unknown_family ";
305 char namebuf
[LDNS_MAX_DOMAINLEN
+1];
307 int af
= (int)((struct sockaddr_in
*)addr
)->sin_family
;
308 void* sinaddr
= &((struct sockaddr_in
*)addr
)->sin_addr
;
312 case AF_INET
: family
=""; break;
313 case AF_INET6
: family
="";
314 sinaddr
= &((struct sockaddr_in6
*)addr
)->sin6_addr
;
316 case AF_UNIX
: family
="unix_family "; break;
319 if(inet_ntop(af
, sinaddr
, dest
, (socklen_t
)sizeof(dest
)) == 0) {
320 (void)strlcpy(dest
, "(inet_ntop error)", sizeof(dest
));
322 dest
[sizeof(dest
)-1] = 0;
323 port
= ntohs(((struct sockaddr_in
*)addr
)->sin_port
);
324 dname_str(zone
, namebuf
);
325 if(af
!= AF_INET
&& af
!= AF_INET6
)
326 verbose(v
, "%s <%s> %s%s#%d (addrlen %d)",
327 str
, namebuf
, family
, dest
, (int)port
, (int)addrlen
);
328 else verbose(v
, "%s <%s> %s%s#%d",
329 str
, namebuf
, family
, dest
, (int)port
);
332 void log_err_addr(const char* str
, const char* err
,
333 struct sockaddr_storage
* addr
, socklen_t addrlen
)
337 int af
= (int)((struct sockaddr_in
*)addr
)->sin_family
;
338 void* sinaddr
= &((struct sockaddr_in
*)addr
)->sin_addr
;
340 sinaddr
= &((struct sockaddr_in6
*)addr
)->sin6_addr
;
341 if(inet_ntop(af
, sinaddr
, dest
, (socklen_t
)sizeof(dest
)) == 0) {
342 (void)strlcpy(dest
, "(inet_ntop error)", sizeof(dest
));
344 dest
[sizeof(dest
)-1] = 0;
345 port
= ntohs(((struct sockaddr_in
*)addr
)->sin_port
);
347 log_err("%s: %s for %s port %d (len %d)", str
, err
, dest
,
348 (int)port
, (int)addrlen
);
349 else log_err("%s: %s for %s", str
, err
, dest
);
353 sockaddr_cmp(struct sockaddr_storage
* addr1
, socklen_t len1
,
354 struct sockaddr_storage
* addr2
, socklen_t len2
)
356 struct sockaddr_in
* p1_in
= (struct sockaddr_in
*)addr1
;
357 struct sockaddr_in
* p2_in
= (struct sockaddr_in
*)addr2
;
358 struct sockaddr_in6
* p1_in6
= (struct sockaddr_in6
*)addr1
;
359 struct sockaddr_in6
* p2_in6
= (struct sockaddr_in6
*)addr2
;
364 log_assert(len1
== len2
);
365 if( p1_in
->sin_family
< p2_in
->sin_family
)
367 if( p1_in
->sin_family
> p2_in
->sin_family
)
369 log_assert( p1_in
->sin_family
== p2_in
->sin_family
);
371 if( p1_in
->sin_family
== AF_INET
) {
372 /* just order it, ntohs not required */
373 if(p1_in
->sin_port
< p2_in
->sin_port
)
375 if(p1_in
->sin_port
> p2_in
->sin_port
)
377 log_assert(p1_in
->sin_port
== p2_in
->sin_port
);
378 return memcmp(&p1_in
->sin_addr
, &p2_in
->sin_addr
, INET_SIZE
);
379 } else if (p1_in6
->sin6_family
== AF_INET6
) {
380 /* just order it, ntohs not required */
381 if(p1_in6
->sin6_port
< p2_in6
->sin6_port
)
383 if(p1_in6
->sin6_port
> p2_in6
->sin6_port
)
385 log_assert(p1_in6
->sin6_port
== p2_in6
->sin6_port
);
386 return memcmp(&p1_in6
->sin6_addr
, &p2_in6
->sin6_addr
,
389 /* eek unknown type, perform this comparison for sanity. */
390 return memcmp(addr1
, addr2
, len1
);
395 sockaddr_cmp_addr(struct sockaddr_storage
* addr1
, socklen_t len1
,
396 struct sockaddr_storage
* addr2
, socklen_t len2
)
398 struct sockaddr_in
* p1_in
= (struct sockaddr_in
*)addr1
;
399 struct sockaddr_in
* p2_in
= (struct sockaddr_in
*)addr2
;
400 struct sockaddr_in6
* p1_in6
= (struct sockaddr_in6
*)addr1
;
401 struct sockaddr_in6
* p2_in6
= (struct sockaddr_in6
*)addr2
;
406 log_assert(len1
== len2
);
407 if( p1_in
->sin_family
< p2_in
->sin_family
)
409 if( p1_in
->sin_family
> p2_in
->sin_family
)
411 log_assert( p1_in
->sin_family
== p2_in
->sin_family
);
413 if( p1_in
->sin_family
== AF_INET
) {
414 return memcmp(&p1_in
->sin_addr
, &p2_in
->sin_addr
, INET_SIZE
);
415 } else if (p1_in6
->sin6_family
== AF_INET6
) {
416 return memcmp(&p1_in6
->sin6_addr
, &p2_in6
->sin6_addr
,
419 /* eek unknown type, perform this comparison for sanity. */
420 return memcmp(addr1
, addr2
, len1
);
425 addr_is_ip6(struct sockaddr_storage
* addr
, socklen_t len
)
427 if(len
== (socklen_t
)sizeof(struct sockaddr_in6
) &&
428 ((struct sockaddr_in6
*)addr
)->sin6_family
== AF_INET6
)
434 addr_mask(struct sockaddr_storage
* addr
, socklen_t len
, int net
)
436 uint8_t mask
[8] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
439 if(addr_is_ip6(addr
, len
)) {
440 s
= (uint8_t*)&((struct sockaddr_in6
*)addr
)->sin6_addr
;
443 s
= (uint8_t*)&((struct sockaddr_in
*)addr
)->sin_addr
;
448 for(i
=net
/8+1; i
<max
/8; i
++) {
451 s
[net
/8] &= mask
[net
&0x7];
455 addr_in_common(struct sockaddr_storage
* addr1
, int net1
,
456 struct sockaddr_storage
* addr2
, int net2
, socklen_t addrlen
)
458 int min
= (net1
<net2
)?net1
:net2
;
462 if(addr_is_ip6(addr1
, addrlen
)) {
463 s1
= (uint8_t*)&((struct sockaddr_in6
*)addr1
)->sin6_addr
;
464 s2
= (uint8_t*)&((struct sockaddr_in6
*)addr2
)->sin6_addr
;
467 s1
= (uint8_t*)&((struct sockaddr_in
*)addr1
)->sin_addr
;
468 s2
= (uint8_t*)&((struct sockaddr_in
*)addr2
)->sin_addr
;
471 /* match = bits_in_common(s1, s2, to); */
472 for(i
=0; i
<to
; i
++) {
476 uint8_t z
= s1
[i
]^s2
[i
];
485 if(match
> min
) match
= min
;
490 addr_to_str(struct sockaddr_storage
* addr
, socklen_t addrlen
,
491 char* buf
, size_t len
)
493 int af
= (int)((struct sockaddr_in
*)addr
)->sin_family
;
494 void* sinaddr
= &((struct sockaddr_in
*)addr
)->sin_addr
;
495 if(addr_is_ip6(addr
, addrlen
))
496 sinaddr
= &((struct sockaddr_in6
*)addr
)->sin6_addr
;
497 if(inet_ntop(af
, sinaddr
, buf
, (socklen_t
)len
) == 0) {
498 snprintf(buf
, len
, "(inet_ntop_error)");
503 addr_is_ip4mapped(struct sockaddr_storage
* addr
, socklen_t addrlen
)
505 /* prefix for ipv4 into ipv6 mapping is ::ffff:x.x.x.x */
506 const uint8_t map_prefix
[16] =
507 {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 0,0,0,0};
509 if(!addr_is_ip6(addr
, addrlen
))
511 /* s is 16 octet ipv6 address string */
512 s
= (uint8_t*)&((struct sockaddr_in6
*)addr
)->sin6_addr
;
513 return (memcmp(s
, map_prefix
, 12) == 0);
516 int addr_is_broadcast(struct sockaddr_storage
* addr
, socklen_t addrlen
)
518 int af
= (int)((struct sockaddr_in
*)addr
)->sin_family
;
519 void* sinaddr
= &((struct sockaddr_in
*)addr
)->sin_addr
;
520 return af
== AF_INET
&& addrlen
>=(socklen_t
)sizeof(struct sockaddr_in
)
521 && memcmp(sinaddr
, "\377\377\377\377", 4) == 0;
524 int addr_is_any(struct sockaddr_storage
* addr
, socklen_t addrlen
)
526 int af
= (int)((struct sockaddr_in
*)addr
)->sin_family
;
527 void* sinaddr
= &((struct sockaddr_in
*)addr
)->sin_addr
;
528 void* sin6addr
= &((struct sockaddr_in6
*)addr
)->sin6_addr
;
529 if(af
== AF_INET
&& addrlen
>=(socklen_t
)sizeof(struct sockaddr_in
)
530 && memcmp(sinaddr
, "\000\000\000\000", 4) == 0)
532 else if(af
==AF_INET6
&& addrlen
>=(socklen_t
)sizeof(struct sockaddr_in6
)
533 && memcmp(sin6addr
, "\000\000\000\000\000\000\000\000"
534 "\000\000\000\000\000\000\000\000", 16) == 0)
539 void sock_list_insert(struct sock_list
** list
, struct sockaddr_storage
* addr
,
540 socklen_t len
, struct regional
* region
)
542 struct sock_list
* add
= (struct sock_list
*)regional_alloc(region
,
543 sizeof(*add
) - sizeof(add
->addr
) + (size_t)len
);
545 log_err("out of memory in socketlist insert");
552 if(len
) memmove(&add
->addr
, addr
, len
);
555 void sock_list_prepend(struct sock_list
** list
, struct sock_list
* add
)
557 struct sock_list
* last
= add
;
566 int sock_list_find(struct sock_list
* list
, struct sockaddr_storage
* addr
,
570 if(len
== list
->len
) {
571 if(len
== 0 || sockaddr_cmp_addr(addr
, len
,
572 &list
->addr
, list
->len
) == 0)
580 void sock_list_merge(struct sock_list
** list
, struct regional
* region
,
581 struct sock_list
* add
)
584 for(p
=add
; p
; p
=p
->next
) {
585 if(!sock_list_find(*list
, &p
->addr
, p
->len
))
586 sock_list_insert(list
, &p
->addr
, p
->len
, region
);
591 log_crypto_err(const char* str
)
594 /* error:[error code]:[library name]:[function name]:[reason string] */
597 ERR_error_string_n(ERR_get_error(), buf
, sizeof(buf
));
598 log_err("%s crypto %s", str
, buf
);
599 while( (e
=ERR_get_error()) ) {
600 ERR_error_string_n(e
, buf
, sizeof(buf
));
601 log_err("and additionally crypto %s", buf
);
605 #endif /* HAVE_SSL */
608 void* listen_sslctx_create(char* key
, char* pem
, char* verifypem
)
611 SSL_CTX
* ctx
= SSL_CTX_new(SSLv23_server_method());
613 log_crypto_err("could not SSL_CTX_new");
616 if(!SSL_CTX_use_certificate_file(ctx
, pem
, SSL_FILETYPE_PEM
)) {
617 log_err("error for cert file: %s", pem
);
618 log_crypto_err("error in SSL_CTX use_certificate_file");
622 if(!SSL_CTX_use_PrivateKey_file(ctx
, key
, SSL_FILETYPE_PEM
)) {
623 log_err("error for private key file: %s", key
);
624 log_crypto_err("Error in SSL_CTX use_PrivateKey_file");
628 if(!SSL_CTX_check_private_key(ctx
)) {
629 log_err("error for key file: %s", key
);
630 log_crypto_err("Error in SSL_CTX check_private_key");
635 if(verifypem
&& verifypem
[0]) {
636 if(!SSL_CTX_load_verify_locations(ctx
, verifypem
, NULL
)) {
637 log_crypto_err("Error in SSL_CTX verify locations");
641 SSL_CTX_set_client_CA_list(ctx
, SSL_load_client_CA_file(
643 SSL_CTX_set_verify(ctx
, SSL_VERIFY_PEER
, NULL
);
647 (void)key
; (void)pem
; (void)verifypem
;
652 void* connect_sslctx_create(char* key
, char* pem
, char* verifypem
)
655 SSL_CTX
* ctx
= SSL_CTX_new(SSLv23_client_method());
657 log_crypto_err("could not allocate SSL_CTX pointer");
661 if(!SSL_CTX_use_certificate_file(ctx
, pem
, SSL_FILETYPE_PEM
)) {
662 log_err("error in client certificate %s", pem
);
663 log_crypto_err("error in certificate file");
667 if(!SSL_CTX_use_PrivateKey_file(ctx
, key
, SSL_FILETYPE_PEM
)) {
668 log_err("error in client private key %s", key
);
669 log_crypto_err("error in key file");
673 if(!SSL_CTX_check_private_key(ctx
)) {
674 log_err("error in client key %s", key
);
675 log_crypto_err("error in SSL_CTX_check_private_key");
680 if(verifypem
&& verifypem
[0]) {
681 if(!SSL_CTX_load_verify_locations(ctx
, verifypem
, NULL
)) {
682 log_crypto_err("error in SSL_CTX verify");
686 SSL_CTX_set_verify(ctx
, SSL_VERIFY_PEER
, NULL
);
690 (void)key
; (void)pem
; (void)verifypem
;
695 void* incoming_ssl_fd(void* sslctx
, int fd
)
698 SSL
* ssl
= SSL_new((SSL_CTX
*)sslctx
);
700 log_crypto_err("could not SSL_new");
703 SSL_set_accept_state(ssl
);
704 (void)SSL_set_mode(ssl
, SSL_MODE_AUTO_RETRY
);
705 if(!SSL_set_fd(ssl
, fd
)) {
706 log_crypto_err("could not SSL_set_fd");
712 (void)sslctx
; (void)fd
;
717 void* outgoing_ssl_fd(void* sslctx
, int fd
)
720 SSL
* ssl
= SSL_new((SSL_CTX
*)sslctx
);
722 log_crypto_err("could not SSL_new");
725 SSL_set_connect_state(ssl
);
726 (void)SSL_set_mode(ssl
, SSL_MODE_AUTO_RETRY
);
727 if(!SSL_set_fd(ssl
, fd
)) {
728 log_crypto_err("could not SSL_set_fd");
734 (void)sslctx
; (void)fd
;
739 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
740 /** global lock list for openssl locks */
741 static lock_basic_t
*ub_openssl_locks
= NULL
;
743 /** callback that gets thread id for openssl */
745 ub_crypto_id_cb(void)
747 return (unsigned long)ub_thread_self();
751 ub_crypto_lock_cb(int mode
, int type
, const char *ATTR_UNUSED(file
),
752 int ATTR_UNUSED(line
))
754 if((mode
&CRYPTO_LOCK
)) {
755 lock_basic_lock(&ub_openssl_locks
[type
]);
757 lock_basic_unlock(&ub_openssl_locks
[type
]);
760 #endif /* OPENSSL_THREADS */
762 int ub_openssl_lock_init(void)
764 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
766 ub_openssl_locks
= (lock_basic_t
*)malloc(
767 sizeof(lock_basic_t
)*CRYPTO_num_locks());
768 if(!ub_openssl_locks
)
770 for(i
=0; i
<CRYPTO_num_locks(); i
++) {
771 lock_basic_init(&ub_openssl_locks
[i
]);
773 CRYPTO_set_id_callback(&ub_crypto_id_cb
);
774 CRYPTO_set_locking_callback(&ub_crypto_lock_cb
);
775 #endif /* OPENSSL_THREADS */
779 void ub_openssl_lock_delete(void)
781 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
783 if(!ub_openssl_locks
)
785 CRYPTO_set_id_callback(NULL
);
786 CRYPTO_set_locking_callback(NULL
);
787 for(i
=0; i
<CRYPTO_num_locks(); i
++) {
788 lock_basic_destroy(&ub_openssl_locks
[i
]);
790 free(ub_openssl_locks
);
791 #endif /* OPENSSL_THREADS */