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