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