2 * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
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
14 #ifndef OPENSSL_NO_DGRAM
16 # if !(defined(_WIN32) || defined(OPENSSL_SYS_VMS))
17 # include <sys/time.h>
19 # if defined(OPENSSL_SYS_VMS)
20 # include <sys/timeb.h>
23 # ifndef OPENSSL_NO_SCTP
24 # include <netinet/sctp.h>
26 # define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00
27 # define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
30 # if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
31 # define IP_MTU 14 /* linux is lame */
34 # if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
35 # define IPPROTO_IPV6 41 /* windows is lame */
38 # if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
39 /* Standard definition causes type-punning problems. */
40 # undef IN6_IS_ADDR_V4MAPPED
41 # define s6_addr32 __u6_addr.__u6_addr32
42 # define IN6_IS_ADDR_V4MAPPED(a) \
43 (((a)->s6_addr32[0] == 0) && \
44 ((a)->s6_addr32[1] == 0) && \
45 ((a)->s6_addr32[2] == htonl(0x0000ffff)))
48 static int dgram_write(BIO *h, const char *buf, int num);
49 static int dgram_read(BIO *h, char *buf, int size);
50 static int dgram_puts(BIO *h, const char *str);
51 static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
52 static int dgram_new(BIO *h);
53 static int dgram_free(BIO *data);
54 static int dgram_clear(BIO *bio);
56 # ifndef OPENSSL_NO_SCTP
57 static int dgram_sctp_write(BIO *h, const char *buf, int num);
58 static int dgram_sctp_read(BIO *h, char *buf, int size);
59 static int dgram_sctp_puts(BIO *h, const char *str);
60 static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
61 static int dgram_sctp_new(BIO *h);
62 static int dgram_sctp_free(BIO *data);
63 # ifdef SCTP_AUTHENTICATION_EVENT
64 static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
69 static int BIO_dgram_should_retry(int s);
71 static void get_current_time(struct timeval *t);
73 static const BIO_METHOD methods_dgramp = {
76 /* TODO: Convert to new style write function */
79 /* TODO: Convert to new style read function */
83 NULL, /* dgram_gets, */
90 # ifndef OPENSSL_NO_SCTP
91 static const BIO_METHOD methods_dgramp_sctp = {
93 "datagram sctp socket",
94 /* TODO: Convert to new style write function */
97 /* TODO: Convert to new style write function */
101 NULL, /* dgram_gets, */
109 typedef struct bio_dgram_data_st {
111 unsigned int connected;
114 struct timeval next_timeout;
115 struct timeval socket_timeout;
116 unsigned int peekmode;
119 # ifndef OPENSSL_NO_SCTP
120 typedef struct bio_dgram_sctp_save_message_st {
124 } bio_dgram_sctp_save_message;
126 typedef struct bio_dgram_sctp_data_st {
128 unsigned int connected;
131 struct bio_dgram_sctp_sndinfo sndinfo;
132 struct bio_dgram_sctp_rcvinfo rcvinfo;
133 struct bio_dgram_sctp_prinfo prinfo;
134 void (*handle_notifications) (BIO *bio, void *context, void *buf);
135 void *notification_context;
140 int peer_auth_tested;
141 bio_dgram_sctp_save_message saved_message;
142 } bio_dgram_sctp_data;
145 const BIO_METHOD *BIO_s_datagram(void)
147 return (&methods_dgramp);
150 BIO *BIO_new_dgram(int fd, int close_flag)
154 ret = BIO_new(BIO_s_datagram());
157 BIO_set_fd(ret, fd, close_flag);
161 static int dgram_new(BIO *bi)
163 bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
171 static int dgram_free(BIO *a)
173 bio_dgram_data *data;
180 data = (bio_dgram_data *)a->ptr;
186 static int dgram_clear(BIO *a)
192 BIO_closesocket(a->num);
200 static void dgram_adjust_rcv_timeout(BIO *b)
202 # if defined(SO_RCVTIMEO)
203 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
211 /* Is a timer active? */
212 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
213 struct timeval timenow, timeleft;
215 /* Read current socket timeout */
216 # ifdef OPENSSL_SYS_WINDOWS
219 sz.i = sizeof(timeout);
220 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
221 (void *)&timeout, &sz.i) < 0) {
222 perror("getsockopt");
224 data->socket_timeout.tv_sec = timeout / 1000;
225 data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
228 sz.i = sizeof(data->socket_timeout);
229 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
230 &(data->socket_timeout), (void *)&sz) < 0) {
231 perror("getsockopt");
232 } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
233 OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
236 /* Get current time */
237 get_current_time(&timenow);
239 /* Calculate time left until timer expires */
240 memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
241 if (timeleft.tv_usec < timenow.tv_usec) {
242 timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
245 timeleft.tv_usec -= timenow.tv_usec;
247 if (timeleft.tv_sec < timenow.tv_sec) {
249 timeleft.tv_usec = 1;
251 timeleft.tv_sec -= timenow.tv_sec;
255 * Adjust socket timeout if next handshake message timer will expire
258 if ((data->socket_timeout.tv_sec == 0
259 && data->socket_timeout.tv_usec == 0)
260 || (data->socket_timeout.tv_sec > timeleft.tv_sec)
261 || (data->socket_timeout.tv_sec == timeleft.tv_sec
262 && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
263 # ifdef OPENSSL_SYS_WINDOWS
264 timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
265 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
266 (void *)&timeout, sizeof(timeout)) < 0) {
267 perror("setsockopt");
270 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
271 sizeof(struct timeval)) < 0) {
272 perror("setsockopt");
280 static void dgram_reset_rcv_timeout(BIO *b)
282 # if defined(SO_RCVTIMEO)
283 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
285 /* Is a timer active? */
286 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
287 # ifdef OPENSSL_SYS_WINDOWS
288 int timeout = data->socket_timeout.tv_sec * 1000 +
289 data->socket_timeout.tv_usec / 1000;
290 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
291 (void *)&timeout, sizeof(timeout)) < 0) {
292 perror("setsockopt");
296 (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
297 sizeof(struct timeval)) < 0) {
298 perror("setsockopt");
305 static int dgram_read(BIO *b, char *out, int outl)
308 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
312 socklen_t len = sizeof(peer);
315 clear_socket_error();
316 memset(&peer, 0, sizeof(peer));
317 dgram_adjust_rcv_timeout(b);
320 ret = recvfrom(b->num, out, outl, flags,
321 BIO_ADDR_sockaddr_noconst(&peer), &len);
323 if (!data->connected && ret >= 0)
324 BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
326 BIO_clear_retry_flags(b);
328 if (BIO_dgram_should_retry(ret)) {
329 BIO_set_retry_read(b);
330 data->_errno = get_last_socket_error();
334 dgram_reset_rcv_timeout(b);
339 static int dgram_write(BIO *b, const char *in, int inl)
342 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
343 clear_socket_error();
346 ret = writesocket(b->num, in, inl);
348 int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
350 # if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
351 ret = sendto(b->num, (char *)in, inl, 0,
352 BIO_ADDR_sockaddr(&data->peer), peerlen);
354 ret = sendto(b->num, in, inl, 0,
355 BIO_ADDR_sockaddr(&data->peer), peerlen);
359 BIO_clear_retry_flags(b);
361 if (BIO_dgram_should_retry(ret)) {
362 BIO_set_retry_write(b);
363 data->_errno = get_last_socket_error();
369 static long dgram_get_mtu_overhead(bio_dgram_data *data)
373 switch (BIO_ADDR_family(&data->peer)) {
376 * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
383 # ifdef IN6_IS_ADDR_V4MAPPED
384 struct in6_addr tmp_addr;
385 if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
386 && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
388 * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
394 * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
401 /* We don't know. Go with the historical default */
408 static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
412 bio_dgram_data *data = NULL;
415 # if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
416 socklen_t sockopt_len; /* assume that system supporting IP_MTU is
417 * modern enough to define socklen_t */
422 data = (bio_dgram_data *)b->ptr;
434 b->num = *((int *)ptr);
435 b->shutdown = (int)num;
447 case BIO_CTRL_GET_CLOSE:
450 case BIO_CTRL_SET_CLOSE:
451 b->shutdown = (int)num;
453 case BIO_CTRL_PENDING:
454 case BIO_CTRL_WPENDING:
461 case BIO_CTRL_DGRAM_CONNECT:
462 BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
464 /* (Linux)kernel sets DF bit on outgoing IP packets */
465 case BIO_CTRL_DGRAM_MTU_DISCOVER:
466 # if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
467 addr_len = (socklen_t) sizeof(addr);
468 memset(&addr, 0, sizeof(addr));
469 if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
473 switch (addr.sa.sa_family) {
475 sockopt_val = IP_PMTUDISC_DO;
476 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
477 &sockopt_val, sizeof(sockopt_val))) < 0)
478 perror("setsockopt");
480 # if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
482 sockopt_val = IPV6_PMTUDISC_DO;
483 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
484 &sockopt_val, sizeof(sockopt_val))) < 0)
485 perror("setsockopt");
496 case BIO_CTRL_DGRAM_QUERY_MTU:
497 # if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
498 addr_len = (socklen_t) sizeof(addr);
499 memset(&addr, 0, sizeof(addr));
500 if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
504 sockopt_len = sizeof(sockopt_val);
505 switch (addr.sa.sa_family) {
508 getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
509 &sockopt_len)) < 0 || sockopt_val < 0) {
513 * we assume that the transport protocol is UDP and no IP
516 data->mtu = sockopt_val - 8 - 20;
520 # if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
523 getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
524 (void *)&sockopt_val, &sockopt_len)) < 0
525 || sockopt_val < 0) {
529 * we assume that the transport protocol is UDP and no IPV6
532 data->mtu = sockopt_val - 8 - 40;
545 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
546 ret = -dgram_get_mtu_overhead(data);
547 switch (BIO_ADDR_family(&data->peer)) {
551 # if OPENSSL_USE_IPV6
554 # ifdef IN6_IS_ADDR_V4MAPPED
555 struct in6_addr tmp_addr;
556 if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
557 && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
570 case BIO_CTRL_DGRAM_GET_MTU:
572 case BIO_CTRL_DGRAM_SET_MTU:
576 case BIO_CTRL_DGRAM_SET_CONNECTED:
579 BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
582 memset(&data->peer, 0, sizeof(data->peer));
585 case BIO_CTRL_DGRAM_GET_PEER:
586 ret = BIO_ADDR_sockaddr_size(&data->peer);
587 /* FIXME: if num < ret, we will only return part of an address.
588 That should bee an error, no? */
589 if (num == 0 || num > ret)
591 memcpy(ptr, &data->peer, (ret = num));
593 case BIO_CTRL_DGRAM_SET_PEER:
594 BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
596 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
597 memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
599 # if defined(SO_RCVTIMEO)
600 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
601 # ifdef OPENSSL_SYS_WINDOWS
603 struct timeval *tv = (struct timeval *)ptr;
604 int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
605 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
606 (void *)&timeout, sizeof(timeout)) < 0) {
607 perror("setsockopt");
612 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
613 sizeof(struct timeval)) < 0) {
614 perror("setsockopt");
619 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
627 # ifdef OPENSSL_SYS_WINDOWS
629 struct timeval *tv = (struct timeval *)ptr;
631 sz.i = sizeof(timeout);
632 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
633 (void *)&timeout, &sz.i) < 0) {
634 perror("getsockopt");
637 tv->tv_sec = timeout / 1000;
638 tv->tv_usec = (timeout % 1000) * 1000;
642 sz.i = sizeof(struct timeval);
643 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
644 ptr, (void *)&sz) < 0) {
645 perror("getsockopt");
647 } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
648 OPENSSL_assert(sz.s <= sizeof(struct timeval));
656 # if defined(SO_SNDTIMEO)
657 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
658 # ifdef OPENSSL_SYS_WINDOWS
660 struct timeval *tv = (struct timeval *)ptr;
661 int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
662 if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
663 (void *)&timeout, sizeof(timeout)) < 0) {
664 perror("setsockopt");
669 if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
670 sizeof(struct timeval)) < 0) {
671 perror("setsockopt");
676 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
684 # ifdef OPENSSL_SYS_WINDOWS
686 struct timeval *tv = (struct timeval *)ptr;
688 sz.i = sizeof(timeout);
689 if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
690 (void *)&timeout, &sz.i) < 0) {
691 perror("getsockopt");
694 tv->tv_sec = timeout / 1000;
695 tv->tv_usec = (timeout % 1000) * 1000;
699 sz.i = sizeof(struct timeval);
700 if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
701 ptr, (void *)&sz) < 0) {
702 perror("getsockopt");
704 } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
705 OPENSSL_assert(sz.s <= sizeof(struct timeval));
713 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
715 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
716 # ifdef OPENSSL_SYS_WINDOWS
717 d_errno = (data->_errno == WSAETIMEDOUT);
719 d_errno = (data->_errno == EAGAIN);
728 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
729 if (data->_errno == EMSGSIZE) {
736 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
737 sockopt_val = num ? 1 : 0;
739 switch (data->peer.sa.sa_family) {
741 # if defined(IP_DONTFRAG)
742 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
743 &sockopt_val, sizeof(sockopt_val))) < 0) {
744 perror("setsockopt");
747 # elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
748 if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
749 (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
750 &sockopt_val, sizeof(sockopt_val))) < 0) {
751 perror("setsockopt");
754 # elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
755 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
756 (const char *)&sockopt_val,
757 sizeof(sockopt_val))) < 0) {
758 perror("setsockopt");
765 # if OPENSSL_USE_IPV6
767 # if defined(IPV6_DONTFRAG)
768 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
769 (const void *)&sockopt_val,
770 sizeof(sockopt_val))) < 0) {
771 perror("setsockopt");
774 # elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
775 if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
776 (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
777 &sockopt_val, sizeof(sockopt_val))) < 0) {
778 perror("setsockopt");
791 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
792 ret = dgram_get_mtu_overhead(data);
794 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
795 data->peekmode = (unsigned int)num;
804 static int dgram_puts(BIO *bp, const char *str)
809 ret = dgram_write(bp, str, n);
813 # ifndef OPENSSL_NO_SCTP
814 const BIO_METHOD *BIO_s_datagram_sctp(void)
816 return (&methods_dgramp_sctp);
819 BIO *BIO_new_dgram_sctp(int fd, int close_flag)
822 int ret, optval = 20000;
823 int auth_data = 0, auth_forward = 0;
825 struct sctp_authchunk auth;
826 struct sctp_authchunks *authchunks;
827 socklen_t sockopt_len;
828 # ifdef SCTP_AUTHENTICATION_EVENT
830 struct sctp_event event;
832 struct sctp_event_subscribe event;
836 bio = BIO_new(BIO_s_datagram_sctp());
839 BIO_set_fd(bio, fd, close_flag);
841 /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
842 auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
844 setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
845 sizeof(struct sctp_authchunk));
850 auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
852 setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
853 sizeof(struct sctp_authchunk));
860 * Test if activation was successful. When using accept(), SCTP-AUTH has
861 * to be activated for the listening socket already, otherwise the
862 * connected socket won't use it.
864 sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
865 authchunks = OPENSSL_zalloc(sockopt_len);
866 if (authchunks == NULL) {
870 ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
873 OPENSSL_free(authchunks);
878 for (p = (unsigned char *)authchunks->gauth_chunks;
879 p < (unsigned char *)authchunks + sockopt_len;
880 p += sizeof(uint8_t)) {
881 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
883 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
887 OPENSSL_free(authchunks);
889 OPENSSL_assert(auth_data);
890 OPENSSL_assert(auth_forward);
892 # ifdef SCTP_AUTHENTICATION_EVENT
894 memset(&event, 0, sizeof(event));
895 event.se_assoc_id = 0;
896 event.se_type = SCTP_AUTHENTICATION_EVENT;
899 setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
900 sizeof(struct sctp_event));
906 sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
907 ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
913 event.sctp_authentication_event = 1;
916 setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
917 sizeof(struct sctp_event_subscribe));
926 * Disable partial delivery by setting the min size larger than the max
927 * record size of 2^14 + 2048 + 13
930 setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
940 int BIO_dgram_is_sctp(BIO *bio)
942 return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
945 static int dgram_sctp_new(BIO *bi)
947 bio_dgram_sctp_data *data = NULL;
951 data = OPENSSL_zalloc(sizeof(*data));
954 # ifdef SCTP_PR_SCTP_NONE
955 data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
963 static int dgram_sctp_free(BIO *a)
965 bio_dgram_sctp_data *data;
972 data = (bio_dgram_sctp_data *) a->ptr;
974 OPENSSL_free(data->saved_message.data);
981 # ifdef SCTP_AUTHENTICATION_EVENT
982 void dgram_sctp_handle_auth_free_key_event(BIO *b,
983 union sctp_notification *snp)
986 struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
988 if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
989 struct sctp_authkeyid authkeyid;
992 authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
993 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
994 &authkeyid, sizeof(struct sctp_authkeyid));
999 static int dgram_sctp_read(BIO *b, char *out, int outl)
1001 int ret = 0, n = 0, i, optval;
1003 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1004 union sctp_notification *snp;
1007 struct cmsghdr *cmsg;
1011 clear_socket_error();
1014 memset(&data->rcvinfo, 0, sizeof(data->rcvinfo));
1017 msg.msg_name = NULL;
1018 msg.msg_namelen = 0;
1021 msg.msg_control = cmsgbuf;
1022 msg.msg_controllen = 512;
1024 n = recvmsg(b->num, &msg, 0);
1032 if (msg.msg_controllen > 0) {
1033 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
1034 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1035 if (cmsg->cmsg_level != IPPROTO_SCTP)
1037 # ifdef SCTP_RCVINFO
1038 if (cmsg->cmsg_type == SCTP_RCVINFO) {
1039 struct sctp_rcvinfo *rcvinfo;
1041 rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
1042 data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
1043 data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
1044 data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
1045 data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
1046 data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
1047 data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
1048 data->rcvinfo.rcv_context = rcvinfo->rcv_context;
1052 if (cmsg->cmsg_type == SCTP_SNDRCV) {
1053 struct sctp_sndrcvinfo *sndrcvinfo;
1056 (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1057 data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
1058 data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
1059 data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
1060 data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
1061 data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
1062 data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
1063 data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
1069 if (msg.msg_flags & MSG_NOTIFICATION) {
1070 snp = (union sctp_notification *)out;
1071 if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
1073 struct sctp_event event;
1075 struct sctp_event_subscribe event;
1076 socklen_t eventsize;
1079 * If a message has been delayed until the socket is dry,
1080 * it can be sent now.
1082 if (data->saved_message.length > 0) {
1083 i = dgram_sctp_write(data->saved_message.bio,
1084 data->saved_message.data,
1085 data->saved_message.length);
1090 OPENSSL_free(data->saved_message.data);
1091 data->saved_message.data = NULL;
1092 data->saved_message.length = 0;
1095 /* disable sender dry event */
1097 memset(&event, 0, sizeof(event));
1098 event.se_assoc_id = 0;
1099 event.se_type = SCTP_SENDER_DRY_EVENT;
1101 i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1102 sizeof(struct sctp_event));
1108 eventsize = sizeof(struct sctp_event_subscribe);
1109 i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1116 event.sctp_sender_dry_event = 0;
1118 i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1119 sizeof(struct sctp_event_subscribe));
1126 # ifdef SCTP_AUTHENTICATION_EVENT
1127 if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1128 dgram_sctp_handle_auth_free_key_event(b, snp);
1131 if (data->handle_notifications != NULL)
1132 data->handle_notifications(b, data->notification_context,
1135 memset(out, 0, outl);
1139 while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
1142 if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
1143 /* Partial message read, this should never happen! */
1146 * The buffer was too small, this means the peer sent a message
1147 * that was larger than allowed.
1153 * Test if socket buffer can handle max record size (2^14 + 2048
1156 optlen = (socklen_t) sizeof(int);
1157 ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
1159 OPENSSL_assert(optval >= 18445);
1162 * Test if SCTP doesn't partially deliver below max record size
1163 * (2^14 + 2048 + 13)
1165 optlen = (socklen_t) sizeof(int);
1167 getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
1170 OPENSSL_assert(optval >= 18445);
1173 * Partially delivered notification??? Probably a bug....
1175 OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
1178 * Everything seems ok till now, so it's most likely a message
1179 * dropped by PR-SCTP.
1181 memset(out, 0, outl);
1182 BIO_set_retry_read(b);
1186 BIO_clear_retry_flags(b);
1188 if (BIO_dgram_should_retry(ret)) {
1189 BIO_set_retry_read(b);
1190 data->_errno = get_last_socket_error();
1194 /* Test if peer uses SCTP-AUTH before continuing */
1195 if (!data->peer_auth_tested) {
1196 int ii, auth_data = 0, auth_forward = 0;
1198 struct sctp_authchunks *authchunks;
1201 (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
1202 authchunks = OPENSSL_malloc(optlen);
1203 if (authchunks == NULL) {
1204 BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE);
1207 memset(authchunks, 0, optlen);
1208 ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS,
1209 authchunks, &optlen);
1212 for (p = (unsigned char *)authchunks->gauth_chunks;
1213 p < (unsigned char *)authchunks + optlen;
1214 p += sizeof(uint8_t)) {
1215 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
1217 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
1221 OPENSSL_free(authchunks);
1223 if (!auth_data || !auth_forward) {
1224 BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR);
1228 data->peer_auth_tested = 1;
1235 * dgram_sctp_write - send message on SCTP socket
1236 * @b: BIO to write to
1238 * @inl: amount of bytes in @in to send
1240 * Returns -1 on error or the sent amount of bytes on success
1242 static int dgram_sctp_write(BIO *b, const char *in, int inl)
1245 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1246 struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
1247 struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
1248 struct bio_dgram_sctp_sndinfo handshake_sinfo;
1249 struct iovec iov[1];
1251 struct cmsghdr *cmsg;
1252 # if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1253 char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
1254 CMSG_SPACE(sizeof(struct sctp_prinfo))];
1255 struct sctp_sndinfo *sndinfo;
1256 struct sctp_prinfo *prinfo;
1258 char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
1259 struct sctp_sndrcvinfo *sndrcvinfo;
1262 clear_socket_error();
1265 * If we're send anything else than application data, disable all user
1266 * parameters and flags.
1269 memset(&handshake_sinfo, 0, sizeof(handshake_sinfo));
1270 # ifdef SCTP_SACK_IMMEDIATELY
1271 handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
1273 sinfo = &handshake_sinfo;
1277 * If we have to send a shutdown alert message and the socket is not dry
1278 * yet, we have to save it and send it as soon as the socket gets dry.
1280 if (data->save_shutdown) {
1281 ret = BIO_dgram_sctp_wait_for_dry(b);
1287 data->saved_message.bio = b;
1288 if ((tmp = OPENSSL_malloc(inl)) == NULL) {
1289 BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE);
1292 OPENSSL_free(data->saved_message.data);
1293 data->saved_message.data = tmp;
1294 memcpy(data->saved_message.data, in, inl);
1295 data->saved_message.length = inl;
1300 iov[0].iov_base = (char *)in;
1301 iov[0].iov_len = inl;
1302 msg.msg_name = NULL;
1303 msg.msg_namelen = 0;
1306 msg.msg_control = (caddr_t) cmsgbuf;
1307 msg.msg_controllen = 0;
1309 # if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1310 cmsg = (struct cmsghdr *)cmsgbuf;
1311 cmsg->cmsg_level = IPPROTO_SCTP;
1312 cmsg->cmsg_type = SCTP_SNDINFO;
1313 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
1314 sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
1315 memset(sndinfo, 0, sizeof(*sndinfo));
1316 sndinfo->snd_sid = sinfo->snd_sid;
1317 sndinfo->snd_flags = sinfo->snd_flags;
1318 sndinfo->snd_ppid = sinfo->snd_ppid;
1319 sndinfo->snd_context = sinfo->snd_context;
1320 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
1323 (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
1324 cmsg->cmsg_level = IPPROTO_SCTP;
1325 cmsg->cmsg_type = SCTP_PRINFO;
1326 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
1327 prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
1328 memset(prinfo, 0, sizeof(*prinfo));
1329 prinfo->pr_policy = pinfo->pr_policy;
1330 prinfo->pr_value = pinfo->pr_value;
1331 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
1333 cmsg = (struct cmsghdr *)cmsgbuf;
1334 cmsg->cmsg_level = IPPROTO_SCTP;
1335 cmsg->cmsg_type = SCTP_SNDRCV;
1336 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
1337 sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1338 memset(sndrcvinfo, 0, sizeof(*sndrcvinfo));
1339 sndrcvinfo->sinfo_stream = sinfo->snd_sid;
1340 sndrcvinfo->sinfo_flags = sinfo->snd_flags;
1342 sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
1344 sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
1345 sndrcvinfo->sinfo_context = sinfo->snd_context;
1346 sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
1347 msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
1350 ret = sendmsg(b->num, &msg, 0);
1352 BIO_clear_retry_flags(b);
1354 if (BIO_dgram_should_retry(ret)) {
1355 BIO_set_retry_write(b);
1356 data->_errno = get_last_socket_error();
1362 static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1365 bio_dgram_sctp_data *data = NULL;
1366 socklen_t sockopt_len = 0;
1367 struct sctp_authkeyid authkeyid;
1368 struct sctp_authkey *authkey = NULL;
1370 data = (bio_dgram_sctp_data *) b->ptr;
1373 case BIO_CTRL_DGRAM_QUERY_MTU:
1375 * Set to maximum (2^14) and ignore user input to enable transport
1376 * protocol fragmentation. Returns always 2^14.
1381 case BIO_CTRL_DGRAM_SET_MTU:
1383 * Set to maximum (2^14) and ignore input to enable transport
1384 * protocol fragmentation. Returns always 2^14.
1389 case BIO_CTRL_DGRAM_SET_CONNECTED:
1390 case BIO_CTRL_DGRAM_CONNECT:
1391 /* Returns always -1. */
1394 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
1396 * SCTP doesn't need the DTLS timer Returns always 1.
1399 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
1401 * We allow transport protocol fragmentation so this is irrelevant
1405 case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
1407 data->in_handshake = 1;
1409 data->in_handshake = 0;
1412 setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY,
1413 &data->in_handshake, sizeof(int));
1415 case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
1417 * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise.
1420 /* Get active key */
1421 sockopt_len = sizeof(struct sctp_authkeyid);
1423 getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
1429 sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
1430 authkey = OPENSSL_malloc(sockopt_len);
1431 if (authkey == NULL) {
1435 memset(authkey, 0, sockopt_len);
1436 authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
1437 # ifndef __FreeBSD__
1439 * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3
1440 * and higher work without it.
1442 authkey->sca_keylength = 64;
1444 memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
1447 setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey,
1449 OPENSSL_free(authkey);
1454 /* Reset active key */
1455 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1456 &authkeyid, sizeof(struct sctp_authkeyid));
1461 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
1462 /* Returns 0 on success, -1 otherwise. */
1464 /* Get active key */
1465 sockopt_len = sizeof(struct sctp_authkeyid);
1467 getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
1472 /* Set active key */
1473 authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
1474 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1475 &authkeyid, sizeof(struct sctp_authkeyid));
1480 * CCS has been sent, so remember that and fall through to check if
1481 * we need to deactivate an old key
1485 case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
1486 /* Returns 0 on success, -1 otherwise. */
1489 * Has this command really been called or is this just a
1492 if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
1496 * CSS has been both, received and sent, so deactivate an old key
1498 if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
1499 /* Get active key */
1500 sockopt_len = sizeof(struct sctp_authkeyid);
1502 getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1503 &authkeyid, &sockopt_len);
1508 * Deactivate key or delete second last key if
1509 * SCTP_AUTHENTICATION_EVENT is not available.
1511 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1512 # ifdef SCTP_AUTH_DEACTIVATE_KEY
1513 sockopt_len = sizeof(struct sctp_authkeyid);
1514 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
1515 &authkeyid, sockopt_len);
1519 # ifndef SCTP_AUTHENTICATION_EVENT
1520 if (authkeyid.scact_keynumber > 0) {
1521 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1522 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1523 &authkeyid, sizeof(struct sctp_authkeyid));
1533 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
1534 /* Returns the size of the copied struct. */
1535 if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
1536 num = sizeof(struct bio_dgram_sctp_sndinfo);
1538 memcpy(ptr, &(data->sndinfo), num);
1541 case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
1542 /* Returns the size of the copied struct. */
1543 if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
1544 num = sizeof(struct bio_dgram_sctp_sndinfo);
1546 memcpy(&(data->sndinfo), ptr, num);
1548 case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
1549 /* Returns the size of the copied struct. */
1550 if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
1551 num = sizeof(struct bio_dgram_sctp_rcvinfo);
1553 memcpy(ptr, &data->rcvinfo, num);
1557 case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
1558 /* Returns the size of the copied struct. */
1559 if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
1560 num = sizeof(struct bio_dgram_sctp_rcvinfo);
1562 memcpy(&(data->rcvinfo), ptr, num);
1564 case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
1565 /* Returns the size of the copied struct. */
1566 if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
1567 num = sizeof(struct bio_dgram_sctp_prinfo);
1569 memcpy(ptr, &(data->prinfo), num);
1572 case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
1573 /* Returns the size of the copied struct. */
1574 if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
1575 num = sizeof(struct bio_dgram_sctp_prinfo);
1577 memcpy(&(data->prinfo), ptr, num);
1579 case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
1580 /* Returns always 1. */
1582 data->save_shutdown = 1;
1584 data->save_shutdown = 0;
1589 * Pass to default ctrl function to process SCTP unspecific commands
1591 ret = dgram_ctrl(b, cmd, num, ptr);
1597 int BIO_dgram_sctp_notification_cb(BIO *b,
1598 void (*handle_notifications) (BIO *bio,
1604 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1606 if (handle_notifications != NULL) {
1607 data->handle_notifications = handle_notifications;
1608 data->notification_context = context;
1616 * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event
1617 * @b: The BIO to check for the dry event
1619 * Wait until the peer confirms all packets have been received, and so that
1620 * our kernel doesn't have anything to send anymore. This is only received by
1621 * the peer's kernel, not the application.
1625 * 0 when not dry yet
1628 int BIO_dgram_sctp_wait_for_dry(BIO *b)
1633 union sctp_notification snp;
1637 struct sctp_event event;
1639 struct sctp_event_subscribe event;
1640 socklen_t eventsize;
1642 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1644 /* set sender dry event */
1646 memset(&event, 0, sizeof(event));
1647 event.se_assoc_id = 0;
1648 event.se_type = SCTP_SENDER_DRY_EVENT;
1651 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1652 sizeof(struct sctp_event));
1654 eventsize = sizeof(struct sctp_event_subscribe);
1655 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1659 event.sctp_sender_dry_event = 1;
1662 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1663 sizeof(struct sctp_event_subscribe));
1668 /* peek for notification */
1669 memset(&snp, 0, sizeof(snp));
1670 iov.iov_base = (char *)&snp;
1671 iov.iov_len = sizeof(union sctp_notification);
1672 msg.msg_name = NULL;
1673 msg.msg_namelen = 0;
1676 msg.msg_control = NULL;
1677 msg.msg_controllen = 0;
1680 n = recvmsg(b->num, &msg, MSG_PEEK);
1682 if ((n < 0) && (get_last_socket_error() != EAGAIN)
1683 && (get_last_socket_error() != EWOULDBLOCK))
1689 /* if we find a notification, process it and try again if necessary */
1690 while (msg.msg_flags & MSG_NOTIFICATION) {
1691 memset(&snp, 0, sizeof(snp));
1692 iov.iov_base = (char *)&snp;
1693 iov.iov_len = sizeof(union sctp_notification);
1694 msg.msg_name = NULL;
1695 msg.msg_namelen = 0;
1698 msg.msg_control = NULL;
1699 msg.msg_controllen = 0;
1702 n = recvmsg(b->num, &msg, 0);
1704 if ((n < 0) && (get_last_socket_error() != EAGAIN)
1705 && (get_last_socket_error() != EWOULDBLOCK))
1711 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
1714 /* disable sender dry event */
1716 memset(&event, 0, sizeof(event));
1717 event.se_assoc_id = 0;
1718 event.se_type = SCTP_SENDER_DRY_EVENT;
1721 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
1722 sizeof(struct sctp_event));
1724 eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
1726 getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1731 event.sctp_sender_dry_event = 0;
1734 setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
1735 sizeof(struct sctp_event_subscribe));
1740 # ifdef SCTP_AUTHENTICATION_EVENT
1741 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1742 dgram_sctp_handle_auth_free_key_event(b, &snp);
1745 if (data->handle_notifications != NULL)
1746 data->handle_notifications(b, data->notification_context,
1749 /* found notification, peek again */
1750 memset(&snp, 0, sizeof(snp));
1751 iov.iov_base = (char *)&snp;
1752 iov.iov_len = sizeof(union sctp_notification);
1753 msg.msg_name = NULL;
1754 msg.msg_namelen = 0;
1757 msg.msg_control = NULL;
1758 msg.msg_controllen = 0;
1761 /* if we have seen the dry already, don't wait */
1763 sockflags = fcntl(b->num, F_GETFL, 0);
1764 fcntl(b->num, F_SETFL, O_NONBLOCK);
1767 n = recvmsg(b->num, &msg, MSG_PEEK);
1770 fcntl(b->num, F_SETFL, sockflags);
1774 if ((n < 0) && (get_last_socket_error() != EAGAIN)
1775 && (get_last_socket_error() != EWOULDBLOCK))
1782 /* read anything else */
1786 int BIO_dgram_sctp_msg_waiting(BIO *b)
1789 union sctp_notification snp;
1792 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1794 /* Check if there are any messages waiting to be read */
1796 memset(&snp, 0, sizeof(snp));
1797 iov.iov_base = (char *)&snp;
1798 iov.iov_len = sizeof(union sctp_notification);
1799 msg.msg_name = NULL;
1800 msg.msg_namelen = 0;
1803 msg.msg_control = NULL;
1804 msg.msg_controllen = 0;
1807 sockflags = fcntl(b->num, F_GETFL, 0);
1808 fcntl(b->num, F_SETFL, O_NONBLOCK);
1809 n = recvmsg(b->num, &msg, MSG_PEEK);
1810 fcntl(b->num, F_SETFL, sockflags);
1812 /* if notification, process and try again */
1813 if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
1814 # ifdef SCTP_AUTHENTICATION_EVENT
1815 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1816 dgram_sctp_handle_auth_free_key_event(b, &snp);
1819 memset(&snp, 0, sizeof(snp));
1820 iov.iov_base = (char *)&snp;
1821 iov.iov_len = sizeof(union sctp_notification);
1822 msg.msg_name = NULL;
1823 msg.msg_namelen = 0;
1826 msg.msg_control = NULL;
1827 msg.msg_controllen = 0;
1829 n = recvmsg(b->num, &msg, 0);
1831 if (data->handle_notifications != NULL)
1832 data->handle_notifications(b, data->notification_context,
1836 } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
1838 /* Return 1 if there is a message to be read, return 0 otherwise. */
1845 static int dgram_sctp_puts(BIO *bp, const char *str)
1850 ret = dgram_sctp_write(bp, str, n);
1855 static int BIO_dgram_should_retry(int i)
1859 if ((i == 0) || (i == -1)) {
1860 err = get_last_socket_error();
1862 # if defined(OPENSSL_SYS_WINDOWS)
1864 * If the socket return value (i) is -1 and err is unexpectedly 0 at
1865 * this point, the error code was overwritten by another system call
1866 * before this error handling is called.
1870 return (BIO_dgram_non_fatal_error(err));
1875 int BIO_dgram_non_fatal_error(int err)
1878 # if defined(OPENSSL_SYS_WINDOWS)
1879 # if defined(WSAEWOULDBLOCK)
1880 case WSAEWOULDBLOCK:
1885 # ifdef WSAEWOULDBLOCK
1886 # if WSAEWOULDBLOCK != EWOULDBLOCK
1899 # if EWOULDBLOCK != EAGAIN
1924 static void get_current_time(struct timeval *t)
1926 # if defined(_WIN32)
1929 unsigned __int64 ul;
1934 SystemTimeToFileTime(&st, &now.ft);
1936 now.ul -= 116444736000000000ULL;
1938 now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
1940 t->tv_sec = (long)(now.ul / 10000000);
1941 t->tv_usec = ((int)(now.ul % 10000000)) / 10;
1942 # elif defined(OPENSSL_SYS_VMS)
1945 t->tv_sec = (long)tb.time;
1946 t->tv_usec = (long)tb.millitm * 1000;
1948 gettimeofday(t, NULL);