xref: /freebsd/crypto/openssl/crypto/bio/bss_dgram.c (revision b077aed3)
1 /*
2  * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #ifndef _GNU_SOURCE
11 # define _GNU_SOURCE
12 #endif
13 
14 #include <stdio.h>
15 #include <errno.h>
16 
17 #include "bio_local.h"
18 #ifndef OPENSSL_NO_DGRAM
19 
20 # ifndef OPENSSL_NO_SCTP
21 #  include <netinet/sctp.h>
22 #  include <fcntl.h>
23 #  define OPENSSL_SCTP_DATA_CHUNK_TYPE            0x00
24 #  define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
25 # endif
26 
27 # if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
28 #  define IP_MTU      14        /* linux is lame */
29 # endif
30 
31 # if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
32 #  define IPPROTO_IPV6 41       /* windows is lame */
33 # endif
34 
35 # if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
36 /* Standard definition causes type-punning problems. */
37 #  undef IN6_IS_ADDR_V4MAPPED
38 #  define s6_addr32 __u6_addr.__u6_addr32
39 #  define IN6_IS_ADDR_V4MAPPED(a)               \
40         (((a)->s6_addr32[0] == 0) &&          \
41          ((a)->s6_addr32[1] == 0) &&          \
42          ((a)->s6_addr32[2] == htonl(0x0000ffff)))
43 # endif
44 
45 static int dgram_write(BIO *h, const char *buf, int num);
46 static int dgram_read(BIO *h, char *buf, int size);
47 static int dgram_puts(BIO *h, const char *str);
48 static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
49 static int dgram_new(BIO *h);
50 static int dgram_free(BIO *data);
51 static int dgram_clear(BIO *bio);
52 
53 # ifndef OPENSSL_NO_SCTP
54 static int dgram_sctp_write(BIO *h, const char *buf, int num);
55 static int dgram_sctp_read(BIO *h, char *buf, int size);
56 static int dgram_sctp_puts(BIO *h, const char *str);
57 static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
58 static int dgram_sctp_new(BIO *h);
59 static int dgram_sctp_free(BIO *data);
60 static int dgram_sctp_wait_for_dry(BIO *b);
61 static int dgram_sctp_msg_waiting(BIO *b);
62 #  ifdef SCTP_AUTHENTICATION_EVENT
63 static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
64                                                   *snp);
65 #  endif
66 # endif
67 
68 static int BIO_dgram_should_retry(int s);
69 
70 static void get_current_time(struct timeval *t);
71 
72 static const BIO_METHOD methods_dgramp = {
73     BIO_TYPE_DGRAM,
74     "datagram socket",
75     bwrite_conv,
76     dgram_write,
77     bread_conv,
78     dgram_read,
79     dgram_puts,
80     NULL,                       /* dgram_gets,         */
81     dgram_ctrl,
82     dgram_new,
83     dgram_free,
84     NULL,                       /* dgram_callback_ctrl */
85 };
86 
87 # ifndef OPENSSL_NO_SCTP
88 static const BIO_METHOD methods_dgramp_sctp = {
89     BIO_TYPE_DGRAM_SCTP,
90     "datagram sctp socket",
91     bwrite_conv,
92     dgram_sctp_write,
93     bread_conv,
94     dgram_sctp_read,
95     dgram_sctp_puts,
96     NULL,                       /* dgram_gets,         */
97     dgram_sctp_ctrl,
98     dgram_sctp_new,
99     dgram_sctp_free,
100     NULL,                       /* dgram_callback_ctrl */
101 };
102 # endif
103 
104 typedef struct bio_dgram_data_st {
105     BIO_ADDR peer;
106     unsigned int connected;
107     unsigned int _errno;
108     unsigned int mtu;
109     struct timeval next_timeout;
110     struct timeval socket_timeout;
111     unsigned int peekmode;
112 } bio_dgram_data;
113 
114 # ifndef OPENSSL_NO_SCTP
115 typedef struct bio_dgram_sctp_save_message_st {
116     BIO *bio;
117     char *data;
118     int length;
119 } bio_dgram_sctp_save_message;
120 
121 typedef struct bio_dgram_sctp_data_st {
122     BIO_ADDR peer;
123     unsigned int connected;
124     unsigned int _errno;
125     unsigned int mtu;
126     struct bio_dgram_sctp_sndinfo sndinfo;
127     struct bio_dgram_sctp_rcvinfo rcvinfo;
128     struct bio_dgram_sctp_prinfo prinfo;
129     BIO_dgram_sctp_notification_handler_fn handle_notifications;
130     void *notification_context;
131     int in_handshake;
132     int ccs_rcvd;
133     int ccs_sent;
134     int save_shutdown;
135     int peer_auth_tested;
136 } bio_dgram_sctp_data;
137 # endif
138 
BIO_s_datagram(void)139 const BIO_METHOD *BIO_s_datagram(void)
140 {
141     return &methods_dgramp;
142 }
143 
BIO_new_dgram(int fd,int close_flag)144 BIO *BIO_new_dgram(int fd, int close_flag)
145 {
146     BIO *ret;
147 
148     ret = BIO_new(BIO_s_datagram());
149     if (ret == NULL)
150         return NULL;
151     BIO_set_fd(ret, fd, close_flag);
152     return ret;
153 }
154 
dgram_new(BIO * bi)155 static int dgram_new(BIO *bi)
156 {
157     bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
158 
159     if (data == NULL)
160         return 0;
161     bi->ptr = data;
162     return 1;
163 }
164 
dgram_free(BIO * a)165 static int dgram_free(BIO *a)
166 {
167     bio_dgram_data *data;
168 
169     if (a == NULL)
170         return 0;
171     if (!dgram_clear(a))
172         return 0;
173 
174     data = (bio_dgram_data *)a->ptr;
175     OPENSSL_free(data);
176 
177     return 1;
178 }
179 
dgram_clear(BIO * a)180 static int dgram_clear(BIO *a)
181 {
182     if (a == NULL)
183         return 0;
184     if (a->shutdown) {
185         if (a->init) {
186             BIO_closesocket(a->num);
187         }
188         a->init = 0;
189         a->flags = 0;
190     }
191     return 1;
192 }
193 
dgram_adjust_rcv_timeout(BIO * b)194 static void dgram_adjust_rcv_timeout(BIO *b)
195 {
196 # if defined(SO_RCVTIMEO)
197     bio_dgram_data *data = (bio_dgram_data *)b->ptr;
198 
199     /* Is a timer active? */
200     if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
201         struct timeval timenow, timeleft;
202 
203         /* Read current socket timeout */
204 #  ifdef OPENSSL_SYS_WINDOWS
205         int timeout;
206 
207         int sz = sizeof(timeout);
208         if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
209                        (void *)&timeout, &sz) < 0) {
210             perror("getsockopt");
211         } else {
212             data->socket_timeout.tv_sec = timeout / 1000;
213             data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
214         }
215 #  else
216         socklen_t sz = sizeof(data->socket_timeout);
217         if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
218                        &(data->socket_timeout), &sz) < 0) {
219             perror("getsockopt");
220         } else
221             OPENSSL_assert(sz <= sizeof(data->socket_timeout));
222 #  endif
223 
224         /* Get current time */
225         get_current_time(&timenow);
226 
227         /* Calculate time left until timer expires */
228         memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
229         if (timeleft.tv_usec < timenow.tv_usec) {
230             timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
231             timeleft.tv_sec--;
232         } else {
233             timeleft.tv_usec -= timenow.tv_usec;
234         }
235         if (timeleft.tv_sec < timenow.tv_sec) {
236             timeleft.tv_sec = 0;
237             timeleft.tv_usec = 1;
238         } else {
239             timeleft.tv_sec -= timenow.tv_sec;
240         }
241 
242         /*
243          * Adjust socket timeout if next handshake message timer will expire
244          * earlier.
245          */
246         if ((data->socket_timeout.tv_sec == 0
247              && data->socket_timeout.tv_usec == 0)
248             || (data->socket_timeout.tv_sec > timeleft.tv_sec)
249             || (data->socket_timeout.tv_sec == timeleft.tv_sec
250                 && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
251 #  ifdef OPENSSL_SYS_WINDOWS
252             timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
253             if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
254                            (void *)&timeout, sizeof(timeout)) < 0) {
255                 perror("setsockopt");
256             }
257 #  else
258             if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
259                            sizeof(struct timeval)) < 0) {
260                 perror("setsockopt");
261             }
262 #  endif
263         }
264     }
265 # endif
266 }
267 
dgram_reset_rcv_timeout(BIO * b)268 static void dgram_reset_rcv_timeout(BIO *b)
269 {
270 # if defined(SO_RCVTIMEO)
271     bio_dgram_data *data = (bio_dgram_data *)b->ptr;
272 
273     /* Is a timer active? */
274     if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
275 #  ifdef OPENSSL_SYS_WINDOWS
276         int timeout = data->socket_timeout.tv_sec * 1000 +
277             data->socket_timeout.tv_usec / 1000;
278         if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
279                        (void *)&timeout, sizeof(timeout)) < 0) {
280             perror("setsockopt");
281         }
282 #  else
283         if (setsockopt
284             (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
285              sizeof(struct timeval)) < 0) {
286             perror("setsockopt");
287         }
288 #  endif
289     }
290 # endif
291 }
292 
dgram_read(BIO * b,char * out,int outl)293 static int dgram_read(BIO *b, char *out, int outl)
294 {
295     int ret = 0;
296     bio_dgram_data *data = (bio_dgram_data *)b->ptr;
297     int flags = 0;
298 
299     BIO_ADDR peer;
300     socklen_t len = sizeof(peer);
301 
302     if (out != NULL) {
303         clear_socket_error();
304         memset(&peer, 0, sizeof(peer));
305         dgram_adjust_rcv_timeout(b);
306         if (data->peekmode)
307             flags = MSG_PEEK;
308         ret = recvfrom(b->num, out, outl, flags,
309                        BIO_ADDR_sockaddr_noconst(&peer), &len);
310 
311         if (!data->connected && ret >= 0)
312             BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
313 
314         BIO_clear_retry_flags(b);
315         if (ret < 0) {
316             if (BIO_dgram_should_retry(ret)) {
317                 BIO_set_retry_read(b);
318                 data->_errno = get_last_socket_error();
319             }
320         }
321 
322         dgram_reset_rcv_timeout(b);
323     }
324     return ret;
325 }
326 
dgram_write(BIO * b,const char * in,int inl)327 static int dgram_write(BIO *b, const char *in, int inl)
328 {
329     int ret;
330     bio_dgram_data *data = (bio_dgram_data *)b->ptr;
331     clear_socket_error();
332 
333     if (data->connected)
334         ret = writesocket(b->num, in, inl);
335     else {
336         int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
337 
338         ret = sendto(b->num, in, inl, 0,
339                      BIO_ADDR_sockaddr(&data->peer), peerlen);
340     }
341 
342     BIO_clear_retry_flags(b);
343     if (ret <= 0) {
344         if (BIO_dgram_should_retry(ret)) {
345             BIO_set_retry_write(b);
346             data->_errno = get_last_socket_error();
347         }
348     }
349     return ret;
350 }
351 
dgram_get_mtu_overhead(bio_dgram_data * data)352 static long dgram_get_mtu_overhead(bio_dgram_data *data)
353 {
354     long ret;
355 
356     switch (BIO_ADDR_family(&data->peer)) {
357     case AF_INET:
358         /*
359          * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
360          */
361         ret = 28;
362         break;
363 # if OPENSSL_USE_IPV6
364     case AF_INET6:
365         {
366 #  ifdef IN6_IS_ADDR_V4MAPPED
367             struct in6_addr tmp_addr;
368             if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
369                 && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
370                 /*
371                  * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
372                  */
373                 ret = 28;
374             else
375 #  endif
376             /*
377              * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
378              */
379             ret = 48;
380         }
381         break;
382 # endif
383     default:
384         /* We don't know. Go with the historical default */
385         ret = 28;
386         break;
387     }
388     return ret;
389 }
390 
dgram_ctrl(BIO * b,int cmd,long num,void * ptr)391 static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
392 {
393     long ret = 1;
394     int *ip;
395     bio_dgram_data *data = NULL;
396     int sockopt_val = 0;
397     int d_errno;
398 # if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
399     socklen_t sockopt_len;      /* assume that system supporting IP_MTU is
400                                  * modern enough to define socklen_t */
401     socklen_t addr_len;
402     BIO_ADDR addr;
403 # endif
404 
405     data = (bio_dgram_data *)b->ptr;
406 
407     switch (cmd) {
408     case BIO_CTRL_RESET:
409         num = 0;
410         ret = 0;
411         break;
412     case BIO_CTRL_INFO:
413         ret = 0;
414         break;
415     case BIO_C_SET_FD:
416         dgram_clear(b);
417         b->num = *((int *)ptr);
418         b->shutdown = (int)num;
419         b->init = 1;
420         break;
421     case BIO_C_GET_FD:
422         if (b->init) {
423             ip = (int *)ptr;
424             if (ip != NULL)
425                 *ip = b->num;
426             ret = b->num;
427         } else
428             ret = -1;
429         break;
430     case BIO_CTRL_GET_CLOSE:
431         ret = b->shutdown;
432         break;
433     case BIO_CTRL_SET_CLOSE:
434         b->shutdown = (int)num;
435         break;
436     case BIO_CTRL_PENDING:
437     case BIO_CTRL_WPENDING:
438         ret = 0;
439         break;
440     case BIO_CTRL_DUP:
441     case BIO_CTRL_FLUSH:
442         ret = 1;
443         break;
444     case BIO_CTRL_DGRAM_CONNECT:
445         BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
446         break;
447         /* (Linux)kernel sets DF bit on outgoing IP packets */
448     case BIO_CTRL_DGRAM_MTU_DISCOVER:
449 # if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
450         addr_len = (socklen_t) sizeof(addr);
451         memset(&addr, 0, sizeof(addr));
452         if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
453             ret = 0;
454             break;
455         }
456         switch (addr.sa.sa_family) {
457         case AF_INET:
458             sockopt_val = IP_PMTUDISC_DO;
459             if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
460                                   &sockopt_val, sizeof(sockopt_val))) < 0)
461                 perror("setsockopt");
462             break;
463 #  if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
464         case AF_INET6:
465             sockopt_val = IPV6_PMTUDISC_DO;
466             if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
467                                   &sockopt_val, sizeof(sockopt_val))) < 0)
468                 perror("setsockopt");
469             break;
470 #  endif
471         default:
472             ret = -1;
473             break;
474         }
475 # else
476         ret = -1;
477 # endif
478         break;
479     case BIO_CTRL_DGRAM_QUERY_MTU:
480 # if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
481         addr_len = (socklen_t) sizeof(addr);
482         memset(&addr, 0, sizeof(addr));
483         if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
484             ret = 0;
485             break;
486         }
487         sockopt_len = sizeof(sockopt_val);
488         switch (addr.sa.sa_family) {
489         case AF_INET:
490             if ((ret =
491                  getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
492                             &sockopt_len)) < 0 || sockopt_val < 0) {
493                 ret = 0;
494             } else {
495                 /*
496                  * we assume that the transport protocol is UDP and no IP
497                  * options are used.
498                  */
499                 data->mtu = sockopt_val - 8 - 20;
500                 ret = data->mtu;
501             }
502             break;
503 #  if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
504         case AF_INET6:
505             if ((ret =
506                  getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
507                             (void *)&sockopt_val, &sockopt_len)) < 0
508                 || sockopt_val < 0) {
509                 ret = 0;
510             } else {
511                 /*
512                  * we assume that the transport protocol is UDP and no IPV6
513                  * options are used.
514                  */
515                 data->mtu = sockopt_val - 8 - 40;
516                 ret = data->mtu;
517             }
518             break;
519 #  endif
520         default:
521             ret = 0;
522             break;
523         }
524 # else
525         ret = 0;
526 # endif
527         break;
528     case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
529         ret = -dgram_get_mtu_overhead(data);
530         switch (BIO_ADDR_family(&data->peer)) {
531         case AF_INET:
532             ret += 576;
533             break;
534 # if OPENSSL_USE_IPV6
535         case AF_INET6:
536             {
537 #  ifdef IN6_IS_ADDR_V4MAPPED
538                 struct in6_addr tmp_addr;
539                 if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
540                     && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
541                     ret += 576;
542                 else
543 #  endif
544                     ret += 1280;
545             }
546             break;
547 # endif
548         default:
549             ret += 576;
550             break;
551         }
552         break;
553     case BIO_CTRL_DGRAM_GET_MTU:
554         return data->mtu;
555     case BIO_CTRL_DGRAM_SET_MTU:
556         data->mtu = num;
557         ret = num;
558         break;
559     case BIO_CTRL_DGRAM_SET_CONNECTED:
560         if (ptr != NULL) {
561             data->connected = 1;
562             BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
563         } else {
564             data->connected = 0;
565             memset(&data->peer, 0, sizeof(data->peer));
566         }
567         break;
568     case BIO_CTRL_DGRAM_GET_PEER:
569         ret = BIO_ADDR_sockaddr_size(&data->peer);
570         /* FIXME: if num < ret, we will only return part of an address.
571            That should bee an error, no? */
572         if (num == 0 || num > ret)
573             num = ret;
574         memcpy(ptr, &data->peer, (ret = num));
575         break;
576     case BIO_CTRL_DGRAM_SET_PEER:
577         BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
578         break;
579     case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
580         memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
581         break;
582 # if defined(SO_RCVTIMEO)
583     case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
584 #  ifdef OPENSSL_SYS_WINDOWS
585         {
586             struct timeval *tv = (struct timeval *)ptr;
587             int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
588             if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
589                            (void *)&timeout, sizeof(timeout)) < 0) {
590                 perror("setsockopt");
591                 ret = -1;
592             }
593         }
594 #  else
595         if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
596                        sizeof(struct timeval)) < 0) {
597             perror("setsockopt");
598             ret = -1;
599         }
600 #  endif
601         break;
602     case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
603         {
604 #  ifdef OPENSSL_SYS_WINDOWS
605             int sz = 0;
606             int timeout;
607             struct timeval *tv = (struct timeval *)ptr;
608 
609             sz = sizeof(timeout);
610             if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
611                            (void *)&timeout, &sz) < 0) {
612                 perror("getsockopt");
613                 ret = -1;
614             } else {
615                 tv->tv_sec = timeout / 1000;
616                 tv->tv_usec = (timeout % 1000) * 1000;
617                 ret = sizeof(*tv);
618             }
619 #  else
620             socklen_t sz = sizeof(struct timeval);
621             if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
622                            ptr, &sz) < 0) {
623                 perror("getsockopt");
624                 ret = -1;
625             } else {
626                 OPENSSL_assert(sz <= sizeof(struct timeval));
627                 ret = (int)sz;
628             }
629 #  endif
630         }
631         break;
632 # endif
633 # if defined(SO_SNDTIMEO)
634     case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
635 #  ifdef OPENSSL_SYS_WINDOWS
636         {
637             struct timeval *tv = (struct timeval *)ptr;
638             int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
639             if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
640                            (void *)&timeout, sizeof(timeout)) < 0) {
641                 perror("setsockopt");
642                 ret = -1;
643             }
644         }
645 #  else
646         if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
647                        sizeof(struct timeval)) < 0) {
648             perror("setsockopt");
649             ret = -1;
650         }
651 #  endif
652         break;
653     case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
654         {
655 #  ifdef OPENSSL_SYS_WINDOWS
656             int sz = 0;
657             int timeout;
658             struct timeval *tv = (struct timeval *)ptr;
659 
660             sz = sizeof(timeout);
661             if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
662                            (void *)&timeout, &sz) < 0) {
663                 perror("getsockopt");
664                 ret = -1;
665             } else {
666                 tv->tv_sec = timeout / 1000;
667                 tv->tv_usec = (timeout % 1000) * 1000;
668                 ret = sizeof(*tv);
669             }
670 #  else
671             socklen_t sz = sizeof(struct timeval);
672             if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
673                            ptr, &sz) < 0) {
674                 perror("getsockopt");
675                 ret = -1;
676             } else {
677                 OPENSSL_assert(sz <= sizeof(struct timeval));
678                 ret = (int)sz;
679             }
680 #  endif
681         }
682         break;
683 # endif
684     case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
685         /* fall-through */
686     case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
687 # ifdef OPENSSL_SYS_WINDOWS
688         d_errno = (data->_errno == WSAETIMEDOUT);
689 # else
690         d_errno = (data->_errno == EAGAIN);
691 # endif
692         if (d_errno) {
693             ret = 1;
694             data->_errno = 0;
695         } else
696             ret = 0;
697         break;
698 # ifdef EMSGSIZE
699     case BIO_CTRL_DGRAM_MTU_EXCEEDED:
700         if (data->_errno == EMSGSIZE) {
701             ret = 1;
702             data->_errno = 0;
703         } else
704             ret = 0;
705         break;
706 # endif
707     case BIO_CTRL_DGRAM_SET_DONT_FRAG:
708         sockopt_val = num ? 1 : 0;
709 
710         switch (data->peer.sa.sa_family) {
711         case AF_INET:
712 # if defined(IP_DONTFRAG)
713             if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
714                                   &sockopt_val, sizeof(sockopt_val))) < 0) {
715                 perror("setsockopt");
716                 ret = -1;
717             }
718 # elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
719             if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
720                 (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
721                                   &sockopt_val, sizeof(sockopt_val))) < 0) {
722                 perror("setsockopt");
723                 ret = -1;
724             }
725 # elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
726             if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
727                                   (const char *)&sockopt_val,
728                                   sizeof(sockopt_val))) < 0) {
729                 perror("setsockopt");
730                 ret = -1;
731             }
732 # else
733             ret = -1;
734 # endif
735             break;
736 # if OPENSSL_USE_IPV6
737         case AF_INET6:
738 #  if defined(IPV6_DONTFRAG)
739             if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
740                                   (const void *)&sockopt_val,
741                                   sizeof(sockopt_val))) < 0) {
742                 perror("setsockopt");
743                 ret = -1;
744             }
745 #  elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
746             if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
747                 (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
748                                   &sockopt_val, sizeof(sockopt_val))) < 0) {
749                 perror("setsockopt");
750                 ret = -1;
751             }
752 #  else
753             ret = -1;
754 #  endif
755             break;
756 # endif
757         default:
758             ret = -1;
759             break;
760         }
761         break;
762     case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
763         ret = dgram_get_mtu_overhead(data);
764         break;
765 
766     /*
767      * BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE is used here for compatibility
768      * reasons. When BIO_CTRL_DGRAM_SET_PEEK_MODE was first defined its value
769      * was incorrectly clashing with BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE. The
770      * value has been updated to a non-clashing value. However to preserve
771      * binary compatibility we now respond to both the old value and the new one
772      */
773     case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
774     case BIO_CTRL_DGRAM_SET_PEEK_MODE:
775         data->peekmode = (unsigned int)num;
776         break;
777     default:
778         ret = 0;
779         break;
780     }
781     return ret;
782 }
783 
dgram_puts(BIO * bp,const char * str)784 static int dgram_puts(BIO *bp, const char *str)
785 {
786     int n, ret;
787 
788     n = strlen(str);
789     ret = dgram_write(bp, str, n);
790     return ret;
791 }
792 
793 # ifndef OPENSSL_NO_SCTP
BIO_s_datagram_sctp(void)794 const BIO_METHOD *BIO_s_datagram_sctp(void)
795 {
796     return &methods_dgramp_sctp;
797 }
798 
BIO_new_dgram_sctp(int fd,int close_flag)799 BIO *BIO_new_dgram_sctp(int fd, int close_flag)
800 {
801     BIO *bio;
802     int ret, optval = 20000;
803     int auth_data = 0, auth_forward = 0;
804     unsigned char *p;
805     struct sctp_authchunk auth;
806     struct sctp_authchunks *authchunks;
807     socklen_t sockopt_len;
808 #  ifdef SCTP_AUTHENTICATION_EVENT
809 #   ifdef SCTP_EVENT
810     struct sctp_event event;
811 #   else
812     struct sctp_event_subscribe event;
813 #   endif
814 #  endif
815 
816     bio = BIO_new(BIO_s_datagram_sctp());
817     if (bio == NULL)
818         return NULL;
819     BIO_set_fd(bio, fd, close_flag);
820 
821     /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
822     auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
823     ret =
824         setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
825                    sizeof(struct sctp_authchunk));
826     if (ret < 0) {
827         BIO_vfree(bio);
828         ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
829                        "Ensure SCTP AUTH chunks are enabled in kernel");
830         return NULL;
831     }
832     auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
833     ret =
834         setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
835                    sizeof(struct sctp_authchunk));
836     if (ret < 0) {
837         BIO_vfree(bio);
838         ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
839                        "Ensure SCTP AUTH chunks are enabled in kernel");
840         return NULL;
841     }
842 
843     /*
844      * Test if activation was successful. When using accept(), SCTP-AUTH has
845      * to be activated for the listening socket already, otherwise the
846      * connected socket won't use it. Similarly with connect(): the socket
847      * prior to connection must be activated for SCTP-AUTH
848      */
849     sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
850     authchunks = OPENSSL_zalloc(sockopt_len);
851     if (authchunks == NULL) {
852         BIO_vfree(bio);
853         return NULL;
854     }
855     ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
856                    &sockopt_len);
857     if (ret < 0) {
858         OPENSSL_free(authchunks);
859         BIO_vfree(bio);
860         return NULL;
861     }
862 
863     for (p = (unsigned char *)authchunks->gauth_chunks;
864          p < (unsigned char *)authchunks + sockopt_len;
865          p += sizeof(uint8_t)) {
866         if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
867             auth_data = 1;
868         if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
869             auth_forward = 1;
870     }
871 
872     OPENSSL_free(authchunks);
873 
874     if (!auth_data || !auth_forward) {
875         BIO_vfree(bio);
876         ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
877                        "Ensure SCTP AUTH chunks are enabled on the "
878                        "underlying socket");
879         return NULL;
880     }
881 
882 #  ifdef SCTP_AUTHENTICATION_EVENT
883 #   ifdef SCTP_EVENT
884     memset(&event, 0, sizeof(event));
885     event.se_assoc_id = 0;
886     event.se_type = SCTP_AUTHENTICATION_EVENT;
887     event.se_on = 1;
888     ret =
889         setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
890                    sizeof(struct sctp_event));
891     if (ret < 0) {
892         BIO_vfree(bio);
893         return NULL;
894     }
895 #   else
896     sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
897     ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
898     if (ret < 0) {
899         BIO_vfree(bio);
900         return NULL;
901     }
902 
903     event.sctp_authentication_event = 1;
904 
905     ret =
906         setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
907                    sizeof(struct sctp_event_subscribe));
908     if (ret < 0) {
909         BIO_vfree(bio);
910         return NULL;
911     }
912 #   endif
913 #  endif
914 
915     /*
916      * Disable partial delivery by setting the min size larger than the max
917      * record size of 2^14 + 2048 + 13
918      */
919     ret =
920         setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
921                    sizeof(optval));
922     if (ret < 0) {
923         BIO_vfree(bio);
924         return NULL;
925     }
926 
927     return bio;
928 }
929 
BIO_dgram_is_sctp(BIO * bio)930 int BIO_dgram_is_sctp(BIO *bio)
931 {
932     return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
933 }
934 
dgram_sctp_new(BIO * bi)935 static int dgram_sctp_new(BIO *bi)
936 {
937     bio_dgram_sctp_data *data = NULL;
938 
939     bi->init = 0;
940     bi->num = 0;
941     if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) {
942         ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
943         return 0;
944     }
945 #  ifdef SCTP_PR_SCTP_NONE
946     data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
947 #  endif
948     bi->ptr = data;
949 
950     bi->flags = 0;
951     return 1;
952 }
953 
dgram_sctp_free(BIO * a)954 static int dgram_sctp_free(BIO *a)
955 {
956     bio_dgram_sctp_data *data;
957 
958     if (a == NULL)
959         return 0;
960     if (!dgram_clear(a))
961         return 0;
962 
963     data = (bio_dgram_sctp_data *) a->ptr;
964     if (data != NULL)
965         OPENSSL_free(data);
966 
967     return 1;
968 }
969 
970 #  ifdef SCTP_AUTHENTICATION_EVENT
dgram_sctp_handle_auth_free_key_event(BIO * b,union sctp_notification * snp)971 void dgram_sctp_handle_auth_free_key_event(BIO *b,
972                                            union sctp_notification *snp)
973 {
974     int ret;
975     struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
976 
977     if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
978         struct sctp_authkeyid authkeyid;
979 
980         /* delete key */
981         authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
982         ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
983                          &authkeyid, sizeof(struct sctp_authkeyid));
984     }
985 }
986 #  endif
987 
dgram_sctp_read(BIO * b,char * out,int outl)988 static int dgram_sctp_read(BIO *b, char *out, int outl)
989 {
990     int ret = 0, n = 0, i, optval;
991     socklen_t optlen;
992     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
993     struct msghdr msg;
994     struct iovec iov;
995     struct cmsghdr *cmsg;
996     char cmsgbuf[512];
997 
998     if (out != NULL) {
999         clear_socket_error();
1000 
1001         do {
1002             memset(&data->rcvinfo, 0, sizeof(data->rcvinfo));
1003             iov.iov_base = out;
1004             iov.iov_len = outl;
1005             msg.msg_name = NULL;
1006             msg.msg_namelen = 0;
1007             msg.msg_iov = &iov;
1008             msg.msg_iovlen = 1;
1009             msg.msg_control = cmsgbuf;
1010             msg.msg_controllen = 512;
1011             msg.msg_flags = 0;
1012             n = recvmsg(b->num, &msg, 0);
1013 
1014             if (n <= 0) {
1015                 if (n < 0)
1016                     ret = n;
1017                 break;
1018             }
1019 
1020             if (msg.msg_controllen > 0) {
1021                 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
1022                      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1023                     if (cmsg->cmsg_level != IPPROTO_SCTP)
1024                         continue;
1025 #  ifdef SCTP_RCVINFO
1026                     if (cmsg->cmsg_type == SCTP_RCVINFO) {
1027                         struct sctp_rcvinfo *rcvinfo;
1028 
1029                         rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
1030                         data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
1031                         data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
1032                         data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
1033                         data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
1034                         data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
1035                         data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
1036                         data->rcvinfo.rcv_context = rcvinfo->rcv_context;
1037                     }
1038 #  endif
1039 #  ifdef SCTP_SNDRCV
1040                     if (cmsg->cmsg_type == SCTP_SNDRCV) {
1041                         struct sctp_sndrcvinfo *sndrcvinfo;
1042 
1043                         sndrcvinfo =
1044                             (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1045                         data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
1046                         data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
1047                         data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
1048                         data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
1049                         data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
1050                         data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
1051                         data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
1052                     }
1053 #  endif
1054                 }
1055             }
1056 
1057             if (msg.msg_flags & MSG_NOTIFICATION) {
1058                 union sctp_notification snp;
1059 
1060                 memcpy(&snp, out, sizeof(snp));
1061                 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
1062 #  ifdef SCTP_EVENT
1063                     struct sctp_event event;
1064 #  else
1065                     struct sctp_event_subscribe event;
1066                     socklen_t eventsize;
1067 #  endif
1068 
1069                     /* disable sender dry event */
1070 #  ifdef SCTP_EVENT
1071                     memset(&event, 0, sizeof(event));
1072                     event.se_assoc_id = 0;
1073                     event.se_type = SCTP_SENDER_DRY_EVENT;
1074                     event.se_on = 0;
1075                     i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1076                                    sizeof(struct sctp_event));
1077                     if (i < 0) {
1078                         ret = i;
1079                         break;
1080                     }
1081 #  else
1082                     eventsize = sizeof(struct sctp_event_subscribe);
1083                     i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1084                                    &eventsize);
1085                     if (i < 0) {
1086                         ret = i;
1087                         break;
1088                     }
1089 
1090                     event.sctp_sender_dry_event = 0;
1091 
1092                     i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1093                                    sizeof(struct sctp_event_subscribe));
1094                     if (i < 0) {
1095                         ret = i;
1096                         break;
1097                     }
1098 #  endif
1099                 }
1100 #  ifdef SCTP_AUTHENTICATION_EVENT
1101                 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1102                     dgram_sctp_handle_auth_free_key_event(b, &snp);
1103 #  endif
1104 
1105                 if (data->handle_notifications != NULL)
1106                     data->handle_notifications(b, data->notification_context,
1107                                                (void *)out);
1108 
1109                 memset(&snp, 0, sizeof(snp));
1110                 memset(out, 0, outl);
1111             } else {
1112                 ret += n;
1113             }
1114         }
1115         while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
1116                && (ret < outl));
1117 
1118         if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
1119             /* Partial message read, this should never happen! */
1120 
1121             /*
1122              * The buffer was too small, this means the peer sent a message
1123              * that was larger than allowed.
1124              */
1125             if (ret == outl)
1126                 return -1;
1127 
1128             /*
1129              * Test if socket buffer can handle max record size (2^14 + 2048
1130              * + 13)
1131              */
1132             optlen = (socklen_t) sizeof(int);
1133             ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
1134             if (ret >= 0)
1135                 OPENSSL_assert(optval >= 18445);
1136 
1137             /*
1138              * Test if SCTP doesn't partially deliver below max record size
1139              * (2^14 + 2048 + 13)
1140              */
1141             optlen = (socklen_t) sizeof(int);
1142             ret =
1143                 getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
1144                            &optval, &optlen);
1145             if (ret >= 0)
1146                 OPENSSL_assert(optval >= 18445);
1147 
1148             /*
1149              * Partially delivered notification??? Probably a bug....
1150              */
1151             OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
1152 
1153             /*
1154              * Everything seems ok till now, so it's most likely a message
1155              * dropped by PR-SCTP.
1156              */
1157             memset(out, 0, outl);
1158             BIO_set_retry_read(b);
1159             return -1;
1160         }
1161 
1162         BIO_clear_retry_flags(b);
1163         if (ret < 0) {
1164             if (BIO_dgram_should_retry(ret)) {
1165                 BIO_set_retry_read(b);
1166                 data->_errno = get_last_socket_error();
1167             }
1168         }
1169 
1170         /* Test if peer uses SCTP-AUTH before continuing */
1171         if (!data->peer_auth_tested) {
1172             int ii, auth_data = 0, auth_forward = 0;
1173             unsigned char *p;
1174             struct sctp_authchunks *authchunks;
1175 
1176             optlen =
1177                 (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
1178             authchunks = OPENSSL_malloc(optlen);
1179             if (authchunks == NULL) {
1180                 ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
1181                 return -1;
1182             }
1183             memset(authchunks, 0, optlen);
1184             ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS,
1185                             authchunks, &optlen);
1186 
1187             if (ii >= 0)
1188                 for (p = (unsigned char *)authchunks->gauth_chunks;
1189                      p < (unsigned char *)authchunks + optlen;
1190                      p += sizeof(uint8_t)) {
1191                     if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
1192                         auth_data = 1;
1193                     if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
1194                         auth_forward = 1;
1195                 }
1196 
1197             OPENSSL_free(authchunks);
1198 
1199             if (!auth_data || !auth_forward) {
1200                 ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
1201                 return -1;
1202             }
1203 
1204             data->peer_auth_tested = 1;
1205         }
1206     }
1207     return ret;
1208 }
1209 
1210 /*
1211  * dgram_sctp_write - send message on SCTP socket
1212  * @b: BIO to write to
1213  * @in: data to send
1214  * @inl: amount of bytes in @in to send
1215  *
1216  * Returns -1 on error or the sent amount of bytes on success
1217  */
dgram_sctp_write(BIO * b,const char * in,int inl)1218 static int dgram_sctp_write(BIO *b, const char *in, int inl)
1219 {
1220     int ret;
1221     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1222     struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
1223     struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
1224     struct bio_dgram_sctp_sndinfo handshake_sinfo;
1225     struct iovec iov[1];
1226     struct msghdr msg;
1227     struct cmsghdr *cmsg;
1228 #  if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1229     char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
1230                  CMSG_SPACE(sizeof(struct sctp_prinfo))];
1231     struct sctp_sndinfo *sndinfo;
1232     struct sctp_prinfo *prinfo;
1233 #  else
1234     char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
1235     struct sctp_sndrcvinfo *sndrcvinfo;
1236 #  endif
1237 
1238     clear_socket_error();
1239 
1240     /*
1241      * If we're send anything else than application data, disable all user
1242      * parameters and flags.
1243      */
1244     if (in[0] != 23) {
1245         memset(&handshake_sinfo, 0, sizeof(handshake_sinfo));
1246 #  ifdef SCTP_SACK_IMMEDIATELY
1247         handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
1248 #  endif
1249         sinfo = &handshake_sinfo;
1250     }
1251 
1252     /* We can only send a shutdown alert if the socket is dry */
1253     if (data->save_shutdown) {
1254         ret = BIO_dgram_sctp_wait_for_dry(b);
1255         if (ret < 0)
1256             return -1;
1257         if (ret == 0) {
1258             BIO_clear_retry_flags(b);
1259             BIO_set_retry_write(b);
1260             return -1;
1261         }
1262     }
1263 
1264     iov[0].iov_base = (char *)in;
1265     iov[0].iov_len = inl;
1266     msg.msg_name = NULL;
1267     msg.msg_namelen = 0;
1268     msg.msg_iov = iov;
1269     msg.msg_iovlen = 1;
1270     msg.msg_control = (caddr_t) cmsgbuf;
1271     msg.msg_controllen = 0;
1272     msg.msg_flags = 0;
1273 #  if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1274     cmsg = (struct cmsghdr *)cmsgbuf;
1275     cmsg->cmsg_level = IPPROTO_SCTP;
1276     cmsg->cmsg_type = SCTP_SNDINFO;
1277     cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
1278     sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
1279     memset(sndinfo, 0, sizeof(*sndinfo));
1280     sndinfo->snd_sid = sinfo->snd_sid;
1281     sndinfo->snd_flags = sinfo->snd_flags;
1282     sndinfo->snd_ppid = sinfo->snd_ppid;
1283     sndinfo->snd_context = sinfo->snd_context;
1284     msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
1285 
1286     cmsg =
1287         (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
1288     cmsg->cmsg_level = IPPROTO_SCTP;
1289     cmsg->cmsg_type = SCTP_PRINFO;
1290     cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
1291     prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
1292     memset(prinfo, 0, sizeof(*prinfo));
1293     prinfo->pr_policy = pinfo->pr_policy;
1294     prinfo->pr_value = pinfo->pr_value;
1295     msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
1296 #  else
1297     cmsg = (struct cmsghdr *)cmsgbuf;
1298     cmsg->cmsg_level = IPPROTO_SCTP;
1299     cmsg->cmsg_type = SCTP_SNDRCV;
1300     cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
1301     sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1302     memset(sndrcvinfo, 0, sizeof(*sndrcvinfo));
1303     sndrcvinfo->sinfo_stream = sinfo->snd_sid;
1304     sndrcvinfo->sinfo_flags = sinfo->snd_flags;
1305 #   ifdef __FreeBSD__
1306     sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
1307 #   endif
1308     sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
1309     sndrcvinfo->sinfo_context = sinfo->snd_context;
1310     sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
1311     msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
1312 #  endif
1313 
1314     ret = sendmsg(b->num, &msg, 0);
1315 
1316     BIO_clear_retry_flags(b);
1317     if (ret <= 0) {
1318         if (BIO_dgram_should_retry(ret)) {
1319             BIO_set_retry_write(b);
1320             data->_errno = get_last_socket_error();
1321         }
1322     }
1323     return ret;
1324 }
1325 
dgram_sctp_ctrl(BIO * b,int cmd,long num,void * ptr)1326 static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1327 {
1328     long ret = 1;
1329     bio_dgram_sctp_data *data = NULL;
1330     socklen_t sockopt_len = 0;
1331     struct sctp_authkeyid authkeyid;
1332     struct sctp_authkey *authkey = NULL;
1333 
1334     data = (bio_dgram_sctp_data *) b->ptr;
1335 
1336     switch (cmd) {
1337     case BIO_CTRL_DGRAM_QUERY_MTU:
1338         /*
1339          * Set to maximum (2^14) and ignore user input to enable transport
1340          * protocol fragmentation. Returns always 2^14.
1341          */
1342         data->mtu = 16384;
1343         ret = data->mtu;
1344         break;
1345     case BIO_CTRL_DGRAM_SET_MTU:
1346         /*
1347          * Set to maximum (2^14) and ignore input to enable transport
1348          * protocol fragmentation. Returns always 2^14.
1349          */
1350         data->mtu = 16384;
1351         ret = data->mtu;
1352         break;
1353     case BIO_CTRL_DGRAM_SET_CONNECTED:
1354     case BIO_CTRL_DGRAM_CONNECT:
1355         /* Returns always -1. */
1356         ret = -1;
1357         break;
1358     case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
1359         /*
1360          * SCTP doesn't need the DTLS timer Returns always 1.
1361          */
1362         break;
1363     case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
1364         /*
1365          * We allow transport protocol fragmentation so this is irrelevant
1366          */
1367         ret = 0;
1368         break;
1369     case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
1370         if (num > 0)
1371             data->in_handshake = 1;
1372         else
1373             data->in_handshake = 0;
1374 
1375         ret =
1376             setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY,
1377                        &data->in_handshake, sizeof(int));
1378         break;
1379     case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
1380         /*
1381          * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise.
1382          */
1383 
1384         /* Get active key */
1385         sockopt_len = sizeof(struct sctp_authkeyid);
1386         ret =
1387             getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
1388                        &sockopt_len);
1389         if (ret < 0)
1390             break;
1391 
1392         /* Add new key */
1393         sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
1394         authkey = OPENSSL_malloc(sockopt_len);
1395         if (authkey == NULL) {
1396             ret = -1;
1397             break;
1398         }
1399         memset(authkey, 0, sockopt_len);
1400         authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
1401 #  ifndef __FreeBSD__
1402         /*
1403          * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3
1404          * and higher work without it.
1405          */
1406         authkey->sca_keylength = 64;
1407 #  endif
1408         memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
1409 
1410         ret =
1411             setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey,
1412                        sockopt_len);
1413         OPENSSL_free(authkey);
1414         authkey = NULL;
1415         if (ret < 0)
1416             break;
1417 
1418         /* Reset active key */
1419         ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1420                          &authkeyid, sizeof(struct sctp_authkeyid));
1421         if (ret < 0)
1422             break;
1423 
1424         break;
1425     case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
1426         /* Returns 0 on success, -1 otherwise. */
1427 
1428         /* Get active key */
1429         sockopt_len = sizeof(struct sctp_authkeyid);
1430         ret =
1431             getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
1432                        &sockopt_len);
1433         if (ret < 0)
1434             break;
1435 
1436         /* Set active key */
1437         authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
1438         ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1439                          &authkeyid, sizeof(struct sctp_authkeyid));
1440         if (ret < 0)
1441             break;
1442 
1443         /*
1444          * CCS has been sent, so remember that and fall through to check if
1445          * we need to deactivate an old key
1446          */
1447         data->ccs_sent = 1;
1448         /* fall-through */
1449 
1450     case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
1451         /* Returns 0 on success, -1 otherwise. */
1452 
1453         /*
1454          * Has this command really been called or is this just a
1455          * fall-through?
1456          */
1457         if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
1458             data->ccs_rcvd = 1;
1459 
1460         /*
1461          * CSS has been both, received and sent, so deactivate an old key
1462          */
1463         if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
1464             /* Get active key */
1465             sockopt_len = sizeof(struct sctp_authkeyid);
1466             ret =
1467                 getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1468                            &authkeyid, &sockopt_len);
1469             if (ret < 0)
1470                 break;
1471 
1472             /*
1473              * Deactivate key or delete second last key if
1474              * SCTP_AUTHENTICATION_EVENT is not available.
1475              */
1476             authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1477 #  ifdef SCTP_AUTH_DEACTIVATE_KEY
1478             sockopt_len = sizeof(struct sctp_authkeyid);
1479             ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
1480                              &authkeyid, sockopt_len);
1481             if (ret < 0)
1482                 break;
1483 #  endif
1484 #  ifndef SCTP_AUTHENTICATION_EVENT
1485             if (authkeyid.scact_keynumber > 0) {
1486                 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1487                 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1488                                  &authkeyid, sizeof(struct sctp_authkeyid));
1489                 if (ret < 0)
1490                     break;
1491             }
1492 #  endif
1493 
1494             data->ccs_rcvd = 0;
1495             data->ccs_sent = 0;
1496         }
1497         break;
1498     case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
1499         /* Returns the size of the copied struct. */
1500         if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
1501             num = sizeof(struct bio_dgram_sctp_sndinfo);
1502 
1503         memcpy(ptr, &(data->sndinfo), num);
1504         ret = num;
1505         break;
1506     case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
1507         /* Returns the size of the copied struct. */
1508         if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
1509             num = sizeof(struct bio_dgram_sctp_sndinfo);
1510 
1511         memcpy(&(data->sndinfo), ptr, num);
1512         break;
1513     case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
1514         /* Returns the size of the copied struct. */
1515         if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
1516             num = sizeof(struct bio_dgram_sctp_rcvinfo);
1517 
1518         memcpy(ptr, &data->rcvinfo, num);
1519 
1520         ret = num;
1521         break;
1522     case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
1523         /* Returns the size of the copied struct. */
1524         if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
1525             num = sizeof(struct bio_dgram_sctp_rcvinfo);
1526 
1527         memcpy(&(data->rcvinfo), ptr, num);
1528         break;
1529     case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
1530         /* Returns the size of the copied struct. */
1531         if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
1532             num = sizeof(struct bio_dgram_sctp_prinfo);
1533 
1534         memcpy(ptr, &(data->prinfo), num);
1535         ret = num;
1536         break;
1537     case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
1538         /* Returns the size of the copied struct. */
1539         if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
1540             num = sizeof(struct bio_dgram_sctp_prinfo);
1541 
1542         memcpy(&(data->prinfo), ptr, num);
1543         break;
1544     case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
1545         /* Returns always 1. */
1546         if (num > 0)
1547             data->save_shutdown = 1;
1548         else
1549             data->save_shutdown = 0;
1550         break;
1551     case BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY:
1552         return dgram_sctp_wait_for_dry(b);
1553     case BIO_CTRL_DGRAM_SCTP_MSG_WAITING:
1554         return dgram_sctp_msg_waiting(b);
1555 
1556     default:
1557         /*
1558          * Pass to default ctrl function to process SCTP unspecific commands
1559          */
1560         ret = dgram_ctrl(b, cmd, num, ptr);
1561         break;
1562     }
1563     return ret;
1564 }
1565 
BIO_dgram_sctp_notification_cb(BIO * b,BIO_dgram_sctp_notification_handler_fn handle_notifications,void * context)1566 int BIO_dgram_sctp_notification_cb(BIO *b,
1567                 BIO_dgram_sctp_notification_handler_fn handle_notifications,
1568                 void *context)
1569 {
1570     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1571 
1572     if (handle_notifications != NULL) {
1573         data->handle_notifications = handle_notifications;
1574         data->notification_context = context;
1575     } else
1576         return -1;
1577 
1578     return 0;
1579 }
1580 
1581 /*
1582  * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event
1583  * @b: The BIO to check for the dry event
1584  *
1585  * Wait until the peer confirms all packets have been received, and so that
1586  * our kernel doesn't have anything to send anymore.  This is only received by
1587  * the peer's kernel, not the application.
1588  *
1589  * Returns:
1590  * -1 on error
1591  *  0 when not dry yet
1592  *  1 when dry
1593  */
BIO_dgram_sctp_wait_for_dry(BIO * b)1594 int BIO_dgram_sctp_wait_for_dry(BIO *b)
1595 {
1596     return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY, 0, NULL);
1597 }
1598 
dgram_sctp_wait_for_dry(BIO * b)1599 static int dgram_sctp_wait_for_dry(BIO *b)
1600 {
1601     int is_dry = 0;
1602     int sockflags = 0;
1603     int n, ret;
1604     union sctp_notification snp;
1605     struct msghdr msg;
1606     struct iovec iov;
1607 #  ifdef SCTP_EVENT
1608     struct sctp_event event;
1609 #  else
1610     struct sctp_event_subscribe event;
1611     socklen_t eventsize;
1612 #  endif
1613     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1614 
1615     /* set sender dry event */
1616 #  ifdef SCTP_EVENT
1617     memset(&event, 0, sizeof(event));
1618     event.se_assoc_id = 0;
1619     event.se_type = SCTP_SENDER_DRY_EVENT;
1620     event.se_on = 1;
1621     ret =
1622         setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1623                    sizeof(struct sctp_event));
1624 #  else
1625     eventsize = sizeof(struct sctp_event_subscribe);
1626     ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1627     if (ret < 0)
1628         return -1;
1629 
1630     event.sctp_sender_dry_event = 1;
1631 
1632     ret =
1633         setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1634                    sizeof(struct sctp_event_subscribe));
1635 #  endif
1636     if (ret < 0)
1637         return -1;
1638 
1639     /* peek for notification */
1640     memset(&snp, 0, sizeof(snp));
1641     iov.iov_base = (char *)&snp;
1642     iov.iov_len = sizeof(union sctp_notification);
1643     msg.msg_name = NULL;
1644     msg.msg_namelen = 0;
1645     msg.msg_iov = &iov;
1646     msg.msg_iovlen = 1;
1647     msg.msg_control = NULL;
1648     msg.msg_controllen = 0;
1649     msg.msg_flags = 0;
1650 
1651     n = recvmsg(b->num, &msg, MSG_PEEK);
1652     if (n <= 0) {
1653         if ((n < 0) && (get_last_socket_error() != EAGAIN)
1654             && (get_last_socket_error() != EWOULDBLOCK))
1655             return -1;
1656         else
1657             return 0;
1658     }
1659 
1660     /* if we find a notification, process it and try again if necessary */
1661     while (msg.msg_flags & MSG_NOTIFICATION) {
1662         memset(&snp, 0, sizeof(snp));
1663         iov.iov_base = (char *)&snp;
1664         iov.iov_len = sizeof(union sctp_notification);
1665         msg.msg_name = NULL;
1666         msg.msg_namelen = 0;
1667         msg.msg_iov = &iov;
1668         msg.msg_iovlen = 1;
1669         msg.msg_control = NULL;
1670         msg.msg_controllen = 0;
1671         msg.msg_flags = 0;
1672 
1673         n = recvmsg(b->num, &msg, 0);
1674         if (n <= 0) {
1675             if ((n < 0) && (get_last_socket_error() != EAGAIN)
1676                 && (get_last_socket_error() != EWOULDBLOCK))
1677                 return -1;
1678             else
1679                 return is_dry;
1680         }
1681 
1682         if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
1683             is_dry = 1;
1684 
1685             /* disable sender dry event */
1686 #  ifdef SCTP_EVENT
1687             memset(&event, 0, sizeof(event));
1688             event.se_assoc_id = 0;
1689             event.se_type = SCTP_SENDER_DRY_EVENT;
1690             event.se_on = 0;
1691             ret =
1692                 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1693                            sizeof(struct sctp_event));
1694 #  else
1695             eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
1696             ret =
1697                 getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1698                            &eventsize);
1699             if (ret < 0)
1700                 return -1;
1701 
1702             event.sctp_sender_dry_event = 0;
1703 
1704             ret =
1705                 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1706                            sizeof(struct sctp_event_subscribe));
1707 #  endif
1708             if (ret < 0)
1709                 return -1;
1710         }
1711 #  ifdef SCTP_AUTHENTICATION_EVENT
1712         if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1713             dgram_sctp_handle_auth_free_key_event(b, &snp);
1714 #  endif
1715 
1716         if (data->handle_notifications != NULL)
1717             data->handle_notifications(b, data->notification_context,
1718                                        (void *)&snp);
1719 
1720         /* found notification, peek again */
1721         memset(&snp, 0, sizeof(snp));
1722         iov.iov_base = (char *)&snp;
1723         iov.iov_len = sizeof(union sctp_notification);
1724         msg.msg_name = NULL;
1725         msg.msg_namelen = 0;
1726         msg.msg_iov = &iov;
1727         msg.msg_iovlen = 1;
1728         msg.msg_control = NULL;
1729         msg.msg_controllen = 0;
1730         msg.msg_flags = 0;
1731 
1732         /* if we have seen the dry already, don't wait */
1733         if (is_dry) {
1734             sockflags = fcntl(b->num, F_GETFL, 0);
1735             fcntl(b->num, F_SETFL, O_NONBLOCK);
1736         }
1737 
1738         n = recvmsg(b->num, &msg, MSG_PEEK);
1739 
1740         if (is_dry) {
1741             fcntl(b->num, F_SETFL, sockflags);
1742         }
1743 
1744         if (n <= 0) {
1745             if ((n < 0) && (get_last_socket_error() != EAGAIN)
1746                 && (get_last_socket_error() != EWOULDBLOCK))
1747                 return -1;
1748             else
1749                 return is_dry;
1750         }
1751     }
1752 
1753     /* read anything else */
1754     return is_dry;
1755 }
1756 
BIO_dgram_sctp_msg_waiting(BIO * b)1757 int BIO_dgram_sctp_msg_waiting(BIO *b)
1758 {
1759     return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_MSG_WAITING, 0, NULL);
1760 }
1761 
dgram_sctp_msg_waiting(BIO * b)1762 static int dgram_sctp_msg_waiting(BIO *b)
1763 {
1764     int n, sockflags;
1765     union sctp_notification snp;
1766     struct msghdr msg;
1767     struct iovec iov;
1768     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1769 
1770     /* Check if there are any messages waiting to be read */
1771     do {
1772         memset(&snp, 0, sizeof(snp));
1773         iov.iov_base = (char *)&snp;
1774         iov.iov_len = sizeof(union sctp_notification);
1775         msg.msg_name = NULL;
1776         msg.msg_namelen = 0;
1777         msg.msg_iov = &iov;
1778         msg.msg_iovlen = 1;
1779         msg.msg_control = NULL;
1780         msg.msg_controllen = 0;
1781         msg.msg_flags = 0;
1782 
1783         sockflags = fcntl(b->num, F_GETFL, 0);
1784         fcntl(b->num, F_SETFL, O_NONBLOCK);
1785         n = recvmsg(b->num, &msg, MSG_PEEK);
1786         fcntl(b->num, F_SETFL, sockflags);
1787 
1788         /* if notification, process and try again */
1789         if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
1790 #  ifdef SCTP_AUTHENTICATION_EVENT
1791             if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1792                 dgram_sctp_handle_auth_free_key_event(b, &snp);
1793 #  endif
1794 
1795             memset(&snp, 0, sizeof(snp));
1796             iov.iov_base = (char *)&snp;
1797             iov.iov_len = sizeof(union sctp_notification);
1798             msg.msg_name = NULL;
1799             msg.msg_namelen = 0;
1800             msg.msg_iov = &iov;
1801             msg.msg_iovlen = 1;
1802             msg.msg_control = NULL;
1803             msg.msg_controllen = 0;
1804             msg.msg_flags = 0;
1805             n = recvmsg(b->num, &msg, 0);
1806 
1807             if (data->handle_notifications != NULL)
1808                 data->handle_notifications(b, data->notification_context,
1809                                            (void *)&snp);
1810         }
1811 
1812     } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
1813 
1814     /* Return 1 if there is a message to be read, return 0 otherwise. */
1815     if (n > 0)
1816         return 1;
1817     else
1818         return 0;
1819 }
1820 
dgram_sctp_puts(BIO * bp,const char * str)1821 static int dgram_sctp_puts(BIO *bp, const char *str)
1822 {
1823     int n, ret;
1824 
1825     n = strlen(str);
1826     ret = dgram_sctp_write(bp, str, n);
1827     return ret;
1828 }
1829 # endif
1830 
BIO_dgram_should_retry(int i)1831 static int BIO_dgram_should_retry(int i)
1832 {
1833     int err;
1834 
1835     if ((i == 0) || (i == -1)) {
1836         err = get_last_socket_error();
1837 
1838 # if defined(OPENSSL_SYS_WINDOWS)
1839         /*
1840          * If the socket return value (i) is -1 and err is unexpectedly 0 at
1841          * this point, the error code was overwritten by another system call
1842          * before this error handling is called.
1843          */
1844 # endif
1845 
1846         return BIO_dgram_non_fatal_error(err);
1847     }
1848     return 0;
1849 }
1850 
BIO_dgram_non_fatal_error(int err)1851 int BIO_dgram_non_fatal_error(int err)
1852 {
1853     switch (err) {
1854 # if defined(OPENSSL_SYS_WINDOWS)
1855 #  if defined(WSAEWOULDBLOCK)
1856     case WSAEWOULDBLOCK:
1857 #  endif
1858 # endif
1859 
1860 # ifdef EWOULDBLOCK
1861 #  ifdef WSAEWOULDBLOCK
1862 #   if WSAEWOULDBLOCK != EWOULDBLOCK
1863     case EWOULDBLOCK:
1864 #   endif
1865 #  else
1866     case EWOULDBLOCK:
1867 #  endif
1868 # endif
1869 
1870 # ifdef EINTR
1871     case EINTR:
1872 # endif
1873 
1874 # ifdef EAGAIN
1875 #  if EWOULDBLOCK != EAGAIN
1876     case EAGAIN:
1877 #  endif
1878 # endif
1879 
1880 # ifdef EPROTO
1881     case EPROTO:
1882 # endif
1883 
1884 # ifdef EINPROGRESS
1885     case EINPROGRESS:
1886 # endif
1887 
1888 # ifdef EALREADY
1889     case EALREADY:
1890 # endif
1891 
1892         return 1;
1893     default:
1894         break;
1895     }
1896     return 0;
1897 }
1898 
get_current_time(struct timeval * t)1899 static void get_current_time(struct timeval *t)
1900 {
1901 # if defined(_WIN32)
1902     SYSTEMTIME st;
1903     unsigned __int64 now_ul;
1904     FILETIME now_ft;
1905 
1906     GetSystemTime(&st);
1907     SystemTimeToFileTime(&st, &now_ft);
1908     now_ul = ((unsigned __int64)now_ft.dwHighDateTime << 32) | now_ft.dwLowDateTime;
1909 #  ifdef  __MINGW32__
1910     now_ul -= 116444736000000000ULL;
1911 #  else
1912     now_ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
1913 #  endif
1914     t->tv_sec = (long)(now_ul / 10000000);
1915     t->tv_usec = ((int)(now_ul % 10000000)) / 10;
1916 # else
1917     if (gettimeofday(t, NULL) < 0)
1918         perror("gettimeofday");
1919 # endif
1920 }
1921 
1922 #endif
1923