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