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