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