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