bio: remove TODOs
[openssl.git] / crypto / bio / bss_dgram.c
1 /*
2  * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #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 static int dgram_sctp_wait_for_dry(BIO *b);
57 static int dgram_sctp_msg_waiting(BIO *b);
58 #  ifdef SCTP_AUTHENTICATION_EVENT
59 static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
60                                                   *snp);
61 #  endif
62 # endif
63
64 static int BIO_dgram_should_retry(int s);
65
66 static void get_current_time(struct timeval *t);
67
68 static const BIO_METHOD methods_dgramp = {
69     BIO_TYPE_DGRAM,
70     "datagram socket",
71     bwrite_conv,
72     dgram_write,
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     bwrite_conv,
88     dgram_sctp_write,
89     bread_conv,
90     dgram_sctp_read,
91     dgram_sctp_puts,
92     NULL,                       /* dgram_gets,         */
93     dgram_sctp_ctrl,
94     dgram_sctp_new,
95     dgram_sctp_free,
96     NULL,                       /* dgram_callback_ctrl */
97 };
98 # endif
99
100 typedef struct bio_dgram_data_st {
101     BIO_ADDR peer;
102     unsigned int connected;
103     unsigned int _errno;
104     unsigned int mtu;
105     struct timeval next_timeout;
106     struct timeval socket_timeout;
107     unsigned int peekmode;
108 } bio_dgram_data;
109
110 # ifndef OPENSSL_NO_SCTP
111 typedef struct bio_dgram_sctp_save_message_st {
112     BIO *bio;
113     char *data;
114     int length;
115 } bio_dgram_sctp_save_message;
116
117 typedef struct bio_dgram_sctp_data_st {
118     BIO_ADDR peer;
119     unsigned int connected;
120     unsigned int _errno;
121     unsigned int mtu;
122     struct bio_dgram_sctp_sndinfo sndinfo;
123     struct bio_dgram_sctp_rcvinfo rcvinfo;
124     struct bio_dgram_sctp_prinfo prinfo;
125     BIO_dgram_sctp_notification_handler_fn handle_notifications;
126     void *notification_context;
127     int in_handshake;
128     int ccs_rcvd;
129     int ccs_sent;
130     int save_shutdown;
131     int peer_auth_tested;
132 } bio_dgram_sctp_data;
133 # endif
134
135 const BIO_METHOD *BIO_s_datagram(void)
136 {
137     return &methods_dgramp;
138 }
139
140 BIO *BIO_new_dgram(int fd, int close_flag)
141 {
142     BIO *ret;
143
144     ret = BIO_new(BIO_s_datagram());
145     if (ret == NULL)
146         return NULL;
147     BIO_set_fd(ret, fd, close_flag);
148     return ret;
149 }
150
151 static int dgram_new(BIO *bi)
152 {
153     bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
154
155     if (data == NULL)
156         return 0;
157     bi->ptr = data;
158     return 1;
159 }
160
161 static int dgram_free(BIO *a)
162 {
163     bio_dgram_data *data;
164
165     if (a == NULL)
166         return 0;
167     if (!dgram_clear(a))
168         return 0;
169
170     data = (bio_dgram_data *)a->ptr;
171     OPENSSL_free(data);
172
173     return 1;
174 }
175
176 static int dgram_clear(BIO *a)
177 {
178     if (a == NULL)
179         return 0;
180     if (a->shutdown) {
181         if (a->init) {
182             BIO_closesocket(a->num);
183         }
184         a->init = 0;
185         a->flags = 0;
186     }
187     return 1;
188 }
189
190 static void dgram_adjust_rcv_timeout(BIO *b)
191 {
192 # if defined(SO_RCVTIMEO)
193     bio_dgram_data *data = (bio_dgram_data *)b->ptr;
194     union {
195         size_t s;
196         int i;
197     } sz = {
198         0
199     };
200
201     /* Is a timer active? */
202     if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
203         struct timeval timenow, timeleft;
204
205         /* Read current socket timeout */
206 #  ifdef OPENSSL_SYS_WINDOWS
207         int timeout;
208
209         sz.i = sizeof(timeout);
210         if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
211                        (void *)&timeout, &sz.i) < 0) {
212             perror("getsockopt");
213         } else {
214             data->socket_timeout.tv_sec = timeout / 1000;
215             data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
216         }
217 #  else
218         sz.i = sizeof(data->socket_timeout);
219         if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
220                        &(data->socket_timeout), (void *)&sz) < 0) {
221             perror("getsockopt");
222         } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
223             OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
224 #  endif
225
226         /* Get current time */
227         get_current_time(&timenow);
228
229         /* Calculate time left until timer expires */
230         memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
231         if (timeleft.tv_usec < timenow.tv_usec) {
232             timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
233             timeleft.tv_sec--;
234         } else {
235             timeleft.tv_usec -= timenow.tv_usec;
236         }
237         if (timeleft.tv_sec < timenow.tv_sec) {
238             timeleft.tv_sec = 0;
239             timeleft.tv_usec = 1;
240         } else {
241             timeleft.tv_sec -= timenow.tv_sec;
242         }
243
244         /*
245          * Adjust socket timeout if next handshake message timer will expire
246          * earlier.
247          */
248         if ((data->socket_timeout.tv_sec == 0
249              && data->socket_timeout.tv_usec == 0)
250             || (data->socket_timeout.tv_sec > timeleft.tv_sec)
251             || (data->socket_timeout.tv_sec == timeleft.tv_sec
252                 && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
253 #  ifdef OPENSSL_SYS_WINDOWS
254             timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
255             if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
256                            (void *)&timeout, sizeof(timeout)) < 0) {
257                 perror("setsockopt");
258             }
259 #  else
260             if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
261                            sizeof(struct timeval)) < 0) {
262                 perror("setsockopt");
263             }
264 #  endif
265         }
266     }
267 # endif
268 }
269
270 static void dgram_reset_rcv_timeout(BIO *b)
271 {
272 # if defined(SO_RCVTIMEO)
273     bio_dgram_data *data = (bio_dgram_data *)b->ptr;
274
275     /* Is a timer active? */
276     if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
277 #  ifdef OPENSSL_SYS_WINDOWS
278         int timeout = data->socket_timeout.tv_sec * 1000 +
279             data->socket_timeout.tv_usec / 1000;
280         if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
281                        (void *)&timeout, sizeof(timeout)) < 0) {
282             perror("setsockopt");
283         }
284 #  else
285         if (setsockopt
286             (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
287              sizeof(struct timeval)) < 0) {
288             perror("setsockopt");
289         }
290 #  endif
291     }
292 # endif
293 }
294
295 static int dgram_read(BIO *b, char *out, int outl)
296 {
297     int ret = 0;
298     bio_dgram_data *data = (bio_dgram_data *)b->ptr;
299     int flags = 0;
300
301     BIO_ADDR peer;
302     socklen_t len = sizeof(peer);
303
304     if (out != NULL) {
305         clear_socket_error();
306         memset(&peer, 0, sizeof(peer));
307         dgram_adjust_rcv_timeout(b);
308         if (data->peekmode)
309             flags = MSG_PEEK;
310         ret = recvfrom(b->num, out, outl, flags,
311                        BIO_ADDR_sockaddr_noconst(&peer), &len);
312
313         if (!data->connected && ret >= 0)
314             BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
315
316         BIO_clear_retry_flags(b);
317         if (ret < 0) {
318             if (BIO_dgram_should_retry(ret)) {
319                 BIO_set_retry_read(b);
320                 data->_errno = get_last_socket_error();
321             }
322         }
323
324         dgram_reset_rcv_timeout(b);
325     }
326     return ret;
327 }
328
329 static int dgram_write(BIO *b, const char *in, int inl)
330 {
331     int ret;
332     bio_dgram_data *data = (bio_dgram_data *)b->ptr;
333     clear_socket_error();
334
335     if (data->connected)
336         ret = writesocket(b->num, in, inl);
337     else {
338         int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
339
340         ret = sendto(b->num, in, inl, 0,
341                      BIO_ADDR_sockaddr(&data->peer), peerlen);
342     }
343
344     BIO_clear_retry_flags(b);
345     if (ret <= 0) {
346         if (BIO_dgram_should_retry(ret)) {
347             BIO_set_retry_write(b);
348             data->_errno = get_last_socket_error();
349         }
350     }
351     return ret;
352 }
353
354 static long dgram_get_mtu_overhead(bio_dgram_data *data)
355 {
356     long ret;
357
358     switch (BIO_ADDR_family(&data->peer)) {
359     case AF_INET:
360         /*
361          * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
362          */
363         ret = 28;
364         break;
365 # if OPENSSL_USE_IPV6
366     case AF_INET6:
367         {
368 #  ifdef IN6_IS_ADDR_V4MAPPED
369             struct in6_addr tmp_addr;
370             if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
371                 && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
372                 /*
373                  * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
374                  */
375                 ret = 28;
376             else
377 #  endif
378             /*
379              * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
380              */
381             ret = 48;
382         }
383         break;
384 # endif
385     default:
386         /* We don't know. Go with the historical default */
387         ret = 28;
388         break;
389     }
390     return ret;
391 }
392
393 static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
394 {
395     long ret = 1;
396     int *ip;
397     bio_dgram_data *data = NULL;
398     int sockopt_val = 0;
399     int d_errno;
400 # if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
401     socklen_t sockopt_len;      /* assume that system supporting IP_MTU is
402                                  * modern enough to define socklen_t */
403     socklen_t addr_len;
404     BIO_ADDR addr;
405 # endif
406
407     data = (bio_dgram_data *)b->ptr;
408
409     switch (cmd) {
410     case BIO_CTRL_RESET:
411         num = 0;
412         ret = 0;
413         break;
414     case BIO_CTRL_INFO:
415         ret = 0;
416         break;
417     case BIO_C_SET_FD:
418         dgram_clear(b);
419         b->num = *((int *)ptr);
420         b->shutdown = (int)num;
421         b->init = 1;
422         break;
423     case BIO_C_GET_FD:
424         if (b->init) {
425             ip = (int *)ptr;
426             if (ip != NULL)
427                 *ip = b->num;
428             ret = b->num;
429         } else
430             ret = -1;
431         break;
432     case BIO_CTRL_GET_CLOSE:
433         ret = b->shutdown;
434         break;
435     case BIO_CTRL_SET_CLOSE:
436         b->shutdown = (int)num;
437         break;
438     case BIO_CTRL_PENDING:
439     case BIO_CTRL_WPENDING:
440         ret = 0;
441         break;
442     case BIO_CTRL_DUP:
443     case BIO_CTRL_FLUSH:
444         ret = 1;
445         break;
446     case BIO_CTRL_DGRAM_CONNECT:
447         BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
448         break;
449         /* (Linux)kernel sets DF bit on outgoing IP packets */
450     case BIO_CTRL_DGRAM_MTU_DISCOVER:
451 # if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
452         addr_len = (socklen_t) sizeof(addr);
453         memset(&addr, 0, sizeof(addr));
454         if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
455             ret = 0;
456             break;
457         }
458         switch (addr.sa.sa_family) {
459         case AF_INET:
460             sockopt_val = IP_PMTUDISC_DO;
461             if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
462                                   &sockopt_val, sizeof(sockopt_val))) < 0)
463                 perror("setsockopt");
464             break;
465 #  if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
466         case AF_INET6:
467             sockopt_val = IPV6_PMTUDISC_DO;
468             if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
469                                   &sockopt_val, sizeof(sockopt_val))) < 0)
470                 perror("setsockopt");
471             break;
472 #  endif
473         default:
474             ret = -1;
475             break;
476         }
477 # else
478         ret = -1;
479 # endif
480         break;
481     case BIO_CTRL_DGRAM_QUERY_MTU:
482 # if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
483         addr_len = (socklen_t) sizeof(addr);
484         memset(&addr, 0, sizeof(addr));
485         if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
486             ret = 0;
487             break;
488         }
489         sockopt_len = sizeof(sockopt_val);
490         switch (addr.sa.sa_family) {
491         case AF_INET:
492             if ((ret =
493                  getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
494                             &sockopt_len)) < 0 || sockopt_val < 0) {
495                 ret = 0;
496             } else {
497                 /*
498                  * we assume that the transport protocol is UDP and no IP
499                  * options are used.
500                  */
501                 data->mtu = sockopt_val - 8 - 20;
502                 ret = data->mtu;
503             }
504             break;
505 #  if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
506         case AF_INET6:
507             if ((ret =
508                  getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
509                             (void *)&sockopt_val, &sockopt_len)) < 0
510                 || sockopt_val < 0) {
511                 ret = 0;
512             } else {
513                 /*
514                  * we assume that the transport protocol is UDP and no IPV6
515                  * options are used.
516                  */
517                 data->mtu = sockopt_val - 8 - 40;
518                 ret = data->mtu;
519             }
520             break;
521 #  endif
522         default:
523             ret = 0;
524             break;
525         }
526 # else
527         ret = 0;
528 # endif
529         break;
530     case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
531         ret = -dgram_get_mtu_overhead(data);
532         switch (BIO_ADDR_family(&data->peer)) {
533         case AF_INET:
534             ret += 576;
535             break;
536 # if OPENSSL_USE_IPV6
537         case AF_INET6:
538             {
539 #  ifdef IN6_IS_ADDR_V4MAPPED
540                 struct in6_addr tmp_addr;
541                 if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
542                     && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
543                     ret += 576;
544                 else
545 #  endif
546                     ret += 1280;
547             }
548             break;
549 # endif
550         default:
551             ret += 576;
552             break;
553         }
554         break;
555     case BIO_CTRL_DGRAM_GET_MTU:
556         return data->mtu;
557     case BIO_CTRL_DGRAM_SET_MTU:
558         data->mtu = num;
559         ret = num;
560         break;
561     case BIO_CTRL_DGRAM_SET_CONNECTED:
562         if (ptr != NULL) {
563             data->connected = 1;
564             BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
565         } else {
566             data->connected = 0;
567             memset(&data->peer, 0, sizeof(data->peer));
568         }
569         break;
570     case BIO_CTRL_DGRAM_GET_PEER:
571         ret = BIO_ADDR_sockaddr_size(&data->peer);
572         /* FIXME: if num < ret, we will only return part of an address.
573            That should bee an error, no? */
574         if (num == 0 || num > ret)
575             num = ret;
576         memcpy(ptr, &data->peer, (ret = num));
577         break;
578     case BIO_CTRL_DGRAM_SET_PEER:
579         BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
580         break;
581     case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
582         memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
583         break;
584 # if defined(SO_RCVTIMEO)
585     case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
586 #  ifdef OPENSSL_SYS_WINDOWS
587         {
588             struct timeval *tv = (struct timeval *)ptr;
589             int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
590             if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
591                            (void *)&timeout, sizeof(timeout)) < 0) {
592                 perror("setsockopt");
593                 ret = -1;
594             }
595         }
596 #  else
597         if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
598                        sizeof(struct timeval)) < 0) {
599             perror("setsockopt");
600             ret = -1;
601         }
602 #  endif
603         break;
604     case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
605         {
606             union {
607                 size_t s;
608                 int i;
609             } sz = {
610                 0
611             };
612 #  ifdef OPENSSL_SYS_WINDOWS
613             int timeout;
614             struct timeval *tv = (struct timeval *)ptr;
615
616             sz.i = sizeof(timeout);
617             if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
618                            (void *)&timeout, &sz.i) < 0) {
619                 perror("getsockopt");
620                 ret = -1;
621             } else {
622                 tv->tv_sec = timeout / 1000;
623                 tv->tv_usec = (timeout % 1000) * 1000;
624                 ret = sizeof(*tv);
625             }
626 #  else
627             sz.i = sizeof(struct timeval);
628             if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
629                            ptr, (void *)&sz) < 0) {
630                 perror("getsockopt");
631                 ret = -1;
632             } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
633                 OPENSSL_assert(sz.s <= sizeof(struct timeval));
634                 ret = (int)sz.s;
635             } else
636                 ret = sz.i;
637 #  endif
638         }
639         break;
640 # endif
641 # if defined(SO_SNDTIMEO)
642     case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
643 #  ifdef OPENSSL_SYS_WINDOWS
644         {
645             struct timeval *tv = (struct timeval *)ptr;
646             int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
647             if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
648                            (void *)&timeout, sizeof(timeout)) < 0) {
649                 perror("setsockopt");
650                 ret = -1;
651             }
652         }
653 #  else
654         if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
655                        sizeof(struct timeval)) < 0) {
656             perror("setsockopt");
657             ret = -1;
658         }
659 #  endif
660         break;
661     case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
662         {
663             union {
664                 size_t s;
665                 int i;
666             } sz = {
667                 0
668             };
669 #  ifdef OPENSSL_SYS_WINDOWS
670             int timeout;
671             struct timeval *tv = (struct timeval *)ptr;
672
673             sz.i = sizeof(timeout);
674             if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
675                            (void *)&timeout, &sz.i) < 0) {
676                 perror("getsockopt");
677                 ret = -1;
678             } else {
679                 tv->tv_sec = timeout / 1000;
680                 tv->tv_usec = (timeout % 1000) * 1000;
681                 ret = sizeof(*tv);
682             }
683 #  else
684             sz.i = sizeof(struct timeval);
685             if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
686                            ptr, (void *)&sz) < 0) {
687                 perror("getsockopt");
688                 ret = -1;
689             } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
690                 OPENSSL_assert(sz.s <= sizeof(struct timeval));
691                 ret = (int)sz.s;
692             } else
693                 ret = sz.i;
694 #  endif
695         }
696         break;
697 # endif
698     case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
699         /* fall-through */
700     case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
701 # ifdef OPENSSL_SYS_WINDOWS
702         d_errno = (data->_errno == WSAETIMEDOUT);
703 # else
704         d_errno = (data->_errno == EAGAIN);
705 # endif
706         if (d_errno) {
707             ret = 1;
708             data->_errno = 0;
709         } else
710             ret = 0;
711         break;
712 # ifdef EMSGSIZE
713     case BIO_CTRL_DGRAM_MTU_EXCEEDED:
714         if (data->_errno == EMSGSIZE) {
715             ret = 1;
716             data->_errno = 0;
717         } else
718             ret = 0;
719         break;
720 # endif
721     case BIO_CTRL_DGRAM_SET_DONT_FRAG:
722         sockopt_val = num ? 1 : 0;
723
724         switch (data->peer.sa.sa_family) {
725         case AF_INET:
726 # if defined(IP_DONTFRAG)
727             if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
728                                   &sockopt_val, sizeof(sockopt_val))) < 0) {
729                 perror("setsockopt");
730                 ret = -1;
731             }
732 # elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
733             if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
734                 (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
735                                   &sockopt_val, sizeof(sockopt_val))) < 0) {
736                 perror("setsockopt");
737                 ret = -1;
738             }
739 # elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
740             if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
741                                   (const char *)&sockopt_val,
742                                   sizeof(sockopt_val))) < 0) {
743                 perror("setsockopt");
744                 ret = -1;
745             }
746 # else
747             ret = -1;
748 # endif
749             break;
750 # if OPENSSL_USE_IPV6
751         case AF_INET6:
752 #  if defined(IPV6_DONTFRAG)
753             if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
754                                   (const void *)&sockopt_val,
755                                   sizeof(sockopt_val))) < 0) {
756                 perror("setsockopt");
757                 ret = -1;
758             }
759 #  elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
760             if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
761                 (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
762                                   &sockopt_val, sizeof(sockopt_val))) < 0) {
763                 perror("setsockopt");
764                 ret = -1;
765             }
766 #  else
767             ret = -1;
768 #  endif
769             break;
770 # endif
771         default:
772             ret = -1;
773             break;
774         }
775         break;
776     case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
777         ret = dgram_get_mtu_overhead(data);
778         break;
779
780     /*
781      * BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE is used here for compatibility
782      * reasons. When BIO_CTRL_DGRAM_SET_PEEK_MODE was first defined its value
783      * was incorrectly clashing with BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE. The
784      * value has been updated to a non-clashing value. However to preserve
785      * binary compatibility we now respond to both the old value and the new one
786      */
787     case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
788     case BIO_CTRL_DGRAM_SET_PEEK_MODE:
789         data->peekmode = (unsigned int)num;
790         break;
791     default:
792         ret = 0;
793         break;
794     }
795     return ret;
796 }
797
798 static int dgram_puts(BIO *bp, const char *str)
799 {
800     int n, ret;
801
802     n = strlen(str);
803     ret = dgram_write(bp, str, n);
804     return ret;
805 }
806
807 # ifndef OPENSSL_NO_SCTP
808 const BIO_METHOD *BIO_s_datagram_sctp(void)
809 {
810     return &methods_dgramp_sctp;
811 }
812
813 BIO *BIO_new_dgram_sctp(int fd, int close_flag)
814 {
815     BIO *bio;
816     int ret, optval = 20000;
817     int auth_data = 0, auth_forward = 0;
818     unsigned char *p;
819     struct sctp_authchunk auth;
820     struct sctp_authchunks *authchunks;
821     socklen_t sockopt_len;
822 #  ifdef SCTP_AUTHENTICATION_EVENT
823 #   ifdef SCTP_EVENT
824     struct sctp_event event;
825 #   else
826     struct sctp_event_subscribe event;
827 #   endif
828 #  endif
829
830     bio = BIO_new(BIO_s_datagram_sctp());
831     if (bio == NULL)
832         return NULL;
833     BIO_set_fd(bio, fd, close_flag);
834
835     /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
836     auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
837     ret =
838         setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
839                    sizeof(struct sctp_authchunk));
840     if (ret < 0) {
841         BIO_vfree(bio);
842         ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
843                        "Ensure SCTP AUTH chunks are enabled in kernel");
844         return NULL;
845     }
846     auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
847     ret =
848         setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
849                    sizeof(struct sctp_authchunk));
850     if (ret < 0) {
851         BIO_vfree(bio);
852         ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
853                        "Ensure SCTP AUTH chunks are enabled in kernel");
854         return NULL;
855     }
856
857     /*
858      * Test if activation was successful. When using accept(), SCTP-AUTH has
859      * to be activated for the listening socket already, otherwise the
860      * connected socket won't use it. Similarly with connect(): the socket
861      * prior to connection must be activated for SCTP-AUTH
862      */
863     sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
864     authchunks = OPENSSL_zalloc(sockopt_len);
865     if (authchunks == NULL) {
866         BIO_vfree(bio);
867         return NULL;
868     }
869     ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
870                    &sockopt_len);
871     if (ret < 0) {
872         OPENSSL_free(authchunks);
873         BIO_vfree(bio);
874         return NULL;
875     }
876
877     for (p = (unsigned char *)authchunks->gauth_chunks;
878          p < (unsigned char *)authchunks + sockopt_len;
879          p += sizeof(uint8_t)) {
880         if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
881             auth_data = 1;
882         if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
883             auth_forward = 1;
884     }
885
886     OPENSSL_free(authchunks);
887
888     if (!auth_data || !auth_forward) {
889         BIO_vfree(bio);
890         ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
891                        "Ensure SCTP AUTH chunks are enabled on the "
892                        "underlying socket");
893         return NULL;
894     }
895
896 #  ifdef SCTP_AUTHENTICATION_EVENT
897 #   ifdef SCTP_EVENT
898     memset(&event, 0, sizeof(event));
899     event.se_assoc_id = 0;
900     event.se_type = SCTP_AUTHENTICATION_EVENT;
901     event.se_on = 1;
902     ret =
903         setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
904                    sizeof(struct sctp_event));
905     if (ret < 0) {
906         BIO_vfree(bio);
907         return NULL;
908     }
909 #   else
910     sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
911     ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
912     if (ret < 0) {
913         BIO_vfree(bio);
914         return NULL;
915     }
916
917     event.sctp_authentication_event = 1;
918
919     ret =
920         setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
921                    sizeof(struct sctp_event_subscribe));
922     if (ret < 0) {
923         BIO_vfree(bio);
924         return NULL;
925     }
926 #   endif
927 #  endif
928
929     /*
930      * Disable partial delivery by setting the min size larger than the max
931      * record size of 2^14 + 2048 + 13
932      */
933     ret =
934         setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
935                    sizeof(optval));
936     if (ret < 0) {
937         BIO_vfree(bio);
938         return NULL;
939     }
940
941     return bio;
942 }
943
944 int BIO_dgram_is_sctp(BIO *bio)
945 {
946     return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
947 }
948
949 static int dgram_sctp_new(BIO *bi)
950 {
951     bio_dgram_sctp_data *data = NULL;
952
953     bi->init = 0;
954     bi->num = 0;
955     if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) {
956         ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
957         return 0;
958     }
959 #  ifdef SCTP_PR_SCTP_NONE
960     data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
961 #  endif
962     bi->ptr = data;
963
964     bi->flags = 0;
965     return 1;
966 }
967
968 static int dgram_sctp_free(BIO *a)
969 {
970     bio_dgram_sctp_data *data;
971
972     if (a == NULL)
973         return 0;
974     if (!dgram_clear(a))
975         return 0;
976
977     data = (bio_dgram_sctp_data *) a->ptr;
978     if (data != NULL)
979         OPENSSL_free(data);
980
981     return 1;
982 }
983
984 #  ifdef SCTP_AUTHENTICATION_EVENT
985 void dgram_sctp_handle_auth_free_key_event(BIO *b,
986                                            union sctp_notification *snp)
987 {
988     int ret;
989     struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
990
991     if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
992         struct sctp_authkeyid authkeyid;
993
994         /* delete key */
995         authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
996         ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
997                          &authkeyid, sizeof(struct sctp_authkeyid));
998     }
999 }
1000 #  endif
1001
1002 static int dgram_sctp_read(BIO *b, char *out, int outl)
1003 {
1004     int ret = 0, n = 0, i, optval;
1005     socklen_t optlen;
1006     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1007     struct msghdr msg;
1008     struct iovec iov;
1009     struct cmsghdr *cmsg;
1010     char cmsgbuf[512];
1011
1012     if (out != NULL) {
1013         clear_socket_error();
1014
1015         do {
1016             memset(&data->rcvinfo, 0, sizeof(data->rcvinfo));
1017             iov.iov_base = out;
1018             iov.iov_len = outl;
1019             msg.msg_name = NULL;
1020             msg.msg_namelen = 0;
1021             msg.msg_iov = &iov;
1022             msg.msg_iovlen = 1;
1023             msg.msg_control = cmsgbuf;
1024             msg.msg_controllen = 512;
1025             msg.msg_flags = 0;
1026             n = recvmsg(b->num, &msg, 0);
1027
1028             if (n <= 0) {
1029                 if (n < 0)
1030                     ret = n;
1031                 break;
1032             }
1033
1034             if (msg.msg_controllen > 0) {
1035                 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
1036                      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1037                     if (cmsg->cmsg_level != IPPROTO_SCTP)
1038                         continue;
1039 #  ifdef SCTP_RCVINFO
1040                     if (cmsg->cmsg_type == SCTP_RCVINFO) {
1041                         struct sctp_rcvinfo *rcvinfo;
1042
1043                         rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
1044                         data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
1045                         data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
1046                         data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
1047                         data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
1048                         data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
1049                         data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
1050                         data->rcvinfo.rcv_context = rcvinfo->rcv_context;
1051                     }
1052 #  endif
1053 #  ifdef SCTP_SNDRCV
1054                     if (cmsg->cmsg_type == SCTP_SNDRCV) {
1055                         struct sctp_sndrcvinfo *sndrcvinfo;
1056
1057                         sndrcvinfo =
1058                             (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1059                         data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
1060                         data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
1061                         data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
1062                         data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
1063                         data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
1064                         data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
1065                         data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
1066                     }
1067 #  endif
1068                 }
1069             }
1070
1071             if (msg.msg_flags & MSG_NOTIFICATION) {
1072                 union sctp_notification snp;
1073
1074                 memcpy(&snp, out, sizeof(snp));
1075                 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
1076 #  ifdef SCTP_EVENT
1077                     struct sctp_event event;
1078 #  else
1079                     struct sctp_event_subscribe event;
1080                     socklen_t eventsize;
1081 #  endif
1082
1083                     /* disable sender dry event */
1084 #  ifdef SCTP_EVENT
1085                     memset(&event, 0, sizeof(event));
1086                     event.se_assoc_id = 0;
1087                     event.se_type = SCTP_SENDER_DRY_EVENT;
1088                     event.se_on = 0;
1089                     i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1090                                    sizeof(struct sctp_event));
1091                     if (i < 0) {
1092                         ret = i;
1093                         break;
1094                     }
1095 #  else
1096                     eventsize = sizeof(struct sctp_event_subscribe);
1097                     i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1098                                    &eventsize);
1099                     if (i < 0) {
1100                         ret = i;
1101                         break;
1102                     }
1103
1104                     event.sctp_sender_dry_event = 0;
1105
1106                     i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1107                                    sizeof(struct sctp_event_subscribe));
1108                     if (i < 0) {
1109                         ret = i;
1110                         break;
1111                     }
1112 #  endif
1113                 }
1114 #  ifdef SCTP_AUTHENTICATION_EVENT
1115                 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1116                     dgram_sctp_handle_auth_free_key_event(b, &snp);
1117 #  endif
1118
1119                 if (data->handle_notifications != NULL)
1120                     data->handle_notifications(b, data->notification_context,
1121                                                (void *)out);
1122
1123                 memset(&snp, 0, sizeof(snp));
1124                 memset(out, 0, outl);
1125             } else {
1126                 ret += n;
1127             }
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                 ERR_raise(ERR_LIB_BIO, 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                 ERR_raise(ERR_LIB_BIO, 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  */
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
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     case BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY:
1566         return dgram_sctp_wait_for_dry(b);
1567     case BIO_CTRL_DGRAM_SCTP_MSG_WAITING:
1568         return dgram_sctp_msg_waiting(b);
1569
1570     default:
1571         /*
1572          * Pass to default ctrl function to process SCTP unspecific commands
1573          */
1574         ret = dgram_ctrl(b, cmd, num, ptr);
1575         break;
1576     }
1577     return ret;
1578 }
1579
1580 int BIO_dgram_sctp_notification_cb(BIO *b,
1581                 BIO_dgram_sctp_notification_handler_fn handle_notifications,
1582                 void *context)
1583 {
1584     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1585
1586     if (handle_notifications != NULL) {
1587         data->handle_notifications = handle_notifications;
1588         data->notification_context = context;
1589     } else
1590         return -1;
1591
1592     return 0;
1593 }
1594
1595 /*
1596  * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event
1597  * @b: The BIO to check for the dry event
1598  *
1599  * Wait until the peer confirms all packets have been received, and so that
1600  * our kernel doesn't have anything to send anymore.  This is only received by
1601  * the peer's kernel, not the application.
1602  *
1603  * Returns:
1604  * -1 on error
1605  *  0 when not dry yet
1606  *  1 when dry
1607  */
1608 int BIO_dgram_sctp_wait_for_dry(BIO *b)
1609 {
1610     return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY, 0, NULL);
1611 }
1612
1613 static int dgram_sctp_wait_for_dry(BIO *b)
1614 {
1615     int is_dry = 0;
1616     int sockflags = 0;
1617     int n, ret;
1618     union sctp_notification snp;
1619     struct msghdr msg;
1620     struct iovec iov;
1621 #  ifdef SCTP_EVENT
1622     struct sctp_event event;
1623 #  else
1624     struct sctp_event_subscribe event;
1625     socklen_t eventsize;
1626 #  endif
1627     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1628
1629     /* set sender dry event */
1630 #  ifdef SCTP_EVENT
1631     memset(&event, 0, sizeof(event));
1632     event.se_assoc_id = 0;
1633     event.se_type = SCTP_SENDER_DRY_EVENT;
1634     event.se_on = 1;
1635     ret =
1636         setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1637                    sizeof(struct sctp_event));
1638 #  else
1639     eventsize = sizeof(struct sctp_event_subscribe);
1640     ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1641     if (ret < 0)
1642         return -1;
1643
1644     event.sctp_sender_dry_event = 1;
1645
1646     ret =
1647         setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1648                    sizeof(struct sctp_event_subscribe));
1649 #  endif
1650     if (ret < 0)
1651         return -1;
1652
1653     /* peek for notification */
1654     memset(&snp, 0, sizeof(snp));
1655     iov.iov_base = (char *)&snp;
1656     iov.iov_len = sizeof(union sctp_notification);
1657     msg.msg_name = NULL;
1658     msg.msg_namelen = 0;
1659     msg.msg_iov = &iov;
1660     msg.msg_iovlen = 1;
1661     msg.msg_control = NULL;
1662     msg.msg_controllen = 0;
1663     msg.msg_flags = 0;
1664
1665     n = recvmsg(b->num, &msg, MSG_PEEK);
1666     if (n <= 0) {
1667         if ((n < 0) && (get_last_socket_error() != EAGAIN)
1668             && (get_last_socket_error() != EWOULDBLOCK))
1669             return -1;
1670         else
1671             return 0;
1672     }
1673
1674     /* if we find a notification, process it and try again if necessary */
1675     while (msg.msg_flags & MSG_NOTIFICATION) {
1676         memset(&snp, 0, sizeof(snp));
1677         iov.iov_base = (char *)&snp;
1678         iov.iov_len = sizeof(union sctp_notification);
1679         msg.msg_name = NULL;
1680         msg.msg_namelen = 0;
1681         msg.msg_iov = &iov;
1682         msg.msg_iovlen = 1;
1683         msg.msg_control = NULL;
1684         msg.msg_controllen = 0;
1685         msg.msg_flags = 0;
1686
1687         n = recvmsg(b->num, &msg, 0);
1688         if (n <= 0) {
1689             if ((n < 0) && (get_last_socket_error() != EAGAIN)
1690                 && (get_last_socket_error() != EWOULDBLOCK))
1691                 return -1;
1692             else
1693                 return is_dry;
1694         }
1695
1696         if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
1697             is_dry = 1;
1698
1699             /* disable sender dry event */
1700 #  ifdef SCTP_EVENT
1701             memset(&event, 0, sizeof(event));
1702             event.se_assoc_id = 0;
1703             event.se_type = SCTP_SENDER_DRY_EVENT;
1704             event.se_on = 0;
1705             ret =
1706                 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1707                            sizeof(struct sctp_event));
1708 #  else
1709             eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
1710             ret =
1711                 getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1712                            &eventsize);
1713             if (ret < 0)
1714                 return -1;
1715
1716             event.sctp_sender_dry_event = 0;
1717
1718             ret =
1719                 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1720                            sizeof(struct sctp_event_subscribe));
1721 #  endif
1722             if (ret < 0)
1723                 return -1;
1724         }
1725 #  ifdef SCTP_AUTHENTICATION_EVENT
1726         if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1727             dgram_sctp_handle_auth_free_key_event(b, &snp);
1728 #  endif
1729
1730         if (data->handle_notifications != NULL)
1731             data->handle_notifications(b, data->notification_context,
1732                                        (void *)&snp);
1733
1734         /* found notification, peek again */
1735         memset(&snp, 0, sizeof(snp));
1736         iov.iov_base = (char *)&snp;
1737         iov.iov_len = sizeof(union sctp_notification);
1738         msg.msg_name = NULL;
1739         msg.msg_namelen = 0;
1740         msg.msg_iov = &iov;
1741         msg.msg_iovlen = 1;
1742         msg.msg_control = NULL;
1743         msg.msg_controllen = 0;
1744         msg.msg_flags = 0;
1745
1746         /* if we have seen the dry already, don't wait */
1747         if (is_dry) {
1748             sockflags = fcntl(b->num, F_GETFL, 0);
1749             fcntl(b->num, F_SETFL, O_NONBLOCK);
1750         }
1751
1752         n = recvmsg(b->num, &msg, MSG_PEEK);
1753
1754         if (is_dry) {
1755             fcntl(b->num, F_SETFL, sockflags);
1756         }
1757
1758         if (n <= 0) {
1759             if ((n < 0) && (get_last_socket_error() != EAGAIN)
1760                 && (get_last_socket_error() != EWOULDBLOCK))
1761                 return -1;
1762             else
1763                 return is_dry;
1764         }
1765     }
1766
1767     /* read anything else */
1768     return is_dry;
1769 }
1770
1771 int BIO_dgram_sctp_msg_waiting(BIO *b)
1772 {
1773     return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_MSG_WAITING, 0, NULL);
1774 }
1775
1776 static int dgram_sctp_msg_waiting(BIO *b)
1777 {
1778     int n, sockflags;
1779     union sctp_notification snp;
1780     struct msghdr msg;
1781     struct iovec iov;
1782     bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1783
1784     /* Check if there are any messages waiting to be read */
1785     do {
1786         memset(&snp, 0, sizeof(snp));
1787         iov.iov_base = (char *)&snp;
1788         iov.iov_len = sizeof(union sctp_notification);
1789         msg.msg_name = NULL;
1790         msg.msg_namelen = 0;
1791         msg.msg_iov = &iov;
1792         msg.msg_iovlen = 1;
1793         msg.msg_control = NULL;
1794         msg.msg_controllen = 0;
1795         msg.msg_flags = 0;
1796
1797         sockflags = fcntl(b->num, F_GETFL, 0);
1798         fcntl(b->num, F_SETFL, O_NONBLOCK);
1799         n = recvmsg(b->num, &msg, MSG_PEEK);
1800         fcntl(b->num, F_SETFL, sockflags);
1801
1802         /* if notification, process and try again */
1803         if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
1804 #  ifdef SCTP_AUTHENTICATION_EVENT
1805             if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1806                 dgram_sctp_handle_auth_free_key_event(b, &snp);
1807 #  endif
1808
1809             memset(&snp, 0, sizeof(snp));
1810             iov.iov_base = (char *)&snp;
1811             iov.iov_len = sizeof(union sctp_notification);
1812             msg.msg_name = NULL;
1813             msg.msg_namelen = 0;
1814             msg.msg_iov = &iov;
1815             msg.msg_iovlen = 1;
1816             msg.msg_control = NULL;
1817             msg.msg_controllen = 0;
1818             msg.msg_flags = 0;
1819             n = recvmsg(b->num, &msg, 0);
1820
1821             if (data->handle_notifications != NULL)
1822                 data->handle_notifications(b, data->notification_context,
1823                                            (void *)&snp);
1824         }
1825
1826     } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
1827
1828     /* Return 1 if there is a message to be read, return 0 otherwise. */
1829     if (n > 0)
1830         return 1;
1831     else
1832         return 0;
1833 }
1834
1835 static int dgram_sctp_puts(BIO *bp, const char *str)
1836 {
1837     int n, ret;
1838
1839     n = strlen(str);
1840     ret = dgram_sctp_write(bp, str, n);
1841     return ret;
1842 }
1843 # endif
1844
1845 static int BIO_dgram_should_retry(int i)
1846 {
1847     int err;
1848
1849     if ((i == 0) || (i == -1)) {
1850         err = get_last_socket_error();
1851
1852 # if defined(OPENSSL_SYS_WINDOWS)
1853         /*
1854          * If the socket return value (i) is -1 and err is unexpectedly 0 at
1855          * this point, the error code was overwritten by another system call
1856          * before this error handling is called.
1857          */
1858 # endif
1859
1860         return BIO_dgram_non_fatal_error(err);
1861     }
1862     return 0;
1863 }
1864
1865 int BIO_dgram_non_fatal_error(int err)
1866 {
1867     switch (err) {
1868 # if defined(OPENSSL_SYS_WINDOWS)
1869 #  if defined(WSAEWOULDBLOCK)
1870     case WSAEWOULDBLOCK:
1871 #  endif
1872 # endif
1873
1874 # ifdef EWOULDBLOCK
1875 #  ifdef WSAEWOULDBLOCK
1876 #   if WSAEWOULDBLOCK != EWOULDBLOCK
1877     case EWOULDBLOCK:
1878 #   endif
1879 #  else
1880     case EWOULDBLOCK:
1881 #  endif
1882 # endif
1883
1884 # ifdef EINTR
1885     case EINTR:
1886 # endif
1887
1888 # ifdef EAGAIN
1889 #  if EWOULDBLOCK != EAGAIN
1890     case EAGAIN:
1891 #  endif
1892 # endif
1893
1894 # ifdef EPROTO
1895     case EPROTO:
1896 # endif
1897
1898 # ifdef EINPROGRESS
1899     case EINPROGRESS:
1900 # endif
1901
1902 # ifdef EALREADY
1903     case EALREADY:
1904 # endif
1905
1906         return 1;
1907     default:
1908         break;
1909     }
1910     return 0;
1911 }
1912
1913 static void get_current_time(struct timeval *t)
1914 {
1915 # if defined(_WIN32)
1916     SYSTEMTIME st;
1917     union {
1918         unsigned __int64 ul;
1919         FILETIME ft;
1920     } now;
1921
1922     GetSystemTime(&st);
1923     SystemTimeToFileTime(&st, &now.ft);
1924 #  ifdef  __MINGW32__
1925     now.ul -= 116444736000000000ULL;
1926 #  else
1927     now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
1928 #  endif
1929     t->tv_sec = (long)(now.ul / 10000000);
1930     t->tv_usec = ((int)(now.ul % 10000000)) / 10;
1931 # else
1932     gettimeofday(t, NULL);
1933 # endif
1934 }
1935
1936 #endif