Coverage Report

Created: 2025-04-22 06:18

/src/openssl/crypto/bio/bss_dgram.c
Line
Count
Source (jump to first uncovered line)
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
45
static int dgram_write(BIO *h, const char *buf, int num);
46
static int dgram_read(BIO *h, char *buf, int size);
47
static int dgram_puts(BIO *h, const char *str);
48
static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
49
static int dgram_new(BIO *h);
50
static int dgram_free(BIO *data);
51
static int dgram_clear(BIO *bio);
52
53
# ifndef OPENSSL_NO_SCTP
54
static int dgram_sctp_write(BIO *h, const char *buf, int num);
55
static int dgram_sctp_read(BIO *h, char *buf, int size);
56
static int dgram_sctp_puts(BIO *h, const char *str);
57
static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
58
static int dgram_sctp_new(BIO *h);
59
static int dgram_sctp_free(BIO *data);
60
static int dgram_sctp_wait_for_dry(BIO *b);
61
static int dgram_sctp_msg_waiting(BIO *b);
62
#  ifdef SCTP_AUTHENTICATION_EVENT
63
static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
64
                                                  *snp);
65
#  endif
66
# endif
67
68
static int BIO_dgram_should_retry(int s);
69
70
static void get_current_time(struct timeval *t);
71
72
static 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
88
static 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
104
typedef 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
115
typedef struct bio_dgram_sctp_save_message_st {
116
    BIO *bio;
117
    char *data;
118
    int length;
119
} bio_dgram_sctp_save_message;
120
121
typedef 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
139
const BIO_METHOD *BIO_s_datagram(void)
140
0
{
141
0
    return &methods_dgramp;
142
0
}
143
144
BIO *BIO_new_dgram(int fd, int close_flag)
145
0
{
146
0
    BIO *ret;
147
148
0
    ret = BIO_new(BIO_s_datagram());
149
0
    if (ret == NULL)
150
0
        return NULL;
151
0
    BIO_set_fd(ret, fd, close_flag);
152
0
    return ret;
153
0
}
154
155
static int dgram_new(BIO *bi)
156
0
{
157
0
    bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
158
159
0
    if (data == NULL)
160
0
        return 0;
161
0
    bi->ptr = data;
162
0
    return 1;
163
0
}
164
165
static int dgram_free(BIO *a)
166
0
{
167
0
    bio_dgram_data *data;
168
169
0
    if (a == NULL)
170
0
        return 0;
171
0
    if (!dgram_clear(a))
172
0
        return 0;
173
174
0
    data = (bio_dgram_data *)a->ptr;
175
0
    OPENSSL_free(data);
176
177
0
    return 1;
178
0
}
179
180
static int dgram_clear(BIO *a)
181
0
{
182
0
    if (a == NULL)
183
0
        return 0;
184
0
    if (a->shutdown) {
185
0
        if (a->init) {
186
0
            BIO_closesocket(a->num);
187
0
        }
188
0
        a->init = 0;
189
0
        a->flags = 0;
190
0
    }
191
0
    return 1;
192
0
}
193
194
static void dgram_adjust_rcv_timeout(BIO *b)
195
0
{
196
0
# if defined(SO_RCVTIMEO)
197
0
    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
198
199
    /* Is a timer active? */
200
0
    if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
201
0
        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
0
        socklen_t sz = sizeof(data->socket_timeout);
217
0
        if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
218
0
                       &(data->socket_timeout), &sz) < 0) {
219
0
            perror("getsockopt");
220
0
        } else
221
0
            OPENSSL_assert(sz <= sizeof(data->socket_timeout));
222
0
#  endif
223
224
        /* Get current time */
225
0
        get_current_time(&timenow);
226
227
        /* Calculate time left until timer expires */
228
0
        memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
229
0
        if (timeleft.tv_usec < timenow.tv_usec) {
230
0
            timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
231
0
            timeleft.tv_sec--;
232
0
        } else {
233
0
            timeleft.tv_usec -= timenow.tv_usec;
234
0
        }
235
0
        if (timeleft.tv_sec < timenow.tv_sec) {
236
0
            timeleft.tv_sec = 0;
237
0
            timeleft.tv_usec = 1;
238
0
        } else {
239
0
            timeleft.tv_sec -= timenow.tv_sec;
240
0
        }
241
242
        /*
243
         * Adjust socket timeout if next handshake message timer will expire
244
         * earlier.
245
         */
246
0
        if ((data->socket_timeout.tv_sec == 0
247
0
             && data->socket_timeout.tv_usec == 0)
248
0
            || (data->socket_timeout.tv_sec > timeleft.tv_sec)
249
0
            || (data->socket_timeout.tv_sec == timeleft.tv_sec
250
0
                && 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
0
            if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
259
0
                           sizeof(struct timeval)) < 0) {
260
0
                perror("setsockopt");
261
0
            }
262
0
#  endif
263
0
        }
264
0
    }
265
0
# endif
266
0
}
267
268
static void dgram_reset_rcv_timeout(BIO *b)
269
0
{
270
0
# if defined(SO_RCVTIMEO)
271
0
    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
272
273
    /* Is a timer active? */
274
0
    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
0
        if (setsockopt
284
0
            (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
285
0
             sizeof(struct timeval)) < 0) {
286
0
            perror("setsockopt");
287
0
        }
288
0
#  endif
289
0
    }
290
0
# endif
291
0
}
292
293
static int dgram_read(BIO *b, char *out, int outl)
294
0
{
295
0
    int ret = 0;
296
0
    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
297
0
    int flags = 0;
298
299
0
    BIO_ADDR peer;
300
0
    socklen_t len = sizeof(peer);
301
302
0
    if (out != NULL) {
303
0
        clear_socket_error();
304
0
        memset(&peer, 0, sizeof(peer));
305
0
        dgram_adjust_rcv_timeout(b);
306
0
        if (data->peekmode)
307
0
            flags = MSG_PEEK;
308
0
        ret = recvfrom(b->num, out, outl, flags,
309
0
                       BIO_ADDR_sockaddr_noconst(&peer), &len);
310
311
0
        if (!data->connected && ret >= 0)
312
0
            BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
313
314
0
        BIO_clear_retry_flags(b);
315
0
        if (ret < 0) {
316
0
            if (BIO_dgram_should_retry(ret)) {
317
0
                BIO_set_retry_read(b);
318
0
                data->_errno = get_last_socket_error();
319
0
            }
320
0
        }
321
322
0
        dgram_reset_rcv_timeout(b);
323
0
    }
324
0
    return ret;
325
0
}
326
327
static int dgram_write(BIO *b, const char *in, int inl)
328
0
{
329
0
    int ret;
330
0
    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
331
0
    clear_socket_error();
332
333
0
    if (data->connected)
334
0
        ret = writesocket(b->num, in, inl);
335
0
    else {
336
0
        int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
337
338
0
        ret = sendto(b->num, in, inl, 0,
339
0
                     BIO_ADDR_sockaddr(&data->peer), peerlen);
340
0
    }
341
342
0
    BIO_clear_retry_flags(b);
343
0
    if (ret <= 0) {
344
0
        if (BIO_dgram_should_retry(ret)) {
345
0
            BIO_set_retry_write(b);
346
0
            data->_errno = get_last_socket_error();
347
0
        }
348
0
    }
349
0
    return ret;
350
0
}
351
352
static long dgram_get_mtu_overhead(bio_dgram_data *data)
353
0
{
354
0
    long ret;
355
356
0
    switch (BIO_ADDR_family(&data->peer)) {
357
0
    case AF_INET:
358
        /*
359
         * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
360
         */
361
0
        ret = 28;
362
0
        break;
363
0
# if OPENSSL_USE_IPV6
364
0
    case AF_INET6:
365
0
        {
366
0
#  ifdef IN6_IS_ADDR_V4MAPPED
367
0
            struct in6_addr tmp_addr;
368
0
            if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
369
0
                && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
370
                /*
371
                 * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
372
                 */
373
0
                ret = 28;
374
0
            else
375
0
#  endif
376
            /*
377
             * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
378
             */
379
0
            ret = 48;
380
0
        }
381
0
        break;
382
0
# endif
383
0
    default:
384
        /* We don't know. Go with the historical default */
385
0
        ret = 28;
386
0
        break;
387
0
    }
388
0
    return ret;
389
0
}
390
391
static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
392
0
{
393
0
    long ret = 1;
394
0
    int *ip;
395
0
    bio_dgram_data *data = NULL;
396
0
    int sockopt_val = 0;
397
0
    int d_errno;
398
0
# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
399
0
    socklen_t sockopt_len;      /* assume that system supporting IP_MTU is
400
                                 * modern enough to define socklen_t */
401
0
    socklen_t addr_len;
402
0
    BIO_ADDR addr;
403
0
# endif
404
405
0
    data = (bio_dgram_data *)b->ptr;
406
407
0
    switch (cmd) {
408
0
    case BIO_CTRL_RESET:
409
0
        num = 0;
410
0
        ret = 0;
411
0
        break;
412
0
    case BIO_CTRL_INFO:
413
0
        ret = 0;
414
0
        break;
415
0
    case BIO_C_SET_FD:
416
0
        dgram_clear(b);
417
0
        b->num = *((int *)ptr);
418
0
        b->shutdown = (int)num;
419
0
        b->init = 1;
420
0
        break;
421
0
    case BIO_C_GET_FD:
422
0
        if (b->init) {
423
0
            ip = (int *)ptr;
424
0
            if (ip != NULL)
425
0
                *ip = b->num;
426
0
            ret = b->num;
427
0
        } else
428
0
            ret = -1;
429
0
        break;
430
0
    case BIO_CTRL_GET_CLOSE:
431
0
        ret = b->shutdown;
432
0
        break;
433
0
    case BIO_CTRL_SET_CLOSE:
434
0
        b->shutdown = (int)num;
435
0
        break;
436
0
    case BIO_CTRL_PENDING:
437
0
    case BIO_CTRL_WPENDING:
438
0
        ret = 0;
439
0
        break;
440
0
    case BIO_CTRL_DUP:
441
0
    case BIO_CTRL_FLUSH:
442
0
        ret = 1;
443
0
        break;
444
0
    case BIO_CTRL_DGRAM_CONNECT:
445
0
        BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
446
0
        break;
447
        /* (Linux)kernel sets DF bit on outgoing IP packets */
448
0
    case BIO_CTRL_DGRAM_MTU_DISCOVER:
449
0
# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
450
0
        addr_len = (socklen_t) sizeof(addr);
451
0
        memset(&addr, 0, sizeof(addr));
452
0
        if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
453
0
            ret = 0;
454
0
            break;
455
0
        }
456
0
        switch (addr.sa.sa_family) {
457
0
        case AF_INET:
458
0
            sockopt_val = IP_PMTUDISC_DO;
459
0
            if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
460
0
                                  &sockopt_val, sizeof(sockopt_val))) < 0)
461
0
                perror("setsockopt");
462
0
            break;
463
0
#  if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
464
0
        case AF_INET6:
465
0
            sockopt_val = IPV6_PMTUDISC_DO;
466
0
            if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
467
0
                                  &sockopt_val, sizeof(sockopt_val))) < 0)
468
0
                perror("setsockopt");
469
0
            break;
470
0
#  endif
471
0
        default:
472
0
            ret = -1;
473
0
            break;
474
0
        }
475
# else
476
        ret = -1;
477
# endif
478
0
        break;
479
0
    case BIO_CTRL_DGRAM_QUERY_MTU:
480
0
# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
481
0
        addr_len = (socklen_t) sizeof(addr);
482
0
        memset(&addr, 0, sizeof(addr));
483
0
        if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
484
0
            ret = 0;
485
0
            break;
486
0
        }
487
0
        sockopt_len = sizeof(sockopt_val);
488
0
        switch (addr.sa.sa_family) {
489
0
        case AF_INET:
490
0
            if ((ret =
491
0
                 getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
492
0
                            &sockopt_len)) < 0 || sockopt_val < 0) {
493
0
                ret = 0;
494
0
            } else {
495
                /*
496
                 * we assume that the transport protocol is UDP and no IP
497
                 * options are used.
498
                 */
499
0
                data->mtu = sockopt_val - 8 - 20;
500
0
                ret = data->mtu;
501
0
            }
502
0
            break;
503
0
#  if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
504
0
        case AF_INET6:
505
0
            if ((ret =
506
0
                 getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
507
0
                            (void *)&sockopt_val, &sockopt_len)) < 0
508
0
                || sockopt_val < 0) {
509
0
                ret = 0;
510
0
            } else {
511
                /*
512
                 * we assume that the transport protocol is UDP and no IPV6
513
                 * options are used.
514
                 */
515
0
                data->mtu = sockopt_val - 8 - 40;
516
0
                ret = data->mtu;
517
0
            }
518
0
            break;
519
0
#  endif
520
0
        default:
521
0
            ret = 0;
522
0
            break;
523
0
        }
524
# else
525
        ret = 0;
526
# endif
527
0
        break;
528
0
    case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
529
0
        ret = -dgram_get_mtu_overhead(data);
530
0
        switch (BIO_ADDR_family(&data->peer)) {
531
0
        case AF_INET:
532
0
            ret += 576;
533
0
            break;
534
0
# if OPENSSL_USE_IPV6
535
0
        case AF_INET6:
536
0
            {
537
0
#  ifdef IN6_IS_ADDR_V4MAPPED
538
0
                struct in6_addr tmp_addr;
539
0
                if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
540
0
                    && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
541
0
                    ret += 576;
542
0
                else
543
0
#  endif
544
0
                    ret += 1280;
545
0
            }
546
0
            break;
547
0
# endif
548
0
        default:
549
0
            ret += 576;
550
0
            break;
551
0
        }
552
0
        break;
553
0
    case BIO_CTRL_DGRAM_GET_MTU:
554
0
        return data->mtu;
555
0
    case BIO_CTRL_DGRAM_SET_MTU:
556
0
        data->mtu = num;
557
0
        ret = num;
558
0
        break;
559
0
    case BIO_CTRL_DGRAM_SET_CONNECTED:
560
0
        if (ptr != NULL) {
561
0
            data->connected = 1;
562
0
            BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
563
0
        } else {
564
0
            data->connected = 0;
565
0
            memset(&data->peer, 0, sizeof(data->peer));
566
0
        }
567
0
        break;
568
0
    case BIO_CTRL_DGRAM_GET_PEER:
569
0
        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
0
        if (num == 0 || num > ret)
573
0
            num = ret;
574
0
        memcpy(ptr, &data->peer, (ret = num));
575
0
        break;
576
0
    case BIO_CTRL_DGRAM_SET_PEER:
577
0
        BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
578
0
        break;
579
0
    case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
580
0
        memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
581
0
        break;
582
0
# if defined(SO_RCVTIMEO)
583
0
    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
0
        if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
596
0
                       sizeof(struct timeval)) < 0) {
597
0
            perror("setsockopt");
598
0
            ret = -1;
599
0
        }
600
0
#  endif
601
0
        break;
602
0
    case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
603
0
        {
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
0
            socklen_t sz = sizeof(struct timeval);
621
0
            if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
622
0
                           ptr, &sz) < 0) {
623
0
                perror("getsockopt");
624
0
                ret = -1;
625
0
            } else {
626
0
                OPENSSL_assert(sz <= sizeof(struct timeval));
627
0
                ret = (int)sz;
628
0
            }
629
0
#  endif
630
0
        }
631
0
        break;
632
0
# endif
633
0
# if defined(SO_SNDTIMEO)
634
0
    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
0
        if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
647
0
                       sizeof(struct timeval)) < 0) {
648
0
            perror("setsockopt");
649
0
            ret = -1;
650
0
        }
651
0
#  endif
652
0
        break;
653
0
    case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
654
0
        {
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
0
            socklen_t sz = sizeof(struct timeval);
672
0
            if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
673
0
                           ptr, &sz) < 0) {
674
0
                perror("getsockopt");
675
0
                ret = -1;
676
0
            } else {
677
0
                OPENSSL_assert(sz <= sizeof(struct timeval));
678
0
                ret = (int)sz;
679
0
            }
680
0
#  endif
681
0
        }
682
0
        break;
683
0
# endif
684
0
    case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
685
        /* fall-through */
686
0
    case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
687
# ifdef OPENSSL_SYS_WINDOWS
688
        d_errno = (data->_errno == WSAETIMEDOUT);
689
# else
690
0
        d_errno = (data->_errno == EAGAIN);
691
0
# endif
692
0
        if (d_errno) {
693
0
            ret = 1;
694
0
            data->_errno = 0;
695
0
        } else
696
0
            ret = 0;
697
0
        break;
698
0
# ifdef EMSGSIZE
699
0
    case BIO_CTRL_DGRAM_MTU_EXCEEDED:
700
0
        if (data->_errno == EMSGSIZE) {
701
0
            ret = 1;
702
0
            data->_errno = 0;
703
0
        } else
704
0
            ret = 0;
705
0
        break;
706
0
# endif
707
0
    case BIO_CTRL_DGRAM_SET_DONT_FRAG:
708
0
        sockopt_val = num ? 1 : 0;
709
710
0
        switch (data->peer.sa.sa_family) {
711
0
        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
0
            if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
720
0
                (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
721
0
                                  &sockopt_val, sizeof(sockopt_val))) < 0) {
722
0
                perror("setsockopt");
723
0
                ret = -1;
724
0
            }
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
0
            break;
736
0
# if OPENSSL_USE_IPV6
737
0
        case AF_INET6:
738
0
#  if defined(IPV6_DONTFRAG)
739
0
            if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
740
0
                                  (const void *)&sockopt_val,
741
0
                                  sizeof(sockopt_val))) < 0) {
742
0
                perror("setsockopt");
743
0
                ret = -1;
744
0
            }
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
0
            break;
756
0
# endif
757
0
        default:
758
0
            ret = -1;
759
0
            break;
760
0
        }
761
0
        break;
762
0
    case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
763
0
        ret = dgram_get_mtu_overhead(data);
764
0
        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
0
    case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
774
0
    case BIO_CTRL_DGRAM_SET_PEEK_MODE:
775
0
        data->peekmode = (unsigned int)num;
776
0
        break;
777
0
    default:
778
0
        ret = 0;
779
0
        break;
780
0
    }
781
0
    return ret;
782
0
}
783
784
static int dgram_puts(BIO *bp, const char *str)
785
0
{
786
0
    int n, ret;
787
788
0
    n = strlen(str);
789
0
    ret = dgram_write(bp, str, n);
790
0
    return ret;
791
0
}
792
793
# ifndef OPENSSL_NO_SCTP
794
const BIO_METHOD *BIO_s_datagram_sctp(void)
795
{
796
    return &methods_dgramp_sctp;
797
}
798
799
BIO *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
930
int BIO_dgram_is_sctp(BIO *bio)
931
{
932
    return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
933
}
934
935
static 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
954
static 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
971
void 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
988
static 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
 */
1218
static 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
1326
static 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
1566
int 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
 */
1594
int 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
1599
static 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
1757
int BIO_dgram_sctp_msg_waiting(BIO *b)
1758
{
1759
    return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_MSG_WAITING, 0, NULL);
1760
}
1761
1762
static 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
1821
static 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
1831
static int BIO_dgram_should_retry(int i)
1832
0
{
1833
0
    int err;
1834
1835
0
    if ((i == 0) || (i == -1)) {
1836
0
        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
0
        return BIO_dgram_non_fatal_error(err);
1847
0
    }
1848
0
    return 0;
1849
0
}
1850
1851
int BIO_dgram_non_fatal_error(int err)
1852
0
{
1853
0
    switch (err) {
1854
# if defined(OPENSSL_SYS_WINDOWS)
1855
#  if defined(WSAEWOULDBLOCK)
1856
    case WSAEWOULDBLOCK:
1857
#  endif
1858
# endif
1859
1860
0
# ifdef EWOULDBLOCK
1861
#  ifdef WSAEWOULDBLOCK
1862
#   if WSAEWOULDBLOCK != EWOULDBLOCK
1863
    case EWOULDBLOCK:
1864
#   endif
1865
#  else
1866
0
    case EWOULDBLOCK:
1867
0
#  endif
1868
0
# endif
1869
1870
0
# ifdef EINTR
1871
0
    case EINTR:
1872
0
# endif
1873
1874
0
# ifdef EAGAIN
1875
#  if EWOULDBLOCK != EAGAIN
1876
    case EAGAIN:
1877
#  endif
1878
0
# endif
1879
1880
0
# ifdef EPROTO
1881
0
    case EPROTO:
1882
0
# endif
1883
1884
0
# ifdef EINPROGRESS
1885
0
    case EINPROGRESS:
1886
0
# endif
1887
1888
0
# ifdef EALREADY
1889
0
    case EALREADY:
1890
0
# endif
1891
1892
0
        return 1;
1893
0
    default:
1894
0
        break;
1895
0
    }
1896
0
    return 0;
1897
0
}
1898
1899
static void get_current_time(struct timeval *t)
1900
0
{
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
0
    if (gettimeofday(t, NULL) < 0)
1918
0
        perror("gettimeofday");
1919
0
# endif
1920
0
}
1921
1922
#endif