]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bio/bss_dgram.c
BIO_dgram support for BIO_sendmmsg/BIO_recvmmsg
[thirdparty/openssl.git] / crypto / bio / bss_dgram.c
CommitLineData
0f113f3e 1/*
38fc02a7 2 * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved.
36d16f8e 3 *
09abbca1 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
b1322259
RS
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
36d16f8e
BL
8 */
9
e8e1f6d1
DK
10#ifndef _GNU_SOURCE
11# define _GNU_SOURCE
12#endif
13
36d16f8e
BL
14#include <stdio.h>
15#include <errno.h>
36d16f8e 16
706457b7 17#include "bio_local.h"
74e056ed 18#ifndef OPENSSL_NO_DGRAM
36d16f8e 19
0f113f3e
MC
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
7e159e01 26
0f113f3e
MC
27# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
28# define IP_MTU 14 /* linux is lame */
29# endif
36d16f8e 30
0f113f3e
MC
31# if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
32# define IPPROTO_IPV6 41 /* windows is lame */
33# endif
5833e4f5 34
0f113f3e 35# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
03c1d9f9 36/* Standard definition causes type-punning problems. */
0f113f3e
MC
37# undef IN6_IS_ADDR_V4MAPPED
38# define s6_addr32 __u6_addr.__u6_addr32
39# define IN6_IS_ADDR_V4MAPPED(a) \
03c1d9f9
BL
40 (((a)->s6_addr32[0] == 0) && \
41 ((a)->s6_addr32[1] == 0) && \
42 ((a)->s6_addr32[2] == htonl(0x0000ffff)))
0f113f3e 43# endif
03c1d9f9 44
664e096c
HL
45/* Determine what method to use for BIO_sendmmsg and BIO_recvmmsg. */
46# define M_METHOD_NONE 0
47# define M_METHOD_RECVMMSG 1
48# define M_METHOD_RECVMSG 2
49# define M_METHOD_RECVFROM 3
50# define M_METHOD_WSARECVMSG 4
51
52# if !defined(M_METHOD)
53# if defined(OPENSSL_SYS_WINDOWS) && defined(BIO_HAVE_WSAMSG) && !defined(NO_WSARECVMSG)
54# define M_METHOD M_METHOD_WSARECVMSG
55# elif !defined(OPENSSL_SYS_WINDOWS) && defined(MSG_WAITFORONE) && !defined(NO_RECVMMSG)
56# define M_METHOD M_METHOD_RECVMMSG
57# elif !defined(OPENSSL_SYS_WINDOWS) && defined(CMSG_LEN) && !defined(NO_RECVMSG)
58# define M_METHOD M_METHOD_RECVMSG
59# elif !defined(NO_RECVFROM)
60# define M_METHOD M_METHOD_RECVFROM
61# else
62# define M_METHOD M_METHOD_NONE
63# endif
64# endif
65
66# if defined(OPENSSL_SYS_WINDOWS)
67# define BIO_CMSG_SPACE(x) WSA_CMSG_SPACE(x)
68# define BIO_CMSG_FIRSTHDR(x) WSA_CMSG_FIRSTHDR(x)
69# define BIO_CMSG_NXTHDR(x, y) WSA_CMSG_NXTHDR(x, y)
70# define BIO_CMSG_DATA(x) WSA_CMSG_DATA(x)
71# define BIO_CMSG_LEN(x) WSA_CMSG_LEN(x)
72# define MSGHDR_TYPE WSAMSG
73# define CMSGHDR_TYPE WSACMSGHDR
74# else
75# define MSGHDR_TYPE struct msghdr
76# define CMSGHDR_TYPE struct cmsghdr
77# define BIO_CMSG_SPACE(x) CMSG_SPACE(x)
78# define BIO_CMSG_FIRSTHDR(x) CMSG_FIRSTHDR(x)
79# define BIO_CMSG_NXTHDR(x, y) CMSG_NXTHDR(x, y)
80# define BIO_CMSG_DATA(x) CMSG_DATA(x)
81# define BIO_CMSG_LEN(x) CMSG_LEN(x)
82# endif
83
84# if M_METHOD == M_METHOD_RECVMMSG \
85 || M_METHOD == M_METHOD_RECVMSG \
86 || M_METHOD == M_METHOD_WSARECVMSG
87# if defined(__APPLE__)
88 /*
89 * CMSG_SPACE is not a constant expresson on OSX even though POSIX
90 * says it's supposed to be. This should be adequate.
91 */
92# define BIO_CMSG_ALLOC_LEN 64
93# else
94# if defined(IPV6_PKTINFO)
95# define BIO_CMSG_ALLOC_LEN_1 BIO_CMSG_SPACE(sizeof(struct in6_pktinfo))
96# else
97# define BIO_CMSG_ALLOC_LEN_1 0
98# endif
99# if defined(IP_PKTINFO)
100# define BIO_CMSG_ALLOC_LEN_2 BIO_CMSG_SPACE(sizeof(struct in_pktinfo))
101# else
102# define BIO_CMSG_ALLOC_LEN_2 0
103# endif
104# if defined(IP_RECVDSTADDR)
105# define BIO_CMSG_ALLOC_LEN_3 BIO_CMSG_SPACE(sizeof(struct in_addr))
106# else
107# define BIO_CMSG_ALLOC_LEN_3 0
108# endif
109# define BIO_MAX(X,Y) ((X) > (Y) ? (X) : (Y))
110# define BIO_CMSG_ALLOC_LEN \
111 BIO_MAX(BIO_CMSG_ALLOC_LEN_1, \
112 BIO_MAX(BIO_CMSG_ALLOC_LEN_2, BIO_CMSG_ALLOC_LEN_3))
113# endif
114# if (defined(IP_PKTINFO) || defined(IP_RECVDSTADDR)) && defined(IPV6_RECVPKTINFO)
115# define SUPPORT_LOCAL_ADDR
116# endif
117# endif
118
119# define BIO_MSG_N(array, stride, n) (*(BIO_MSG *)((char *)(array) + (n)*(stride)))
120
36d16f8e
BL
121static int dgram_write(BIO *h, const char *buf, int num);
122static int dgram_read(BIO *h, char *buf, int size);
123static int dgram_puts(BIO *h, const char *str);
124static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
125static int dgram_new(BIO *h);
126static int dgram_free(BIO *data);
127static int dgram_clear(BIO *bio);
664e096c
HL
128static int dgram_sendmmsg(BIO *b, BIO_MSG *msg,
129 size_t stride, size_t num_msg,
130 uint64_t flags, size_t *num_processed);
131static int dgram_recvmmsg(BIO *b, BIO_MSG *msg,
132 size_t stride, size_t num_msg,
133 uint64_t flags, size_t *num_processed);
36d16f8e 134
0f113f3e 135# ifndef OPENSSL_NO_SCTP
7e159e01
DSH
136static int dgram_sctp_write(BIO *h, const char *buf, int num);
137static int dgram_sctp_read(BIO *h, char *buf, int size);
138static int dgram_sctp_puts(BIO *h, const char *str);
139static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
140static int dgram_sctp_new(BIO *h);
141static int dgram_sctp_free(BIO *data);
c8edb04f 142static int dgram_sctp_wait_for_dry(BIO *b);
143static int dgram_sctp_msg_waiting(BIO *b);
0f113f3e
MC
144# ifdef SCTP_AUTHENTICATION_EVENT
145static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
146 *snp);
147# endif
148# endif
7e159e01 149
b3e72fc3 150static int BIO_dgram_should_retry(int s);
36d16f8e 151
5d6a0179
RL
152static void get_current_time(struct timeval *t);
153
04f6b0fd 154static const BIO_METHOD methods_dgramp = {
0f113f3e
MC
155 BIO_TYPE_DGRAM,
156 "datagram socket",
3befffa3 157 bwrite_conv,
0f113f3e 158 dgram_write,
d07aee2c 159 bread_conv,
0f113f3e
MC
160 dgram_read,
161 dgram_puts,
b4ff6622 162 NULL, /* dgram_gets, */
0f113f3e
MC
163 dgram_ctrl,
164 dgram_new,
165 dgram_free,
b4ff6622 166 NULL, /* dgram_callback_ctrl */
664e096c
HL
167 dgram_sendmmsg,
168 dgram_recvmmsg,
0f113f3e
MC
169};
170
171# ifndef OPENSSL_NO_SCTP
04f6b0fd 172static const BIO_METHOD methods_dgramp_sctp = {
0f113f3e
MC
173 BIO_TYPE_DGRAM_SCTP,
174 "datagram sctp socket",
992155d0 175 bwrite_conv,
0f113f3e 176 dgram_sctp_write,
992155d0 177 bread_conv,
0f113f3e
MC
178 dgram_sctp_read,
179 dgram_sctp_puts,
b4ff6622 180 NULL, /* dgram_gets, */
0f113f3e
MC
181 dgram_sctp_ctrl,
182 dgram_sctp_new,
183 dgram_sctp_free,
b4ff6622 184 NULL, /* dgram_callback_ctrl */
664e096c
HL
185 NULL, /* sendmmsg */
186 NULL, /* recvmmsg */
0f113f3e
MC
187};
188# endif
7e159e01 189
0f113f3e 190typedef struct bio_dgram_data_st {
d858c876 191 BIO_ADDR peer;
664e096c 192 BIO_ADDR local_addr;
0f113f3e
MC
193 unsigned int connected;
194 unsigned int _errno;
195 unsigned int mtu;
196 struct timeval next_timeout;
197 struct timeval socket_timeout;
01b7851a 198 unsigned int peekmode;
664e096c 199 char local_addr_enabled;
0f113f3e
MC
200} bio_dgram_data;
201
202# ifndef OPENSSL_NO_SCTP
203typedef struct bio_dgram_sctp_save_message_st {
204 BIO *bio;
205 char *data;
206 int length;
207} bio_dgram_sctp_save_message;
208
209typedef struct bio_dgram_sctp_data_st {
d858c876 210 BIO_ADDR peer;
0f113f3e
MC
211 unsigned int connected;
212 unsigned int _errno;
213 unsigned int mtu;
214 struct bio_dgram_sctp_sndinfo sndinfo;
215 struct bio_dgram_sctp_rcvinfo rcvinfo;
216 struct bio_dgram_sctp_prinfo prinfo;
c8edb04f 217 BIO_dgram_sctp_notification_handler_fn handle_notifications;
0f113f3e
MC
218 void *notification_context;
219 int in_handshake;
220 int ccs_rcvd;
221 int ccs_sent;
222 int save_shutdown;
223 int peer_auth_tested;
0f113f3e
MC
224} bio_dgram_sctp_data;
225# endif
7e159e01 226
04f6b0fd 227const BIO_METHOD *BIO_s_datagram(void)
0f113f3e 228{
26a7d938 229 return &methods_dgramp;
0f113f3e 230}
36d16f8e
BL
231
232BIO *BIO_new_dgram(int fd, int close_flag)
0f113f3e
MC
233{
234 BIO *ret;
36d16f8e 235
0f113f3e
MC
236 ret = BIO_new(BIO_s_datagram());
237 if (ret == NULL)
26a7d938 238 return NULL;
0f113f3e 239 BIO_set_fd(ret, fd, close_flag);
26a7d938 240 return ret;
0f113f3e 241}
36d16f8e
BL
242
243static int dgram_new(BIO *bi)
0f113f3e 244{
b51bce94 245 bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
0f113f3e 246
0f113f3e
MC
247 if (data == NULL)
248 return 0;
36d16f8e 249 bi->ptr = data;
208fb891 250 return 1;
0f113f3e 251}
36d16f8e
BL
252
253static int dgram_free(BIO *a)
0f113f3e
MC
254{
255 bio_dgram_data *data;
36d16f8e 256
0f113f3e 257 if (a == NULL)
26a7d938 258 return 0;
0f113f3e
MC
259 if (!dgram_clear(a))
260 return 0;
36d16f8e 261
0f113f3e 262 data = (bio_dgram_data *)a->ptr;
b548a1f1 263 OPENSSL_free(data);
36d16f8e 264
208fb891 265 return 1;
0f113f3e 266}
36d16f8e
BL
267
268static int dgram_clear(BIO *a)
0f113f3e
MC
269{
270 if (a == NULL)
26a7d938 271 return 0;
0f113f3e
MC
272 if (a->shutdown) {
273 if (a->init) {
8731a4fc 274 BIO_closesocket(a->num);
0f113f3e
MC
275 }
276 a->init = 0;
277 a->flags = 0;
278 }
208fb891 279 return 1;
0f113f3e 280}
eb38b26d
DSH
281
282static void dgram_adjust_rcv_timeout(BIO *b)
0f113f3e
MC
283{
284# if defined(SO_RCVTIMEO)
285 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
0f113f3e
MC
286
287 /* Is a timer active? */
288 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
289 struct timeval timenow, timeleft;
290
291 /* Read current socket timeout */
292# ifdef OPENSSL_SYS_WINDOWS
293 int timeout;
294
8e949b35 295 int sz = sizeof(timeout);
0f113f3e 296 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
8e949b35 297 (void *)&timeout, &sz) < 0) {
0f113f3e
MC
298 perror("getsockopt");
299 } else {
300 data->socket_timeout.tv_sec = timeout / 1000;
301 data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
302 }
303# else
8e949b35 304 socklen_t sz = sizeof(data->socket_timeout);
0f113f3e 305 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
8e949b35 306 &(data->socket_timeout), &sz) < 0) {
0f113f3e 307 perror("getsockopt");
8e949b35
TK
308 } else
309 OPENSSL_assert(sz <= sizeof(data->socket_timeout));
0f113f3e 310# endif
eb38b26d 311
0f113f3e
MC
312 /* Get current time */
313 get_current_time(&timenow);
314
315 /* Calculate time left until timer expires */
316 memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
fc52ac90
MC
317 if (timeleft.tv_usec < timenow.tv_usec) {
318 timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
0f113f3e 319 timeleft.tv_sec--;
fc52ac90
MC
320 } else {
321 timeleft.tv_usec -= timenow.tv_usec;
0f113f3e 322 }
fc52ac90 323 if (timeleft.tv_sec < timenow.tv_sec) {
0f113f3e
MC
324 timeleft.tv_sec = 0;
325 timeleft.tv_usec = 1;
fc52ac90
MC
326 } else {
327 timeleft.tv_sec -= timenow.tv_sec;
0f113f3e
MC
328 }
329
330 /*
0d4fb843 331 * Adjust socket timeout if next handshake message timer will expire
0f113f3e
MC
332 * earlier.
333 */
334 if ((data->socket_timeout.tv_sec == 0
335 && data->socket_timeout.tv_usec == 0)
336 || (data->socket_timeout.tv_sec > timeleft.tv_sec)
337 || (data->socket_timeout.tv_sec == timeleft.tv_sec
338 && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
339# ifdef OPENSSL_SYS_WINDOWS
340 timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
341 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
342 (void *)&timeout, sizeof(timeout)) < 0) {
343 perror("setsockopt");
344 }
345# else
346 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
347 sizeof(struct timeval)) < 0) {
348 perror("setsockopt");
349 }
350# endif
351 }
352 }
353# endif
354}
eb38b26d 355
664e096c
HL
356static void dgram_update_local_addr(BIO *b)
357{
358 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
359 socklen_t addr_len = sizeof(data->local_addr);
360
361 if (getsockname(b->num, &data->local_addr.sa, &addr_len) < 0)
362 /*
363 * This should not be possible, but zero-initialize and return
364 * anyway.
365 */
366 BIO_ADDR_clear(&data->local_addr);
367}
368
369# if M_METHOD == M_METHOD_RECVMMSG || M_METHOD == M_METHOD_RECVMSG || M_METHOD == M_METHOD_WSARECVMSG
370static int dgram_get_sock_family(BIO *b)
371{
372 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
373 return data->local_addr.sa.sa_family;
374}
375# endif
376
eb38b26d 377static void dgram_reset_rcv_timeout(BIO *b)
0f113f3e
MC
378{
379# if defined(SO_RCVTIMEO)
380 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
381
382 /* Is a timer active? */
383 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
384# ifdef OPENSSL_SYS_WINDOWS
385 int timeout = data->socket_timeout.tv_sec * 1000 +
386 data->socket_timeout.tv_usec / 1000;
387 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
388 (void *)&timeout, sizeof(timeout)) < 0) {
389 perror("setsockopt");
390 }
391# else
392 if (setsockopt
393 (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
394 sizeof(struct timeval)) < 0) {
395 perror("setsockopt");
396 }
397# endif
398 }
399# endif
400}
eb38b26d 401
36d16f8e 402static int dgram_read(BIO *b, char *out, int outl)
0f113f3e
MC
403{
404 int ret = 0;
405 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
01b7851a 406 int flags = 0;
0f113f3e 407
d858c876
RL
408 BIO_ADDR peer;
409 socklen_t len = sizeof(peer);
0f113f3e
MC
410
411 if (out != NULL) {
412 clear_socket_error();
664e096c 413 BIO_ADDR_clear(&peer);
0f113f3e 414 dgram_adjust_rcv_timeout(b);
01b7851a
MC
415 if (data->peekmode)
416 flags = MSG_PEEK;
d858c876
RL
417 ret = recvfrom(b->num, out, outl, flags,
418 BIO_ADDR_sockaddr_noconst(&peer), &len);
0f113f3e
MC
419
420 if (!data->connected && ret >= 0)
d858c876 421 BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
0f113f3e
MC
422
423 BIO_clear_retry_flags(b);
424 if (ret < 0) {
425 if (BIO_dgram_should_retry(ret)) {
426 BIO_set_retry_read(b);
427 data->_errno = get_last_socket_error();
428 }
429 }
430
431 dgram_reset_rcv_timeout(b);
432 }
26a7d938 433 return ret;
0f113f3e 434}
36d16f8e
BL
435
436static int dgram_write(BIO *b, const char *in, int inl)
0f113f3e
MC
437{
438 int ret;
439 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
440 clear_socket_error();
441
442 if (data->connected)
443 ret = writesocket(b->num, in, inl);
444 else {
d858c876 445 int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
0f113f3e 446
d858c876
RL
447 ret = sendto(b->num, in, inl, 0,
448 BIO_ADDR_sockaddr(&data->peer), peerlen);
0f113f3e
MC
449 }
450
451 BIO_clear_retry_flags(b);
452 if (ret <= 0) {
453 if (BIO_dgram_should_retry(ret)) {
454 BIO_set_retry_write(b);
455 data->_errno = get_last_socket_error();
0f113f3e
MC
456 }
457 }
26a7d938 458 return ret;
0f113f3e 459}
36d16f8e 460
0d3ae34d 461static long dgram_get_mtu_overhead(bio_dgram_data *data)
0f113f3e
MC
462{
463 long ret;
464
d858c876 465 switch (BIO_ADDR_family(&data->peer)) {
0f113f3e
MC
466 case AF_INET:
467 /*
468 * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
469 */
470 ret = 28;
471 break;
f36e9f11 472# if OPENSSL_USE_IPV6
0f113f3e 473 case AF_INET6:
d858c876 474 {
0f113f3e 475# ifdef IN6_IS_ADDR_V4MAPPED
d858c876
RL
476 struct in6_addr tmp_addr;
477 if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
478 && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
479 /*
480 * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
481 */
482 ret = 28;
483 else
0f113f3e
MC
484# endif
485 /*
486 * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
487 */
488 ret = 48;
d858c876 489 }
0f113f3e
MC
490 break;
491# endif
492 default:
493 /* We don't know. Go with the historical default */
494 ret = 28;
495 break;
496 }
497 return ret;
498}
0d3ae34d 499
664e096c
HL
500/* Enables appropriate destination address reception option on the socket. */
501# if defined(SUPPORT_LOCAL_ADDR)
502static int enable_local_addr(BIO *b, int enable) {
503 int af = dgram_get_sock_family(b);
504
505 if (af == AF_INET) {
506# if defined(IP_PKTINFO)
507 /* IP_PKTINFO is preferred */
508 if (setsockopt(b->num, IPPROTO_IP, IP_PKTINFO,
509 (void *)&enable, sizeof(enable)) < 0)
510 return 0;
511
512 return 1;
513
514# elif defined(IP_RECVDSTADDR)
515 /* Fall back to IP_RECVDSTADDR */
516
517 if (setsockopt(b->num, IPPROTO_IP, IP_RECVDSTADDR,
518 &enable, sizeof(enable)) < 0)
519 return 0;
520
521 return 1;
522# endif
523 }
524
525# if OPENSSL_USE_IPV6
526 if (af == AF_INET6) {
527# if defined(IPV6_RECVPKTINFO)
528 if (setsockopt(b->num, IPPROTO_IPV6, IPV6_RECVPKTINFO,
529 &enable, sizeof(enable)) < 0)
530 return 0;
531
532 return 1;
533# endif
534 }
535# endif
536
537 return 0;
538}
539# endif
540
36d16f8e 541static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
0f113f3e
MC
542{
543 long ret = 1;
544 int *ip;
0f113f3e
MC
545 bio_dgram_data *data = NULL;
546 int sockopt_val = 0;
b5292f7b 547 int d_errno;
0f113f3e
MC
548# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
549 socklen_t sockopt_len; /* assume that system supporting IP_MTU is
550 * modern enough to define socklen_t */
551 socklen_t addr_len;
d858c876 552 BIO_ADDR addr;
0f113f3e 553# endif
36d16f8e 554
0f113f3e
MC
555 data = (bio_dgram_data *)b->ptr;
556
557 switch (cmd) {
558 case BIO_CTRL_RESET:
559 num = 0;
0f113f3e
MC
560 ret = 0;
561 break;
0f113f3e
MC
562 case BIO_CTRL_INFO:
563 ret = 0;
564 break;
565 case BIO_C_SET_FD:
566 dgram_clear(b);
567 b->num = *((int *)ptr);
568 b->shutdown = (int)num;
569 b->init = 1;
664e096c
HL
570 dgram_update_local_addr(b);
571# if defined(SUPPORT_LOCAL_ADDR)
572 if (data->local_addr_enabled) {
573 if (enable_local_addr(b, 1) < 1)
574 data->local_addr_enabled = 0;
575 }
576# endif
0f113f3e
MC
577 break;
578 case BIO_C_GET_FD:
579 if (b->init) {
580 ip = (int *)ptr;
581 if (ip != NULL)
582 *ip = b->num;
583 ret = b->num;
584 } else
585 ret = -1;
586 break;
587 case BIO_CTRL_GET_CLOSE:
588 ret = b->shutdown;
589 break;
590 case BIO_CTRL_SET_CLOSE:
591 b->shutdown = (int)num;
592 break;
593 case BIO_CTRL_PENDING:
594 case BIO_CTRL_WPENDING:
595 ret = 0;
596 break;
597 case BIO_CTRL_DUP:
598 case BIO_CTRL_FLUSH:
599 ret = 1;
600 break;
601 case BIO_CTRL_DGRAM_CONNECT:
d858c876 602 BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
0f113f3e
MC
603 break;
604 /* (Linux)kernel sets DF bit on outgoing IP packets */
605 case BIO_CTRL_DGRAM_MTU_DISCOVER:
606# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
607 addr_len = (socklen_t) sizeof(addr);
664e096c 608 BIO_ADDR_clear(&addr);
0f113f3e
MC
609 if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
610 ret = 0;
611 break;
612 }
613 switch (addr.sa.sa_family) {
614 case AF_INET:
615 sockopt_val = IP_PMTUDISC_DO;
616 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
617 &sockopt_val, sizeof(sockopt_val))) < 0)
618 perror("setsockopt");
619 break;
620# if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
621 case AF_INET6:
622 sockopt_val = IPV6_PMTUDISC_DO;
623 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
624 &sockopt_val, sizeof(sockopt_val))) < 0)
625 perror("setsockopt");
626 break;
627# endif
628 default:
629 ret = -1;
630 break;
631 }
632# else
633 ret = -1;
634# endif
635 break;
636 case BIO_CTRL_DGRAM_QUERY_MTU:
637# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
638 addr_len = (socklen_t) sizeof(addr);
664e096c 639 BIO_ADDR_clear(&addr);
0f113f3e
MC
640 if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
641 ret = 0;
642 break;
643 }
644 sockopt_len = sizeof(sockopt_val);
645 switch (addr.sa.sa_family) {
646 case AF_INET:
647 if ((ret =
648 getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
649 &sockopt_len)) < 0 || sockopt_val < 0) {
650 ret = 0;
651 } else {
652 /*
653 * we assume that the transport protocol is UDP and no IP
654 * options are used.
655 */
656 data->mtu = sockopt_val - 8 - 20;
657 ret = data->mtu;
658 }
659 break;
660# if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
661 case AF_INET6:
662 if ((ret =
663 getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
664 (void *)&sockopt_val, &sockopt_len)) < 0
665 || sockopt_val < 0) {
666 ret = 0;
667 } else {
668 /*
669 * we assume that the transport protocol is UDP and no IPV6
670 * options are used.
671 */
672 data->mtu = sockopt_val - 8 - 40;
673 ret = data->mtu;
674 }
675 break;
676# endif
677 default:
678 ret = 0;
679 break;
680 }
681# else
682 ret = 0;
683# endif
684 break;
685 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
686 ret = -dgram_get_mtu_overhead(data);
d858c876 687 switch (BIO_ADDR_family(&data->peer)) {
0f113f3e
MC
688 case AF_INET:
689 ret += 576;
690 break;
691# if OPENSSL_USE_IPV6
692 case AF_INET6:
d858c876 693 {
0f113f3e 694# ifdef IN6_IS_ADDR_V4MAPPED
d858c876
RL
695 struct in6_addr tmp_addr;
696 if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
697 && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
698 ret += 576;
699 else
0f113f3e 700# endif
d858c876
RL
701 ret += 1280;
702 }
0f113f3e
MC
703 break;
704# endif
705 default:
706 ret += 576;
707 break;
708 }
709 break;
710 case BIO_CTRL_DGRAM_GET_MTU:
711 return data->mtu;
0f113f3e
MC
712 case BIO_CTRL_DGRAM_SET_MTU:
713 data->mtu = num;
714 ret = num;
715 break;
716 case BIO_CTRL_DGRAM_SET_CONNECTED:
d858c876 717 if (ptr != NULL) {
0f113f3e 718 data->connected = 1;
d858c876 719 BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
0f113f3e
MC
720 } else {
721 data->connected = 0;
664e096c 722 BIO_ADDR_clear(&data->peer);
0f113f3e
MC
723 }
724 break;
725 case BIO_CTRL_DGRAM_GET_PEER:
d858c876
RL
726 ret = BIO_ADDR_sockaddr_size(&data->peer);
727 /* FIXME: if num < ret, we will only return part of an address.
728 That should bee an error, no? */
0f113f3e
MC
729 if (num == 0 || num > ret)
730 num = ret;
731 memcpy(ptr, &data->peer, (ret = num));
732 break;
733 case BIO_CTRL_DGRAM_SET_PEER:
d858c876 734 BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
0f113f3e
MC
735 break;
736 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
737 memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
738 break;
739# if defined(SO_RCVTIMEO)
740 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
741# ifdef OPENSSL_SYS_WINDOWS
742 {
743 struct timeval *tv = (struct timeval *)ptr;
744 int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
745 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
746 (void *)&timeout, sizeof(timeout)) < 0) {
747 perror("setsockopt");
748 ret = -1;
749 }
750 }
751# else
752 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
753 sizeof(struct timeval)) < 0) {
754 perror("setsockopt");
755 ret = -1;
756 }
757# endif
758 break;
759 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
760 {
0f113f3e 761# ifdef OPENSSL_SYS_WINDOWS
8e949b35 762 int sz = 0;
0f113f3e
MC
763 int timeout;
764 struct timeval *tv = (struct timeval *)ptr;
765
8e949b35 766 sz = sizeof(timeout);
0f113f3e 767 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
8e949b35 768 (void *)&timeout, &sz) < 0) {
0f113f3e
MC
769 perror("getsockopt");
770 ret = -1;
771 } else {
772 tv->tv_sec = timeout / 1000;
773 tv->tv_usec = (timeout % 1000) * 1000;
774 ret = sizeof(*tv);
775 }
776# else
8e949b35 777 socklen_t sz = sizeof(struct timeval);
0f113f3e 778 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
8e949b35 779 ptr, &sz) < 0) {
0f113f3e
MC
780 perror("getsockopt");
781 ret = -1;
8e949b35
TK
782 } else {
783 OPENSSL_assert(sz <= sizeof(struct timeval));
784 ret = (int)sz;
785 }
0f113f3e
MC
786# endif
787 }
788 break;
789# endif
790# if defined(SO_SNDTIMEO)
791 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
792# ifdef OPENSSL_SYS_WINDOWS
793 {
794 struct timeval *tv = (struct timeval *)ptr;
795 int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
796 if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
797 (void *)&timeout, sizeof(timeout)) < 0) {
798 perror("setsockopt");
799 ret = -1;
800 }
801 }
802# else
803 if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
804 sizeof(struct timeval)) < 0) {
805 perror("setsockopt");
806 ret = -1;
807 }
808# endif
809 break;
810 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
811 {
0f113f3e 812# ifdef OPENSSL_SYS_WINDOWS
8e949b35 813 int sz = 0;
0f113f3e
MC
814 int timeout;
815 struct timeval *tv = (struct timeval *)ptr;
816
8e949b35 817 sz = sizeof(timeout);
0f113f3e 818 if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
8e949b35 819 (void *)&timeout, &sz) < 0) {
0f113f3e
MC
820 perror("getsockopt");
821 ret = -1;
822 } else {
823 tv->tv_sec = timeout / 1000;
824 tv->tv_usec = (timeout % 1000) * 1000;
825 ret = sizeof(*tv);
826 }
827# else
8e949b35 828 socklen_t sz = sizeof(struct timeval);
0f113f3e 829 if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
8e949b35 830 ptr, &sz) < 0) {
0f113f3e
MC
831 perror("getsockopt");
832 ret = -1;
8e949b35
TK
833 } else {
834 OPENSSL_assert(sz <= sizeof(struct timeval));
835 ret = (int)sz;
836 }
0f113f3e
MC
837# endif
838 }
839 break;
840# endif
841 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
842 /* fall-through */
843 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
844# ifdef OPENSSL_SYS_WINDOWS
b5292f7b 845 d_errno = (data->_errno == WSAETIMEDOUT);
0f113f3e 846# else
b5292f7b 847 d_errno = (data->_errno == EAGAIN);
0f113f3e 848# endif
b5292f7b 849 if (d_errno) {
0f113f3e
MC
850 ret = 1;
851 data->_errno = 0;
852 } else
853 ret = 0;
854 break;
855# ifdef EMSGSIZE
856 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
857 if (data->_errno == EMSGSIZE) {
858 ret = 1;
859 data->_errno = 0;
860 } else
861 ret = 0;
862 break;
863# endif
864 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
865 sockopt_val = num ? 1 : 0;
866
867 switch (data->peer.sa.sa_family) {
868 case AF_INET:
869# if defined(IP_DONTFRAG)
870 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
871 &sockopt_val, sizeof(sockopt_val))) < 0) {
872 perror("setsockopt");
873 ret = -1;
874 }
133dce44 875# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
0f113f3e
MC
876 if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
877 (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
878 &sockopt_val, sizeof(sockopt_val))) < 0) {
879 perror("setsockopt");
880 ret = -1;
881 }
882# elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
883 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
884 (const char *)&sockopt_val,
885 sizeof(sockopt_val))) < 0) {
886 perror("setsockopt");
887 ret = -1;
888 }
889# else
890 ret = -1;
891# endif
892 break;
893# if OPENSSL_USE_IPV6
894 case AF_INET6:
895# if defined(IPV6_DONTFRAG)
896 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
897 (const void *)&sockopt_val,
898 sizeof(sockopt_val))) < 0) {
899 perror("setsockopt");
900 ret = -1;
901 }
902# elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
903 if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
904 (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
905 &sockopt_val, sizeof(sockopt_val))) < 0) {
906 perror("setsockopt");
907 ret = -1;
908 }
909# else
910 ret = -1;
911# endif
912 break;
913# endif
914 default:
915 ret = -1;
916 break;
917 }
918 break;
919 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
920 ret = dgram_get_mtu_overhead(data);
921 break;
99240875
MC
922
923 /*
924 * BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE is used here for compatibility
925 * reasons. When BIO_CTRL_DGRAM_SET_PEEK_MODE was first defined its value
926 * was incorrectly clashing with BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE. The
927 * value has been updated to a non-clashing value. However to preserve
c2969ff6 928 * binary compatibility we now respond to both the old value and the new one
99240875
MC
929 */
930 case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
01b7851a
MC
931 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
932 data->peekmode = (unsigned int)num;
933 break;
664e096c
HL
934
935 case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP:
936# if defined(SUPPORT_LOCAL_ADDR)
937 ret = 1;
938# else
939 ret = 0;
940# endif
941 break;
942
943 case BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE:
944# if defined(SUPPORT_LOCAL_ADDR)
945 num = num > 0;
946 if (num != data->local_addr_enabled) {
947 if (enable_local_addr(b, num) < 1) {
948 ret = 0;
949 break;
950 }
951
952 data->local_addr_enabled = (char)num;
953 }
954# else
955 ret = 0;
956# endif
957 break;
958
959 case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE:
960 *(int *)ptr = data->local_addr_enabled;
961 break;
962
0f113f3e
MC
963 default:
964 ret = 0;
965 break;
966 }
26a7d938 967 return ret;
0f113f3e 968}
36d16f8e
BL
969
970static int dgram_puts(BIO *bp, const char *str)
0f113f3e
MC
971{
972 int n, ret;
36d16f8e 973
0f113f3e
MC
974 n = strlen(str);
975 ret = dgram_write(bp, str, n);
26a7d938 976 return ret;
0f113f3e 977}
36d16f8e 978
664e096c
HL
979# if M_METHOD == M_METHOD_WSARECVMSG
980static void translate_msg_win(BIO *b, WSAMSG *mh, WSABUF *iov,
981 unsigned char *control, BIO_MSG *msg)
982{
983 iov->len = msg->data_len;
984 iov->buf = msg->data;
985
986 /* Windows requires namelen to be set exactly */
987 mh->name = msg->peer != NULL ? &msg->peer->sa : NULL;
988 if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET)
989 mh->namelen = sizeof(struct sockaddr_in);
990# if OPENSSL_USE_IPV6
991 else if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET6)
992 mh->namelen = sizeof(struct sockaddr_in6);
993# endif
994 else
995 mh->namelen = 0;
996
997 /*
998 * When local address reception (IP_PKTINFO, etc.) is enabled, on Windows
999 * this causes WSARecvMsg to fail if the control buffer is too small to hold
1000 * the structure, or if no control buffer is passed. So we need to give it
1001 * the control buffer even if we aren't actually going to examine the
1002 * result.
1003 */
1004 mh->lpBuffers = iov;
1005 mh->dwBufferCount = 1;
1006 mh->Control.len = BIO_CMSG_ALLOC_LEN;
1007 mh->Control.buf = control;
1008 mh->dwFlags = 0;
1009}
1010# endif
1011
1012# if M_METHOD == M_METHOD_RECVMMSG || M_METHOD == M_METHOD_RECVMSG
1013/* Translates a BIO_MSG to a msghdr and iovec. */
1014static void translate_msg(BIO *b, struct msghdr *mh, struct iovec *iov,
1015 unsigned char *control, BIO_MSG *msg)
1016{
1017 iov->iov_base = msg->data;
1018 iov->iov_len = msg->data_len;
1019
1020 /* macOS requires msg_namelen be 0 if msg_name is NULL */
1021 mh->msg_name = msg->peer != NULL ? &msg->peer->sa : NULL;
1022 if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET)
1023 mh->msg_namelen = sizeof(struct sockaddr_in);
1024# if OPENSSL_USE_IPV6
1025 else if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET6)
1026 mh->msg_namelen = sizeof(struct sockaddr_in6);
1027# endif
1028 else
1029 mh->msg_namelen = 0;
1030
1031 mh->msg_iov = iov;
1032 mh->msg_iovlen = 1;
1033 mh->msg_control = msg->local != NULL ? control : NULL;
1034 mh->msg_controllen = msg->local != NULL ? BIO_CMSG_ALLOC_LEN : 0;
1035 mh->msg_flags = 0;
1036}
1037# endif
1038
1039# if M_METHOD == M_METHOD_RECVMMSG || M_METHOD == M_METHOD_RECVMSG || M_METHOD == M_METHOD_WSARECVMSG
1040/* Extracts destination address from the control buffer. */
1041static int extract_local(BIO *b, MSGHDR_TYPE *mh, BIO_ADDR *local) {
1042# if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IPV6_PKTINFO)
1043 CMSGHDR_TYPE *cmsg;
1044 int af = dgram_get_sock_family(b);
1045
1046 for (cmsg = BIO_CMSG_FIRSTHDR(mh); cmsg != NULL;
1047 cmsg = BIO_CMSG_NXTHDR(mh, cmsg)) {
1048 if (af == AF_INET) {
1049 if (cmsg->cmsg_level != IPPROTO_IP)
1050 continue;
1051
1052# if defined(IP_PKTINFO)
1053 if (cmsg->cmsg_type != IP_PKTINFO)
1054 continue;
1055
1056 local->s_in.sin_addr =
1057 ((struct in_pktinfo *)BIO_CMSG_DATA(cmsg))->ipi_addr;
1058
1059# elif defined(IP_RECVDSTADDR)
1060 if (cmsg->cmsg_type != IP_RECVDSTADDR)
1061 continue;
1062
1063 local->s_in.sin_addr = *(struct in_addr *)BIO_CMSG_DATA(cmsg);
1064# endif
1065
1066# if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR)
1067 {
1068 bio_dgram_data *data = b->ptr;
1069
1070 local->s_in.sin_family = AF_INET;
1071 local->s_in.sin_port = data->local_addr.s_in.sin_port;
1072 }
1073 return 1;
1074# endif
1075 }
1076# if OPENSSL_USE_IPV6
1077 else if (af == AF_INET6) {
1078 if (cmsg->cmsg_level != IPPROTO_IPV6)
1079 continue;
1080
1081# if defined(IPV6_RECVPKTINFO)
1082 if (cmsg->cmsg_type != IPV6_PKTINFO)
1083 continue;
1084
1085 {
1086 bio_dgram_data *data = b->ptr;
1087
1088 local->s_in6.sin6_addr =
1089 ((struct in6_pktinfo *)BIO_CMSG_DATA(cmsg))->ipi6_addr;
1090 local->s_in6.sin6_family = AF_INET6;
1091 local->s_in6.sin6_port = data->local_addr.s_in6.sin6_port;
1092 local->s_in6.sin6_scope_id =
1093 data->local_addr.s_in6.sin6_scope_id;
1094 local->s_in6.sin6_flowinfo = 0;
1095 }
1096 return 1;
1097# endif
1098 }
1099# endif
1100 }
1101# endif
1102
1103 return 0;
1104}
1105
1106static int pack_local(BIO *b, MSGHDR_TYPE *mh, const BIO_ADDR *local) {
1107 int af = dgram_get_sock_family(b);
1108
1109 if (af == AF_INET) {
1110# if defined(IP_PKTINFO)
1111 CMSGHDR_TYPE *cmsg;
1112 struct in_pktinfo *info;
1113 bio_dgram_data *data = b->ptr;
1114
1115# if defined(OPENSSL_SYS_WINDOWS)
1116 cmsg = (CMSGHDR_TYPE *)mh->Control.buf;
1117# else
1118 cmsg = (CMSGHDR_TYPE *)mh->msg_control;
1119# endif
1120
1121 cmsg->cmsg_len = BIO_CMSG_LEN(sizeof(struct in_pktinfo));
1122 cmsg->cmsg_level = IPPROTO_IP;
1123 cmsg->cmsg_type = IP_PKTINFO;
1124
1125 info = (struct in_pktinfo *)BIO_CMSG_DATA(cmsg);
1126 info->ipi_spec_dst = local->s_in.sin_addr;
1127 info->ipi_addr.s_addr = 0;
1128 info->ipi_ifindex = 0;
1129
1130 /*
1131 * We cannot override source port using this API, therefore
1132 * ensure the application specified a source port of 0
1133 * or the one we are bound to. (Better to error than silently
1134 * ignore this.)
1135 */
1136 if (local->s_in.sin_port != 0
1137 && data->local_addr.s_in.sin_port != local->s_in.sin_port) {
1138 ERR_raise(ERR_LIB_BIO, BIO_R_PORT_MISMATCH);
1139 return 0;
1140 }
1141
1142# if defined(OPENSSL_SYS_WINDOWS)
1143 mh->Control.len = BIO_CMSG_SPACE(sizeof(struct in_pktinfo));
1144# else
1145 mh->msg_controllen = BIO_CMSG_SPACE(sizeof(struct in_pktinfo));
1146# endif
1147 return 1;
1148
1149# elif defined(IP_SENDSRCADDR)
1150 {
1151 struct cmsghdr *cmsg;
1152 struct in_addr *info;
1153
1154 cmsg = (struct cmsghdr *)mh->msg_control;
1155 cmsg->cmsg_len = BIO_CMSG_LEN(sizeof(struct in_addr));
1156 cmsg->cmsg_level = IPPROTO_IP;
1157 cmsg->cmsg_type = IP_SENDSRCADDR;
1158
1159 info = (struct in_addr *)BIO_CMSG_DATA(cmsg);
1160 *info = local->s_in.sin_addr;
1161 }
1162
1163 /* See comment above. */
1164 if (local->s_in.sin_port != 0
1165 && data->local_addr.s_in.sin_port != local->s_in.sin_port) {
1166 ERR_raise(ERR_LIB_BIO, BIO_R_PORT_MISMATCH);
1167 return 0;
1168 }
1169
1170 mh->msg_controllen = BIO_CMSG_SPACE(sizeof(struct in_addr));
1171 return 1;
1172# endif
1173 }
1174# if OPENSSL_USE_IPV6
1175 else if (af == AF_INET6) {
1176# if defined(IPV6_PKTINFO)
1177 CMSGHDR_TYPE *cmsg;
1178 struct in6_pktinfo *info;
1179 bio_dgram_data *data = b->ptr;
1180
1181# if defined(OPENSSL_SYS_WINDOWS)
1182 cmsg = (CMSGHDR_TYPE *)mh->Control.buf;
1183# else
1184 cmsg = (CMSGHDR_TYPE *)mh->msg_control;
1185# endif
1186 cmsg->cmsg_len = BIO_CMSG_LEN(sizeof(struct in6_pktinfo));
1187 cmsg->cmsg_level = IPPROTO_IPV6;
1188 cmsg->cmsg_type = IPV6_PKTINFO;
1189
1190 info = (struct in6_pktinfo *)BIO_CMSG_DATA(cmsg);
1191 info->ipi6_addr = local->s_in6.sin6_addr;
1192 info->ipi6_ifindex = 0;
1193
1194 /*
1195 * See comment above, but also applies to the other fields
1196 * in sockaddr_in6.
1197 */
1198 if (local->s_in6.sin6_port != 0
1199 && data->local_addr.s_in6.sin6_port != local->s_in6.sin6_port) {
1200 ERR_raise(ERR_LIB_BIO, BIO_R_PORT_MISMATCH);
1201 return 0;
1202 }
1203
1204 if (local->s_in6.sin6_scope_id != 0
1205 && data->local_addr.s_in6.sin6_scope_id != local->s_in6.sin6_scope_id) {
1206 ERR_raise(ERR_LIB_BIO, BIO_R_PORT_MISMATCH);
1207 return 0;
1208 }
1209
1210# if defined(OPENSSL_SYS_WINDOWS)
1211 mh->Control.len = BIO_CMSG_SPACE(sizeof(struct in6_pktinfo));
1212# else
1213 mh->msg_controllen = BIO_CMSG_SPACE(sizeof(struct in6_pktinfo));
1214# endif
1215 return 1;
1216# endif
1217 }
1218# endif
1219
1220 return 0;
1221}
1222# endif
1223
1224/*
1225 * Converts flags passed to BIO_sendmmsg or BIO_recvmmsg to syscall flags. You
1226 * should mask out any system flags returned by this function you cannot support
1227 * in a particular circumstance. Currently no flags are defined.
1228 */
1229# if M_METHOD != M_METHOD_NONE
1230static int translate_flags(uint64_t flags) {
1231 return 0;
1232}
1233# endif
1234
1235static int dgram_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride,
1236 size_t num_msg, uint64_t flags, size_t *num_processed)
1237{
1238# if M_METHOD != M_METHOD_NONE && M_METHOD != M_METHOD_RECVMSG
1239 int ret;
1240# endif
1241# if M_METHOD == M_METHOD_RECVMMSG
1242# define BIO_MAX_MSGS_PER_CALL 64
1243 int sysflags;
1244 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
1245 size_t i;
1246 struct mmsghdr mh[BIO_MAX_MSGS_PER_CALL];
1247 struct iovec iov[BIO_MAX_MSGS_PER_CALL];
1248 unsigned char control[BIO_MAX_MSGS_PER_CALL][BIO_CMSG_ALLOC_LEN];
1249 int have_local_enabled = data->local_addr_enabled;
1250# elif M_METHOD == M_METHOD_RECVMSG
1251 int sysflags;
1252 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
1253 ossl_ssize_t l;
1254 struct msghdr mh;
1255 struct iovec iov;
1256 unsigned char control[BIO_CMSG_ALLOC_LEN];
1257 int have_local_enabled = data->local_addr_enabled;
1258# elif M_METHOD == M_METHOD_WSARECVMSG
1259 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
1260 int have_local_enabled = data->local_addr_enabled;
1261 WSAMSG wmsg;
1262 WSABUF wbuf;
1263 DWORD num_bytes_sent = 0;
1264 unsigned char control[BIO_CMSG_ALLOC_LEN];
1265# endif
1266# if M_METHOD == M_METHOD_RECVFROM || M_METHOD == M_METHOD_WSARECVMSG
1267 int sysflags;
1268# endif
1269
1270 if (num_msg == 0) {
1271 *num_processed = 0;
1272 return 1;
1273 }
1274
1275 if (num_msg > OSSL_SSIZE_MAX)
1276 num_msg = OSSL_SSIZE_MAX;
1277
1278# if M_METHOD != M_METHOD_NONE
1279 sysflags = translate_flags(flags);
1280# endif
1281
1282# if M_METHOD == M_METHOD_RECVMMSG
1283 /*
1284 * In the sendmmsg/recvmmsg case, we need to allocate our translated struct
1285 * msghdr and struct iovec on the stack to support multithreaded use. Thus
1286 * we place a fixed limit on the number of messages per call, in the
1287 * expectation that we will be called again if there were more messages to
1288 * be sent.
1289 */
1290 if (num_msg > BIO_MAX_MSGS_PER_CALL)
1291 num_msg = BIO_MAX_MSGS_PER_CALL;
1292
1293 for (i = 0; i < num_msg; ++i) {
1294 translate_msg(b, &mh[i].msg_hdr, &iov[i],
1295 control[i], &BIO_MSG_N(msg, stride, i));
1296
1297 /* If local address was requested, it must have been enabled */
1298 if (BIO_MSG_N(msg, stride, i).local != NULL) {
1299 if (!have_local_enabled) {
1300 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1301 *num_processed = 0;
1302 return 0;
1303 }
1304
1305 if (pack_local(b, &mh[i].msg_hdr,
1306 BIO_MSG_N(msg, stride, i).local) < 1) {
1307 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1308 *num_processed = 0;
1309 return 0;
1310 }
1311 }
1312 }
1313
1314 /* Do the batch */
1315 ret = sendmmsg(b->num, mh, num_msg, sysflags);
1316 if (ret < 0) {
1317 ERR_raise(ERR_LIB_SYS, get_last_socket_error());
1318 *num_processed = 0;
1319 return 0;
1320 }
1321
1322 for (i = 0; i < (size_t)ret; ++i) {
1323 BIO_MSG_N(msg, stride, i).data_len = mh[i].msg_len;
1324 BIO_MSG_N(msg, stride, i).flags = 0;
1325 }
1326
1327 *num_processed = (size_t)ret;
1328 return 1;
1329
1330# elif M_METHOD == M_METHOD_RECVMSG
1331 /*
1332 * If sendmsg is available, use it.
1333 */
1334 translate_msg(b, &mh, &iov, control, msg);
1335
1336 if (msg->local != NULL) {
1337 if (!have_local_enabled) {
1338 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1339 *num_processed = 0;
1340 return 0;
1341 }
1342
1343 if (pack_local(b, &mh, msg->local) < 1) {
1344 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1345 *num_processed = 0;
1346 return 0;
1347 }
1348 }
1349
1350 l = sendmsg(b->num, &mh, sysflags);
1351 if (l < 0) {
1352 ERR_raise(ERR_LIB_SYS, get_last_socket_error());
1353 *num_processed = 0;
1354 return 0;
1355 }
1356
1357 msg->data_len = (size_t)l;
1358 msg->flags = 0;
1359 *num_processed = 1;
1360 return 1;
1361
1362# elif M_METHOD == M_METHOD_WSARECVMSG || M_METHOD == M_METHOD_RECVFROM
1363# if M_METHOD == M_METHOD_WSARECVMSG
1364 if (bio_WSASendMsg != NULL) {
1365 /* WSASendMsg-based implementation for Windows. */
1366 translate_msg_win(b, &wmsg, &wbuf, control, msg);
1367
1368 if (msg[0].local != NULL) {
1369 if (!have_local_enabled) {
1370 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1371 *num_processed = 0;
1372 return 0;
1373 }
1374
1375 if (pack_local(b, &wmsg, msg[0].local) < 1) {
1376 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1377 *num_processed = 0;
1378 return 0;
1379 }
1380 }
1381
1382 ret = WSASendMsg((SOCKET)b->num, &wmsg, 0, &num_bytes_sent, NULL, NULL);
1383 if (ret < 0) {
1384 ERR_raise(ERR_LIB_SYS, get_last_socket_error());
1385 *num_processed = 0;
1386 return 0;
1387 }
1388
1389 msg[0].data_len = num_bytes_sent;
1390 msg[0].flags = 0;
1391 *num_processed = 1;
1392 return 1;
1393 }
1394# endif
1395
1396 /*
1397 * Fallback to sendto and send a single message.
1398 */
1399 if (msg[0].local != NULL) {
1400 /*
1401 * We cannot set the local address if using sendto
1402 * so fail in this case
1403 */
1404 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1405 *num_processed = 0;
1406 return 0;
1407 }
1408
1409 ret = sendto(b->num, msg[0].data,
1410# if defined(OPENSSL_SYS_WINDOWS)
1411 (int)msg[0].data_len,
1412# else
1413 msg[0].data_len,
1414# endif
1415 sysflags,
1416 msg[0].peer != NULL ? &msg[0].peer->sa : NULL,
1417 msg[0].peer != NULL ? sizeof(*msg[0].peer) : 0);
1418 if (ret <= 0) {
1419 ERR_raise(ERR_LIB_SYS, get_last_socket_error());
1420 *num_processed = 0;
1421 return 0;
1422 }
1423
1424 msg[0].data_len = ret;
1425 msg[0].flags = 0;
1426 *num_processed = 1;
1427 return 1;
1428
1429# else
1430 ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
1431 *num_processed = 0;
1432 return 0;
1433# endif
1434}
1435
1436static int dgram_recvmmsg(BIO *b, BIO_MSG *msg,
1437 size_t stride, size_t num_msg,
1438 uint64_t flags, size_t *num_processed)
1439{
1440# if M_METHOD != M_METHOD_NONE && M_METHOD != M_METHOD_RECVMSG
1441 int ret;
1442# endif
1443# if M_METHOD == M_METHOD_RECVMMSG
1444 int sysflags;
1445 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
1446 size_t i;
1447 struct mmsghdr mh[BIO_MAX_MSGS_PER_CALL];
1448 struct iovec iov[BIO_MAX_MSGS_PER_CALL];
1449 unsigned char control[BIO_MAX_MSGS_PER_CALL][BIO_CMSG_ALLOC_LEN];
1450 int have_local_enabled = data->local_addr_enabled;
1451# elif M_METHOD == M_METHOD_RECVMSG
1452 int sysflags;
1453 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
1454 ossl_ssize_t l;
1455 struct msghdr mh;
1456 struct iovec iov;
1457 unsigned char control[BIO_CMSG_ALLOC_LEN];
1458 int have_local_enabled = data->local_addr_enabled;
1459# elif M_METHOD == M_METHOD_WSARECVMSG
1460 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
1461 int have_local_enabled = data->local_addr_enabled;
1462 WSAMSG wmsg;
1463 WSABUF wbuf;
1464 DWORD num_bytes_received = 0;
1465 unsigned char control[BIO_CMSG_ALLOC_LEN];
1466# endif
1467# if M_METHOD == M_METHOD_RECVFROM || M_METHOD == M_METHOD_WSARECVMSG
1468 int sysflags;
1469 socklen_t slen;
1470# endif
1471
1472 if (num_msg == 0) {
1473 *num_processed = 0;
1474 return 1;
1475 }
1476
1477 if (num_msg > OSSL_SSIZE_MAX)
1478 num_msg = OSSL_SSIZE_MAX;
1479
1480# if M_METHOD != M_METHOD_NONE
1481 sysflags = translate_flags(flags);
1482# endif
1483
1484# if M_METHOD == M_METHOD_RECVMMSG
1485 /*
1486 * In the sendmmsg/recvmmsg case, we need to allocate our translated struct
1487 * msghdr and struct iovec on the stack to support multithreaded use. Thus
1488 * we place a fixed limit on the number of messages per call, in the
1489 * expectation that we will be called again if there were more messages to
1490 * be sent.
1491 */
1492 if (num_msg > BIO_MAX_MSGS_PER_CALL)
1493 num_msg = BIO_MAX_MSGS_PER_CALL;
1494
1495 for (i = 0; i < num_msg; ++i) {
1496 translate_msg(b, &mh[i].msg_hdr, &iov[i],
1497 control[i], &BIO_MSG_N(msg, stride, i));
1498
1499 /* If local address was requested, it must have been enabled */
1500 if (BIO_MSG_N(msg, stride, i).local != NULL && !have_local_enabled) {
1501 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1502 *num_processed = 0;
1503 return 0;
1504 }
1505 }
1506
1507 /* Do the batch */
1508 ret = recvmmsg(b->num, mh, num_msg, sysflags, NULL);
1509 if (ret < 0) {
1510 ERR_raise(ERR_LIB_SYS, get_last_socket_error());
1511 *num_processed = 0;
1512 return 0;
1513 }
1514
1515 for (i = 0; i < (size_t)ret; ++i) {
1516 BIO_MSG_N(msg, stride, i).data_len = mh[i].msg_len;
1517 BIO_MSG_N(msg, stride, i).flags = 0;
1518 /*
1519 * *(msg->peer) will have been filled in by recvmmsg;
1520 * for msg->local we parse the control data returned
1521 */
1522 if (BIO_MSG_N(msg, stride, i).local != NULL)
1523 if (extract_local(b, &mh[i].msg_hdr,
1524 BIO_MSG_N(msg, stride, i).local) < 1) {
1525 if (i > 0) {
1526 *num_processed = i;
1527 return 1;
1528 } else {
1529 *num_processed = 0;
1530 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1531 return 0;
1532 }
1533 }
1534 }
1535
1536 *num_processed = (size_t)ret;
1537 return 1;
1538
1539# elif M_METHOD == M_METHOD_RECVMSG
1540 /*
1541 * If recvmsg is available, use it.
1542 */
1543 translate_msg(b, &mh, &iov, control, msg);
1544
1545 /* If local address was requested, it must have been enabled */
1546 if (msg->local != NULL && !have_local_enabled) {
1547 /*
1548 * If we have done at least one message, we must return the
1549 * count; if we haven't done any, we can give an error code
1550 */
1551 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1552 *num_processed = 0;
1553 return 0;
1554 }
1555
1556 l = recvmsg(b->num, &mh, sysflags);
1557 if (l < 0) {
1558 ERR_raise(ERR_LIB_SYS, get_last_socket_error());
1559 *num_processed = 0;
1560 return 0;
1561 }
1562
1563 msg->data_len = (size_t)l;
1564 msg->flags = 0;
1565
1566 if (msg->local != NULL)
1567 if (extract_local(b, &mh, msg->local) < 1) {
1568 /*
1569 * OS X exhibits odd behaviour where it appears that if a packet is
1570 * sent before the receiving interface enables IP_PKTINFO, it will
1571 * sometimes not have any control data returned even if the
1572 * receiving interface enables IP_PKTINFO before calling recvmsg().
1573 * This appears to occur non-deterministically. Presumably, OS X
1574 * handles IP_PKTINFO at the time the packet is enqueued into a
1575 * socket's receive queue, rather than at the time recvmsg() is
1576 * called, unlike most other operating systems. Thus (if this
1577 * hypothesis is correct) there is a race between where IP_PKTINFO
1578 * is enabled by the process and when the kernel's network stack
1579 * queues the incoming message.
1580 *
1581 * We cannot return the local address if we do not have it, but this
1582 * is not a caller error either, so just return a zero address
1583 * structure.
1584 *
1585 * We enable this workaround for Apple only as it should not
1586 * be necessary otherwise.
1587 */
1588# if defined(__APPLE__)
1589 BIO_ADDR_clear(msg->local);
1590# else
1591 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1592 *num_processed = 0;
1593 return 0;
1594# endif
1595 }
1596
1597 *num_processed = 1;
1598 return 1;
1599
1600# elif M_METHOD == M_METHOD_RECVFROM || M_METHOD == M_METHOD_WSARECVMSG
1601# if M_METHOD == M_METHOD_WSARECVMSG
1602 if (bio_WSARecvMsg != NULL) {
1603 /* WSARecvMsg-based implementation for Windows. */
1604 translate_msg_win(b, &wmsg, &wbuf, control, msg);
1605
1606 /* If local address was requested, it must have been enabled */
1607 if (msg[0].local != NULL && !have_local_enabled) {
1608 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1609 *num_processed = 0;
1610 return 0;
1611 }
1612
1613 ret = WSARecvMsg((SOCKET)b->num, &wmsg, &num_bytes_received, NULL, NULL);
1614 if (ret < 0) {
1615 ERR_raise(ERR_LIB_SYS, get_last_socket_error());
1616 *num_processed = 0;
1617 return 0;
1618 }
1619
1620 msg[0].data_len = num_bytes_received;
1621 msg[0].flags = 0;
1622 if (msg[0].local != NULL)
1623 if (extract_local(b, &wmsg, msg[0].local) < 1)
1624 /*
1625 * On Windows, loopback is not a "proper" interface and it works
1626 * differently; packets are essentially short-circuited and
1627 * don't go through all of the normal processing. A consequence
1628 * of this is that packets sent from the local machine to the
1629 * local machine _will not have IP_PKTINFO_ even if the
1630 * IP_PKTINFO socket option is enabled. WSARecvMsg just sets
1631 * Control.len to 0 on returning.
1632 *
1633 * This applies regardless of whether the loopback address,
1634 * 127.0.0.1 is used, or a local interface address (e.g.
1635 * 192.168.1.1); in both cases IP_PKTINFO will not be present.
1636 *
1637 * We report this condition by setting the local BIO_ADDR's
1638 * family to 0.
1639 */
1640 BIO_ADDR_clear(msg[0].local);
1641
1642 *num_processed = 1;
1643 return 1;
1644 }
1645# endif
1646
1647 /*
1648 * Fallback to recvfrom and receive a single message.
1649 */
1650 if (msg[0].local != NULL) {
1651 /*
1652 * We cannot determine the local address if using recvfrom
1653 * so fail in this case
1654 */
1655 ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE);
1656 *num_processed = 0;
1657 return 0;
1658 }
1659
1660 slen = sizeof(*msg[0].peer);
1661 ret = recvfrom(b->num, msg[0].data,
1662# if defined(OPENSSL_SYS_WINDOWS)
1663 (int)msg[0].data_len,
1664# else
1665 msg[0].data_len,
1666# endif
1667 sysflags,
1668 msg[0].peer != NULL ? &msg[0].peer->sa : NULL,
1669 msg[0].peer != NULL ? &slen : NULL);
1670 if (ret <= 0) {
1671 ERR_raise(ERR_LIB_SYS, get_last_socket_error());
1672 return 0;
1673 }
1674
1675 msg[0].data_len = ret;
1676 msg[0].flags = 0;
1677 *num_processed = 1;
1678 return 1;
1679
1680# else
1681 ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
1682 *num_processed = 0;
1683 return 0;
1684# endif
1685}
1686
0f113f3e 1687# ifndef OPENSSL_NO_SCTP
04f6b0fd 1688const BIO_METHOD *BIO_s_datagram_sctp(void)
0f113f3e 1689{
26a7d938 1690 return &methods_dgramp_sctp;
0f113f3e 1691}
7e159e01
DSH
1692
1693BIO *BIO_new_dgram_sctp(int fd, int close_flag)
0f113f3e
MC
1694{
1695 BIO *bio;
1696 int ret, optval = 20000;
1697 int auth_data = 0, auth_forward = 0;
1698 unsigned char *p;
1699 struct sctp_authchunk auth;
1700 struct sctp_authchunks *authchunks;
1701 socklen_t sockopt_len;
1702# ifdef SCTP_AUTHENTICATION_EVENT
1703# ifdef SCTP_EVENT
1704 struct sctp_event event;
1705# else
1706 struct sctp_event_subscribe event;
1707# endif
1708# endif
7e159e01 1709
0f113f3e
MC
1710 bio = BIO_new(BIO_s_datagram_sctp());
1711 if (bio == NULL)
26a7d938 1712 return NULL;
0f113f3e
MC
1713 BIO_set_fd(bio, fd, close_flag);
1714
1715 /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
1716 auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
1717 ret =
1718 setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
1719 sizeof(struct sctp_authchunk));
1720 if (ret < 0) {
1721 BIO_vfree(bio);
a150f8e1
RL
1722 ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
1723 "Ensure SCTP AUTH chunks are enabled in kernel");
26a7d938 1724 return NULL;
0f113f3e
MC
1725 }
1726 auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
1727 ret =
1728 setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
1729 sizeof(struct sctp_authchunk));
1730 if (ret < 0) {
1731 BIO_vfree(bio);
a150f8e1
RL
1732 ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
1733 "Ensure SCTP AUTH chunks are enabled in kernel");
26a7d938 1734 return NULL;
0f113f3e
MC
1735 }
1736
1737 /*
1738 * Test if activation was successful. When using accept(), SCTP-AUTH has
1739 * to be activated for the listening socket already, otherwise the
dcf88c5b
MC
1740 * connected socket won't use it. Similarly with connect(): the socket
1741 * prior to connection must be activated for SCTP-AUTH
0f113f3e
MC
1742 */
1743 sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
b51bce94 1744 authchunks = OPENSSL_zalloc(sockopt_len);
90945fa3 1745 if (authchunks == NULL) {
918bb865 1746 BIO_vfree(bio);
26a7d938 1747 return NULL;
918bb865 1748 }
b51bce94 1749 ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
0f113f3e 1750 &sockopt_len);
0f113f3e
MC
1751 if (ret < 0) {
1752 OPENSSL_free(authchunks);
1753 BIO_vfree(bio);
26a7d938 1754 return NULL;
0f113f3e
MC
1755 }
1756
1757 for (p = (unsigned char *)authchunks->gauth_chunks;
1758 p < (unsigned char *)authchunks + sockopt_len;
1759 p += sizeof(uint8_t)) {
1760 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
1761 auth_data = 1;
1762 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
1763 auth_forward = 1;
1764 }
1765
1766 OPENSSL_free(authchunks);
1767
dcf88c5b
MC
1768 if (!auth_data || !auth_forward) {
1769 BIO_vfree(bio);
a150f8e1
RL
1770 ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
1771 "Ensure SCTP AUTH chunks are enabled on the "
1772 "underlying socket");
dcf88c5b
MC
1773 return NULL;
1774 }
0f113f3e
MC
1775
1776# ifdef SCTP_AUTHENTICATION_EVENT
1777# ifdef SCTP_EVENT
16f8d4eb 1778 memset(&event, 0, sizeof(event));
0f113f3e
MC
1779 event.se_assoc_id = 0;
1780 event.se_type = SCTP_AUTHENTICATION_EVENT;
1781 event.se_on = 1;
1782 ret =
1783 setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
1784 sizeof(struct sctp_event));
1785 if (ret < 0) {
1786 BIO_vfree(bio);
26a7d938 1787 return NULL;
0f113f3e
MC
1788 }
1789# else
1790 sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
1791 ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
1792 if (ret < 0) {
1793 BIO_vfree(bio);
26a7d938 1794 return NULL;
0f113f3e
MC
1795 }
1796
1797 event.sctp_authentication_event = 1;
1798
1799 ret =
1800 setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
1801 sizeof(struct sctp_event_subscribe));
1802 if (ret < 0) {
1803 BIO_vfree(bio);
26a7d938 1804 return NULL;
0f113f3e
MC
1805 }
1806# endif
1807# endif
7e159e01 1808
0f113f3e
MC
1809 /*
1810 * Disable partial delivery by setting the min size larger than the max
1811 * record size of 2^14 + 2048 + 13
1812 */
1813 ret =
1814 setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
1815 sizeof(optval));
1816 if (ret < 0) {
1817 BIO_vfree(bio);
26a7d938 1818 return NULL;
0f113f3e
MC
1819 }
1820
26a7d938 1821 return bio;
0f113f3e 1822}
7e159e01
DSH
1823
1824int BIO_dgram_is_sctp(BIO *bio)
0f113f3e
MC
1825{
1826 return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
1827}
7e159e01
DSH
1828
1829static int dgram_sctp_new(BIO *bi)
0f113f3e
MC
1830{
1831 bio_dgram_sctp_data *data = NULL;
1832
1833 bi->init = 0;
1834 bi->num = 0;
cdb10bae 1835 if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) {
9311d0c4 1836 ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
0f113f3e 1837 return 0;
cdb10bae 1838 }
0f113f3e
MC
1839# ifdef SCTP_PR_SCTP_NONE
1840 data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
1841# endif
7e159e01
DSH
1842 bi->ptr = data;
1843
0f113f3e 1844 bi->flags = 0;
208fb891 1845 return 1;
0f113f3e 1846}
7e159e01
DSH
1847
1848static int dgram_sctp_free(BIO *a)
0f113f3e
MC
1849{
1850 bio_dgram_sctp_data *data;
7e159e01 1851
0f113f3e 1852 if (a == NULL)
26a7d938 1853 return 0;
0f113f3e
MC
1854 if (!dgram_clear(a))
1855 return 0;
7e159e01 1856
0f113f3e 1857 data = (bio_dgram_sctp_data *) a->ptr;
41b3c9ce 1858 if (data != NULL)
0f113f3e 1859 OPENSSL_free(data);
0f113f3e 1860
208fb891 1861 return 1;
0f113f3e 1862}
7e159e01 1863
0f113f3e
MC
1864# ifdef SCTP_AUTHENTICATION_EVENT
1865void dgram_sctp_handle_auth_free_key_event(BIO *b,
1866 union sctp_notification *snp)
1867{
1868 int ret;
1869 struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
1870
1871 if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
1872 struct sctp_authkeyid authkeyid;
1873
1874 /* delete key */
1875 authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
1876 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1877 &authkeyid, sizeof(struct sctp_authkeyid));
1878 }
1879}
1880# endif
1881
1882static int dgram_sctp_read(BIO *b, char *out, int outl)
1883{
1884 int ret = 0, n = 0, i, optval;
1885 socklen_t optlen;
1886 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
0f113f3e
MC
1887 struct msghdr msg;
1888 struct iovec iov;
1889 struct cmsghdr *cmsg;
1890 char cmsgbuf[512];
1891
1892 if (out != NULL) {
1893 clear_socket_error();
1894
1895 do {
16f8d4eb 1896 memset(&data->rcvinfo, 0, sizeof(data->rcvinfo));
0f113f3e
MC
1897 iov.iov_base = out;
1898 iov.iov_len = outl;
1899 msg.msg_name = NULL;
1900 msg.msg_namelen = 0;
1901 msg.msg_iov = &iov;
1902 msg.msg_iovlen = 1;
1903 msg.msg_control = cmsgbuf;
1904 msg.msg_controllen = 512;
1905 msg.msg_flags = 0;
1906 n = recvmsg(b->num, &msg, 0);
1907
1908 if (n <= 0) {
1909 if (n < 0)
1910 ret = n;
1911 break;
1912 }
1913
1914 if (msg.msg_controllen > 0) {
1915 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
1916 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1917 if (cmsg->cmsg_level != IPPROTO_SCTP)
1918 continue;
1919# ifdef SCTP_RCVINFO
1920 if (cmsg->cmsg_type == SCTP_RCVINFO) {
1921 struct sctp_rcvinfo *rcvinfo;
1922
1923 rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
1924 data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
1925 data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
1926 data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
1927 data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
1928 data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
1929 data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
1930 data->rcvinfo.rcv_context = rcvinfo->rcv_context;
1931 }
1932# endif
1933# ifdef SCTP_SNDRCV
1934 if (cmsg->cmsg_type == SCTP_SNDRCV) {
1935 struct sctp_sndrcvinfo *sndrcvinfo;
1936
1937 sndrcvinfo =
1938 (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1939 data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
1940 data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
1941 data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
1942 data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
1943 data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
1944 data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
1945 data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
1946 }
1947# endif
1948 }
1949 }
1950
1951 if (msg.msg_flags & MSG_NOTIFICATION) {
287e1a7e
PS
1952 union sctp_notification snp;
1953
1954 memcpy(&snp, out, sizeof(snp));
1955 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
0f113f3e
MC
1956# ifdef SCTP_EVENT
1957 struct sctp_event event;
1958# else
1959 struct sctp_event_subscribe event;
1960 socklen_t eventsize;
1961# endif
0f113f3e
MC
1962
1963 /* disable sender dry event */
1964# ifdef SCTP_EVENT
16f8d4eb 1965 memset(&event, 0, sizeof(event));
0f113f3e
MC
1966 event.se_assoc_id = 0;
1967 event.se_type = SCTP_SENDER_DRY_EVENT;
1968 event.se_on = 0;
1969 i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1970 sizeof(struct sctp_event));
1971 if (i < 0) {
1972 ret = i;
1973 break;
1974 }
1975# else
1976 eventsize = sizeof(struct sctp_event_subscribe);
1977 i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1978 &eventsize);
1979 if (i < 0) {
1980 ret = i;
1981 break;
1982 }
1983
1984 event.sctp_sender_dry_event = 0;
1985
1986 i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1987 sizeof(struct sctp_event_subscribe));
1988 if (i < 0) {
1989 ret = i;
1990 break;
1991 }
1992# endif
1993 }
1994# ifdef SCTP_AUTHENTICATION_EVENT
287e1a7e
PS
1995 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1996 dgram_sctp_handle_auth_free_key_event(b, &snp);
0f113f3e
MC
1997# endif
1998
1999 if (data->handle_notifications != NULL)
2000 data->handle_notifications(b, data->notification_context,
2001 (void *)out);
2002
287e1a7e 2003 memset(&snp, 0, sizeof(snp));
0f113f3e 2004 memset(out, 0, outl);
287e1a7e 2005 } else {
0f113f3e 2006 ret += n;
287e1a7e 2007 }
0f113f3e
MC
2008 }
2009 while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
2010 && (ret < outl));
2011
2012 if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
2013 /* Partial message read, this should never happen! */
2014
2015 /*
2016 * The buffer was too small, this means the peer sent a message
2017 * that was larger than allowed.
2018 */
2019 if (ret == outl)
2020 return -1;
2021
2022 /*
2023 * Test if socket buffer can handle max record size (2^14 + 2048
2024 * + 13)
2025 */
2026 optlen = (socklen_t) sizeof(int);
2027 ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
2028 if (ret >= 0)
2029 OPENSSL_assert(optval >= 18445);
2030
2031 /*
2032 * Test if SCTP doesn't partially deliver below max record size
2033 * (2^14 + 2048 + 13)
2034 */
2035 optlen = (socklen_t) sizeof(int);
2036 ret =
2037 getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
2038 &optval, &optlen);
2039 if (ret >= 0)
2040 OPENSSL_assert(optval >= 18445);
2041
2042 /*
2043 * Partially delivered notification??? Probably a bug....
2044 */
2045 OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
2046
2047 /*
2048 * Everything seems ok till now, so it's most likely a message
2049 * dropped by PR-SCTP.
2050 */
2051 memset(out, 0, outl);
2052 BIO_set_retry_read(b);
2053 return -1;
2054 }
2055
2056 BIO_clear_retry_flags(b);
2057 if (ret < 0) {
2058 if (BIO_dgram_should_retry(ret)) {
2059 BIO_set_retry_read(b);
2060 data->_errno = get_last_socket_error();
2061 }
2062 }
2063
2064 /* Test if peer uses SCTP-AUTH before continuing */
2065 if (!data->peer_auth_tested) {
2066 int ii, auth_data = 0, auth_forward = 0;
2067 unsigned char *p;
2068 struct sctp_authchunks *authchunks;
2069
2070 optlen =
2071 (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
2072 authchunks = OPENSSL_malloc(optlen);
90945fa3 2073 if (authchunks == NULL) {
9311d0c4 2074 ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
918bb865
MC
2075 return -1;
2076 }
0f113f3e
MC
2077 memset(authchunks, 0, optlen);
2078 ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS,
2079 authchunks, &optlen);
2080
2081 if (ii >= 0)
2082 for (p = (unsigned char *)authchunks->gauth_chunks;
2083 p < (unsigned char *)authchunks + optlen;
2084 p += sizeof(uint8_t)) {
2085 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
2086 auth_data = 1;
2087 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
2088 auth_forward = 1;
2089 }
2090
2091 OPENSSL_free(authchunks);
2092
2093 if (!auth_data || !auth_forward) {
9311d0c4 2094 ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
0f113f3e
MC
2095 return -1;
2096 }
2097
2098 data->peer_auth_tested = 1;
2099 }
2100 }
26a7d938 2101 return ret;
0f113f3e 2102}
7e159e01 2103
7f098cb4
KR
2104/*
2105 * dgram_sctp_write - send message on SCTP socket
2106 * @b: BIO to write to
2107 * @in: data to send
2108 * @inl: amount of bytes in @in to send
2109 *
2110 * Returns -1 on error or the sent amount of bytes on success
2111 */
7e159e01 2112static int dgram_sctp_write(BIO *b, const char *in, int inl)
0f113f3e
MC
2113{
2114 int ret;
2115 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
2116 struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
2117 struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
2118 struct bio_dgram_sctp_sndinfo handshake_sinfo;
2119 struct iovec iov[1];
2120 struct msghdr msg;
2121 struct cmsghdr *cmsg;
2122# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
2123 char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
2124 CMSG_SPACE(sizeof(struct sctp_prinfo))];
2125 struct sctp_sndinfo *sndinfo;
2126 struct sctp_prinfo *prinfo;
2127# else
2128 char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
2129 struct sctp_sndrcvinfo *sndrcvinfo;
2130# endif
7e159e01 2131
0f113f3e 2132 clear_socket_error();
7e159e01 2133
0f113f3e
MC
2134 /*
2135 * If we're send anything else than application data, disable all user
2136 * parameters and flags.
2137 */
2138 if (in[0] != 23) {
16f8d4eb 2139 memset(&handshake_sinfo, 0, sizeof(handshake_sinfo));
0f113f3e
MC
2140# ifdef SCTP_SACK_IMMEDIATELY
2141 handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
2142# endif
2143 sinfo = &handshake_sinfo;
2144 }
2145
41b3c9ce 2146 /* We can only send a shutdown alert if the socket is dry */
03a1c850
KR
2147 if (data->save_shutdown) {
2148 ret = BIO_dgram_sctp_wait_for_dry(b);
41b3c9ce 2149 if (ret < 0)
918bb865 2150 return -1;
03a1c850 2151 if (ret == 0) {
41b3c9ce
MC
2152 BIO_clear_retry_flags(b);
2153 BIO_set_retry_write(b);
2154 return -1;
03a1c850 2155 }
0f113f3e
MC
2156 }
2157
2158 iov[0].iov_base = (char *)in;
2159 iov[0].iov_len = inl;
2160 msg.msg_name = NULL;
2161 msg.msg_namelen = 0;
2162 msg.msg_iov = iov;
2163 msg.msg_iovlen = 1;
2164 msg.msg_control = (caddr_t) cmsgbuf;
2165 msg.msg_controllen = 0;
2166 msg.msg_flags = 0;
2167# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
2168 cmsg = (struct cmsghdr *)cmsgbuf;
2169 cmsg->cmsg_level = IPPROTO_SCTP;
2170 cmsg->cmsg_type = SCTP_SNDINFO;
2171 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
2172 sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
16f8d4eb 2173 memset(sndinfo, 0, sizeof(*sndinfo));
0f113f3e
MC
2174 sndinfo->snd_sid = sinfo->snd_sid;
2175 sndinfo->snd_flags = sinfo->snd_flags;
2176 sndinfo->snd_ppid = sinfo->snd_ppid;
2177 sndinfo->snd_context = sinfo->snd_context;
2178 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
2179
2180 cmsg =
2181 (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
2182 cmsg->cmsg_level = IPPROTO_SCTP;
2183 cmsg->cmsg_type = SCTP_PRINFO;
2184 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
2185 prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
16f8d4eb 2186 memset(prinfo, 0, sizeof(*prinfo));
0f113f3e
MC
2187 prinfo->pr_policy = pinfo->pr_policy;
2188 prinfo->pr_value = pinfo->pr_value;
2189 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
2190# else
2191 cmsg = (struct cmsghdr *)cmsgbuf;
2192 cmsg->cmsg_level = IPPROTO_SCTP;
2193 cmsg->cmsg_type = SCTP_SNDRCV;
2194 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
2195 sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
16f8d4eb 2196 memset(sndrcvinfo, 0, sizeof(*sndrcvinfo));
0f113f3e
MC
2197 sndrcvinfo->sinfo_stream = sinfo->snd_sid;
2198 sndrcvinfo->sinfo_flags = sinfo->snd_flags;
2199# ifdef __FreeBSD__
2200 sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
2201# endif
2202 sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
2203 sndrcvinfo->sinfo_context = sinfo->snd_context;
2204 sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
2205 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
2206# endif
7e159e01 2207
0f113f3e 2208 ret = sendmsg(b->num, &msg, 0);
7e159e01 2209
0f113f3e
MC
2210 BIO_clear_retry_flags(b);
2211 if (ret <= 0) {
2212 if (BIO_dgram_should_retry(ret)) {
2213 BIO_set_retry_write(b);
2214 data->_errno = get_last_socket_error();
2215 }
2216 }
26a7d938 2217 return ret;
0f113f3e 2218}
7e159e01
DSH
2219
2220static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
0f113f3e
MC
2221{
2222 long ret = 1;
2223 bio_dgram_sctp_data *data = NULL;
2224 socklen_t sockopt_len = 0;
2225 struct sctp_authkeyid authkeyid;
2226 struct sctp_authkey *authkey = NULL;
2227
2228 data = (bio_dgram_sctp_data *) b->ptr;
2229
2230 switch (cmd) {
2231 case BIO_CTRL_DGRAM_QUERY_MTU:
2232 /*
2233 * Set to maximum (2^14) and ignore user input to enable transport
2234 * protocol fragmentation. Returns always 2^14.
2235 */
2236 data->mtu = 16384;
2237 ret = data->mtu;
2238 break;
2239 case BIO_CTRL_DGRAM_SET_MTU:
2240 /*
2241 * Set to maximum (2^14) and ignore input to enable transport
2242 * protocol fragmentation. Returns always 2^14.
2243 */
2244 data->mtu = 16384;
2245 ret = data->mtu;
2246 break;
2247 case BIO_CTRL_DGRAM_SET_CONNECTED:
2248 case BIO_CTRL_DGRAM_CONNECT:
2249 /* Returns always -1. */
2250 ret = -1;
2251 break;
2252 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
2253 /*
2254 * SCTP doesn't need the DTLS timer Returns always 1.
2255 */
2256 break;
2257 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
2258 /*
2259 * We allow transport protocol fragmentation so this is irrelevant
2260 */
2261 ret = 0;
2262 break;
2263 case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
2264 if (num > 0)
2265 data->in_handshake = 1;
2266 else
2267 data->in_handshake = 0;
2268
2269 ret =
2270 setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY,
2271 &data->in_handshake, sizeof(int));
2272 break;
2273 case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
2274 /*
2275 * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise.
2276 */
2277
2278 /* Get active key */
2279 sockopt_len = sizeof(struct sctp_authkeyid);
2280 ret =
2281 getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
2282 &sockopt_len);
2283 if (ret < 0)
2284 break;
2285
2286 /* Add new key */
2287 sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
2288 authkey = OPENSSL_malloc(sockopt_len);
2289 if (authkey == NULL) {
2290 ret = -1;
2291 break;
2292 }
16f8d4eb 2293 memset(authkey, 0, sockopt_len);
0f113f3e
MC
2294 authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
2295# ifndef __FreeBSD__
2296 /*
2297 * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3
2298 * and higher work without it.
2299 */
2300 authkey->sca_keylength = 64;
2301# endif
2302 memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
2303
2304 ret =
2305 setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey,
2306 sockopt_len);
2307 OPENSSL_free(authkey);
2308 authkey = NULL;
2309 if (ret < 0)
2310 break;
2311
2312 /* Reset active key */
2313 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
2314 &authkeyid, sizeof(struct sctp_authkeyid));
2315 if (ret < 0)
2316 break;
2317
2318 break;
2319 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
2320 /* Returns 0 on success, -1 otherwise. */
2321
2322 /* Get active key */
2323 sockopt_len = sizeof(struct sctp_authkeyid);
2324 ret =
2325 getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
2326 &sockopt_len);
2327 if (ret < 0)
2328 break;
2329
2330 /* Set active key */
2331 authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
2332 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
2333 &authkeyid, sizeof(struct sctp_authkeyid));
2334 if (ret < 0)
2335 break;
2336
2337 /*
2338 * CCS has been sent, so remember that and fall through to check if
2339 * we need to deactivate an old key
2340 */
2341 data->ccs_sent = 1;
14716754 2342 /* fall-through */
0f113f3e
MC
2343
2344 case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
2345 /* Returns 0 on success, -1 otherwise. */
2346
2347 /*
2348 * Has this command really been called or is this just a
2349 * fall-through?
2350 */
2351 if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
2352 data->ccs_rcvd = 1;
2353
2354 /*
2355 * CSS has been both, received and sent, so deactivate an old key
2356 */
2357 if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
2358 /* Get active key */
2359 sockopt_len = sizeof(struct sctp_authkeyid);
2360 ret =
2361 getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
2362 &authkeyid, &sockopt_len);
2363 if (ret < 0)
2364 break;
2365
2366 /*
2367 * Deactivate key or delete second last key if
2368 * SCTP_AUTHENTICATION_EVENT is not available.
2369 */
2370 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
2371# ifdef SCTP_AUTH_DEACTIVATE_KEY
2372 sockopt_len = sizeof(struct sctp_authkeyid);
2373 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
2374 &authkeyid, sockopt_len);
2375 if (ret < 0)
2376 break;
2377# endif
2378# ifndef SCTP_AUTHENTICATION_EVENT
2379 if (authkeyid.scact_keynumber > 0) {
2380 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
2381 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
2382 &authkeyid, sizeof(struct sctp_authkeyid));
2383 if (ret < 0)
2384 break;
2385 }
2386# endif
7e159e01 2387
0f113f3e
MC
2388 data->ccs_rcvd = 0;
2389 data->ccs_sent = 0;
2390 }
2391 break;
2392 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
2393 /* Returns the size of the copied struct. */
2394 if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
2395 num = sizeof(struct bio_dgram_sctp_sndinfo);
2396
2397 memcpy(ptr, &(data->sndinfo), num);
2398 ret = num;
2399 break;
2400 case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
2401 /* Returns the size of the copied struct. */
2402 if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
2403 num = sizeof(struct bio_dgram_sctp_sndinfo);
2404
2405 memcpy(&(data->sndinfo), ptr, num);
2406 break;
2407 case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
2408 /* Returns the size of the copied struct. */
2409 if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
2410 num = sizeof(struct bio_dgram_sctp_rcvinfo);
2411
2412 memcpy(ptr, &data->rcvinfo, num);
2413
2414 ret = num;
2415 break;
2416 case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
2417 /* Returns the size of the copied struct. */
2418 if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
2419 num = sizeof(struct bio_dgram_sctp_rcvinfo);
2420
2421 memcpy(&(data->rcvinfo), ptr, num);
2422 break;
2423 case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
2424 /* Returns the size of the copied struct. */
2425 if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
2426 num = sizeof(struct bio_dgram_sctp_prinfo);
2427
2428 memcpy(ptr, &(data->prinfo), num);
2429 ret = num;
2430 break;
2431 case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
2432 /* Returns the size of the copied struct. */
2433 if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
2434 num = sizeof(struct bio_dgram_sctp_prinfo);
2435
2436 memcpy(&(data->prinfo), ptr, num);
2437 break;
2438 case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
2439 /* Returns always 1. */
2440 if (num > 0)
2441 data->save_shutdown = 1;
2442 else
2443 data->save_shutdown = 0;
2444 break;
c8edb04f 2445 case BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY:
2446 return dgram_sctp_wait_for_dry(b);
2447 case BIO_CTRL_DGRAM_SCTP_MSG_WAITING:
2448 return dgram_sctp_msg_waiting(b);
0f113f3e
MC
2449
2450 default:
2451 /*
2452 * Pass to default ctrl function to process SCTP unspecific commands
2453 */
2454 ret = dgram_ctrl(b, cmd, num, ptr);
2455 break;
2456 }
26a7d938 2457 return ret;
0f113f3e 2458}
7e159e01
DSH
2459
2460int BIO_dgram_sctp_notification_cb(BIO *b,
c8edb04f 2461 BIO_dgram_sctp_notification_handler_fn handle_notifications,
2462 void *context)
0f113f3e
MC
2463{
2464 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
7e159e01 2465
0f113f3e
MC
2466 if (handle_notifications != NULL) {
2467 data->handle_notifications = handle_notifications;
2468 data->notification_context = context;
2469 } else
2470 return -1;
7e159e01 2471
0f113f3e
MC
2472 return 0;
2473}
7e159e01 2474
03a1c850
KR
2475/*
2476 * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event
2477 * @b: The BIO to check for the dry event
2478 *
2479 * Wait until the peer confirms all packets have been received, and so that
2480 * our kernel doesn't have anything to send anymore. This is only received by
2481 * the peer's kernel, not the application.
2482 *
2483 * Returns:
2484 * -1 on error
2485 * 0 when not dry yet
2486 * 1 when dry
2487 */
7e159e01 2488int BIO_dgram_sctp_wait_for_dry(BIO *b)
c8edb04f 2489{
2490 return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY, 0, NULL);
2491}
2492
2493static int dgram_sctp_wait_for_dry(BIO *b)
7e159e01 2494{
0f113f3e 2495 int is_dry = 0;
4eacfade
BL
2496 int sockflags = 0;
2497 int n, ret;
0f113f3e
MC
2498 union sctp_notification snp;
2499 struct msghdr msg;
2500 struct iovec iov;
2501# ifdef SCTP_EVENT
2502 struct sctp_event event;
2503# else
2504 struct sctp_event_subscribe event;
2505 socklen_t eventsize;
2506# endif
2507 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
2508
2509 /* set sender dry event */
2510# ifdef SCTP_EVENT
16f8d4eb 2511 memset(&event, 0, sizeof(event));
0f113f3e
MC
2512 event.se_assoc_id = 0;
2513 event.se_type = SCTP_SENDER_DRY_EVENT;
2514 event.se_on = 1;
2515 ret =
2516 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
2517 sizeof(struct sctp_event));
2518# else
2519 eventsize = sizeof(struct sctp_event_subscribe);
2520 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
2521 if (ret < 0)
2522 return -1;
2523
2524 event.sctp_sender_dry_event = 1;
2525
2526 ret =
2527 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
2528 sizeof(struct sctp_event_subscribe));
2529# endif
2530 if (ret < 0)
2531 return -1;
2532
2533 /* peek for notification */
16f8d4eb 2534 memset(&snp, 0, sizeof(snp));
0f113f3e
MC
2535 iov.iov_base = (char *)&snp;
2536 iov.iov_len = sizeof(union sctp_notification);
2537 msg.msg_name = NULL;
2538 msg.msg_namelen = 0;
2539 msg.msg_iov = &iov;
2540 msg.msg_iovlen = 1;
2541 msg.msg_control = NULL;
2542 msg.msg_controllen = 0;
2543 msg.msg_flags = 0;
2544
2545 n = recvmsg(b->num, &msg, MSG_PEEK);
2546 if (n <= 0) {
2547 if ((n < 0) && (get_last_socket_error() != EAGAIN)
2548 && (get_last_socket_error() != EWOULDBLOCK))
2549 return -1;
2550 else
2551 return 0;
2552 }
2553
2554 /* if we find a notification, process it and try again if necessary */
2555 while (msg.msg_flags & MSG_NOTIFICATION) {
16f8d4eb 2556 memset(&snp, 0, sizeof(snp));
0f113f3e
MC
2557 iov.iov_base = (char *)&snp;
2558 iov.iov_len = sizeof(union sctp_notification);
2559 msg.msg_name = NULL;
2560 msg.msg_namelen = 0;
2561 msg.msg_iov = &iov;
2562 msg.msg_iovlen = 1;
2563 msg.msg_control = NULL;
2564 msg.msg_controllen = 0;
2565 msg.msg_flags = 0;
2566
2567 n = recvmsg(b->num, &msg, 0);
2568 if (n <= 0) {
2569 if ((n < 0) && (get_last_socket_error() != EAGAIN)
2570 && (get_last_socket_error() != EWOULDBLOCK))
2571 return -1;
2572 else
2573 return is_dry;
2574 }
2575
2576 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
2577 is_dry = 1;
2578
2579 /* disable sender dry event */
2580# ifdef SCTP_EVENT
16f8d4eb 2581 memset(&event, 0, sizeof(event));
0f113f3e
MC
2582 event.se_assoc_id = 0;
2583 event.se_type = SCTP_SENDER_DRY_EVENT;
2584 event.se_on = 0;
2585 ret =
2586 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
2587 sizeof(struct sctp_event));
2588# else
2589 eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
2590 ret =
2591 getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
2592 &eventsize);
2593 if (ret < 0)
2594 return -1;
2595
2596 event.sctp_sender_dry_event = 0;
2597
2598 ret =
2599 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
2600 sizeof(struct sctp_event_subscribe));
2601# endif
2602 if (ret < 0)
2603 return -1;
2604 }
2605# ifdef SCTP_AUTHENTICATION_EVENT
2606 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
2607 dgram_sctp_handle_auth_free_key_event(b, &snp);
2608# endif
7e159e01 2609
0f113f3e
MC
2610 if (data->handle_notifications != NULL)
2611 data->handle_notifications(b, data->notification_context,
2612 (void *)&snp);
2613
2614 /* found notification, peek again */
16f8d4eb 2615 memset(&snp, 0, sizeof(snp));
0f113f3e
MC
2616 iov.iov_base = (char *)&snp;
2617 iov.iov_len = sizeof(union sctp_notification);
2618 msg.msg_name = NULL;
2619 msg.msg_namelen = 0;
2620 msg.msg_iov = &iov;
2621 msg.msg_iovlen = 1;
2622 msg.msg_control = NULL;
2623 msg.msg_controllen = 0;
2624 msg.msg_flags = 0;
2625
2626 /* if we have seen the dry already, don't wait */
2627 if (is_dry) {
2628 sockflags = fcntl(b->num, F_GETFL, 0);
2629 fcntl(b->num, F_SETFL, O_NONBLOCK);
2630 }
2631
2632 n = recvmsg(b->num, &msg, MSG_PEEK);
2633
2634 if (is_dry) {
2635 fcntl(b->num, F_SETFL, sockflags);
2636 }
2637
2638 if (n <= 0) {
2639 if ((n < 0) && (get_last_socket_error() != EAGAIN)
2640 && (get_last_socket_error() != EWOULDBLOCK))
2641 return -1;
2642 else
2643 return is_dry;
2644 }
2645 }
2646
2647 /* read anything else */
2648 return is_dry;
7e159e01
DSH
2649}
2650
2651int BIO_dgram_sctp_msg_waiting(BIO *b)
c8edb04f 2652{
2653 return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_MSG_WAITING, 0, NULL);
2654}
2655
2656static int dgram_sctp_msg_waiting(BIO *b)
0f113f3e
MC
2657{
2658 int n, sockflags;
2659 union sctp_notification snp;
2660 struct msghdr msg;
2661 struct iovec iov;
2662 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
2663
2664 /* Check if there are any messages waiting to be read */
2665 do {
16f8d4eb 2666 memset(&snp, 0, sizeof(snp));
0f113f3e
MC
2667 iov.iov_base = (char *)&snp;
2668 iov.iov_len = sizeof(union sctp_notification);
2669 msg.msg_name = NULL;
2670 msg.msg_namelen = 0;
2671 msg.msg_iov = &iov;
2672 msg.msg_iovlen = 1;
2673 msg.msg_control = NULL;
2674 msg.msg_controllen = 0;
2675 msg.msg_flags = 0;
2676
2677 sockflags = fcntl(b->num, F_GETFL, 0);
2678 fcntl(b->num, F_SETFL, O_NONBLOCK);
2679 n = recvmsg(b->num, &msg, MSG_PEEK);
2680 fcntl(b->num, F_SETFL, sockflags);
2681
2682 /* if notification, process and try again */
2683 if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
2684# ifdef SCTP_AUTHENTICATION_EVENT
2685 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
2686 dgram_sctp_handle_auth_free_key_event(b, &snp);
2687# endif
7e159e01 2688
16f8d4eb 2689 memset(&snp, 0, sizeof(snp));
0f113f3e
MC
2690 iov.iov_base = (char *)&snp;
2691 iov.iov_len = sizeof(union sctp_notification);
2692 msg.msg_name = NULL;
2693 msg.msg_namelen = 0;
2694 msg.msg_iov = &iov;
2695 msg.msg_iovlen = 1;
2696 msg.msg_control = NULL;
2697 msg.msg_controllen = 0;
2698 msg.msg_flags = 0;
2699 n = recvmsg(b->num, &msg, 0);
2700
2701 if (data->handle_notifications != NULL)
2702 data->handle_notifications(b, data->notification_context,
2703 (void *)&snp);
2704 }
2705
2706 } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
2707
2708 /* Return 1 if there is a message to be read, return 0 otherwise. */
2709 if (n > 0)
2710 return 1;
2711 else
2712 return 0;
2713}
7e159e01
DSH
2714
2715static int dgram_sctp_puts(BIO *bp, const char *str)
0f113f3e
MC
2716{
2717 int n, ret;
7e159e01 2718
0f113f3e
MC
2719 n = strlen(str);
2720 ret = dgram_sctp_write(bp, str, n);
26a7d938 2721 return ret;
0f113f3e
MC
2722}
2723# endif
7e159e01 2724
b3e72fc3 2725static int BIO_dgram_should_retry(int i)
0f113f3e
MC
2726{
2727 int err;
36d16f8e 2728
0f113f3e
MC
2729 if ((i == 0) || (i == -1)) {
2730 err = get_last_socket_error();
36d16f8e 2731
0f113f3e
MC
2732# if defined(OPENSSL_SYS_WINDOWS)
2733 /*
2734 * If the socket return value (i) is -1 and err is unexpectedly 0 at
2735 * this point, the error code was overwritten by another system call
2736 * before this error handling is called.
2737 */
36d16f8e
BL
2738# endif
2739
26a7d938 2740 return BIO_dgram_non_fatal_error(err);
0f113f3e 2741 }
26a7d938 2742 return 0;
0f113f3e
MC
2743}
2744
2745int BIO_dgram_non_fatal_error(int err)
2746{
2747 switch (err) {
2748# if defined(OPENSSL_SYS_WINDOWS)
2749# if defined(WSAEWOULDBLOCK)
2750 case WSAEWOULDBLOCK:
2751# endif
36d16f8e 2752# endif
36d16f8e 2753
0f113f3e
MC
2754# ifdef EWOULDBLOCK
2755# ifdef WSAEWOULDBLOCK
2756# if WSAEWOULDBLOCK != EWOULDBLOCK
2757 case EWOULDBLOCK:
2758# endif
2759# else
2760 case EWOULDBLOCK:
36d16f8e 2761# endif
36d16f8e 2762# endif
36d16f8e 2763
0f113f3e
MC
2764# ifdef EINTR
2765 case EINTR:
2766# endif
36d16f8e 2767
0f113f3e
MC
2768# ifdef EAGAIN
2769# if EWOULDBLOCK != EAGAIN
2770 case EAGAIN:
2771# endif
36d16f8e 2772# endif
36d16f8e 2773
0f113f3e
MC
2774# ifdef EPROTO
2775 case EPROTO:
2776# endif
36d16f8e 2777
0f113f3e
MC
2778# ifdef EINPROGRESS
2779 case EINPROGRESS:
2780# endif
36d16f8e 2781
0f113f3e
MC
2782# ifdef EALREADY
2783 case EALREADY:
2784# endif
36d16f8e 2785
208fb891 2786 return 1;
0f113f3e
MC
2787 default:
2788 break;
2789 }
26a7d938 2790 return 0;
0f113f3e 2791}
5d6a0179
RL
2792
2793static void get_current_time(struct timeval *t)
0f113f3e
MC
2794{
2795# if defined(_WIN32)
2796 SYSTEMTIME st;
8eca6864
TK
2797 unsigned __int64 now_ul;
2798 FILETIME now_ft;
0f113f3e
MC
2799
2800 GetSystemTime(&st);
8eca6864
TK
2801 SystemTimeToFileTime(&st, &now_ft);
2802 now_ul = ((unsigned __int64)now_ft.dwHighDateTime << 32) | now_ft.dwLowDateTime;
0f113f3e 2803# ifdef __MINGW32__
8eca6864 2804 now_ul -= 116444736000000000ULL;
0f113f3e 2805# else
8eca6864 2806 now_ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
0f113f3e 2807# endif
8eca6864
TK
2808 t->tv_sec = (long)(now_ul / 10000000);
2809 t->tv_usec = ((int)(now_ul % 10000000)) / 10;
0f113f3e 2810# else
358103b4
P
2811 if (gettimeofday(t, NULL) < 0)
2812 perror("gettimeofday");
0f113f3e
MC
2813# endif
2814}
74e056ed
DSH
2815
2816#endif