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