1 /* crypto/bio/bio_dgram.c */
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
6 /* ====================================================================
7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@OpenSSL.org.
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
35 * 6. Redistributions of any form whatsoever must retain the following
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
66 #include <openssl/bio.h>
67 #ifndef OPENSSL_NO_DGRAM
69 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
70 #include <sys/timeb.h>
73 #ifndef OPENSSL_NO_SCTP
74 #include <netinet/sctp.h>
76 #define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00
77 #define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
80 #ifdef OPENSSL_SYS_LINUX
81 #define IP_MTU 14 /* linux is lame */
85 #define sock_write SockWrite /* Watt-32 uses same names */
86 #define sock_read SockRead
87 #define sock_puts SockPuts
90 static int dgram_write(BIO
*h
, const char *buf
, int num
);
91 static int dgram_read(BIO
*h
, char *buf
, int size
);
92 static int dgram_puts(BIO
*h
, const char *str
);
93 static long dgram_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
94 static int dgram_new(BIO
*h
);
95 static int dgram_free(BIO
*data
);
96 static int dgram_clear(BIO
*bio
);
98 #ifndef OPENSSL_NO_SCTP
99 static int dgram_sctp_write(BIO
*h
, const char *buf
, int num
);
100 static int dgram_sctp_read(BIO
*h
, char *buf
, int size
);
101 static int dgram_sctp_puts(BIO
*h
, const char *str
);
102 static long dgram_sctp_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
103 static int dgram_sctp_new(BIO
*h
);
104 static int dgram_sctp_free(BIO
*data
);
105 #ifdef SCTP_AUTHENTICATION_EVENT
106 static void dgram_sctp_handle_auth_free_key_event(BIO
*b
, union sctp_notification
*snp
);
110 static int BIO_dgram_should_retry(int s
);
112 static void get_current_time(struct timeval
*t
);
114 static BIO_METHOD methods_dgramp
=
121 NULL
, /* dgram_gets, */
128 #ifndef OPENSSL_NO_SCTP
129 static BIO_METHOD methods_dgramp_sctp
=
132 "datagram sctp socket",
136 NULL
, /* dgram_gets, */
144 typedef struct bio_dgram_data_st
148 struct sockaddr_in sa_in
;
150 struct sockaddr_in6 sa_in6
;
153 unsigned int connected
;
156 struct timeval next_timeout
;
157 struct timeval socket_timeout
;
160 #ifndef OPENSSL_NO_SCTP
161 typedef struct bio_dgram_sctp_save_message_st
166 } bio_dgram_sctp_save_message
;
168 typedef struct bio_dgram_sctp_data_st
172 struct sockaddr_in sa_in
;
174 struct sockaddr_in6 sa_in6
;
177 unsigned int connected
;
180 struct bio_dgram_sctp_sndinfo sndinfo
;
181 struct bio_dgram_sctp_rcvinfo rcvinfo
;
182 struct bio_dgram_sctp_prinfo prinfo
;
183 void (*handle_notifications
)(BIO
*bio
, void *context
, void *buf
);
184 void* notification_context
;
189 int peer_auth_tested
;
190 bio_dgram_sctp_save_message saved_message
;
191 } bio_dgram_sctp_data
;
194 BIO_METHOD
*BIO_s_datagram(void)
196 return(&methods_dgramp
);
199 BIO
*BIO_new_dgram(int fd
, int close_flag
)
203 ret
=BIO_new(BIO_s_datagram());
204 if (ret
== NULL
) return(NULL
);
205 BIO_set_fd(ret
,fd
,close_flag
);
209 static int dgram_new(BIO
*bi
)
211 bio_dgram_data
*data
= NULL
;
215 data
= OPENSSL_malloc(sizeof(bio_dgram_data
));
218 memset(data
, 0x00, sizeof(bio_dgram_data
));
225 static int dgram_free(BIO
*a
)
227 bio_dgram_data
*data
;
229 if (a
== NULL
) return(0);
230 if ( ! dgram_clear(a
))
233 data
= (bio_dgram_data
*)a
->ptr
;
234 if(data
!= NULL
) OPENSSL_free(data
);
239 static int dgram_clear(BIO
*a
)
241 if (a
== NULL
) return(0);
254 static void dgram_adjust_rcv_timeout(BIO
*b
)
256 #if defined(SO_RCVTIMEO)
257 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
258 int sz
= sizeof(int);
260 /* Is a timer active? */
261 if (data
->next_timeout
.tv_sec
> 0 || data
->next_timeout
.tv_usec
> 0)
263 struct timeval timenow
, timeleft
;
265 /* Read current socket timeout */
266 #ifdef OPENSSL_SYS_WINDOWS
268 if (getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
269 (void*)&timeout
, &sz
) < 0)
270 { perror("getsockopt"); }
273 data
->socket_timeout
.tv_sec
= timeout
/ 1000;
274 data
->socket_timeout
.tv_usec
= (timeout
% 1000) * 1000;
277 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
278 &(data
->socket_timeout
), (void *)&sz
) < 0)
279 { perror("getsockopt"); }
282 /* Get current time */
283 get_current_time(&timenow
);
285 /* Calculate time left until timer expires */
286 memcpy(&timeleft
, &(data
->next_timeout
), sizeof(struct timeval
));
287 timeleft
.tv_sec
-= timenow
.tv_sec
;
288 timeleft
.tv_usec
-= timenow
.tv_usec
;
289 if (timeleft
.tv_usec
< 0)
292 timeleft
.tv_usec
+= 1000000;
295 if (timeleft
.tv_sec
< 0)
298 timeleft
.tv_usec
= 1;
301 /* Adjust socket timeout if next handhake message timer
302 * will expire earlier.
304 if ((data
->socket_timeout
.tv_sec
== 0 && data
->socket_timeout
.tv_usec
== 0) ||
305 (data
->socket_timeout
.tv_sec
> timeleft
.tv_sec
) ||
306 (data
->socket_timeout
.tv_sec
== timeleft
.tv_sec
&&
307 data
->socket_timeout
.tv_usec
>= timeleft
.tv_usec
))
309 #ifdef OPENSSL_SYS_WINDOWS
310 timeout
= timeleft
.tv_sec
* 1000 + timeleft
.tv_usec
/ 1000;
311 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
312 (void*)&timeout
, sizeof(timeout
)) < 0)
313 { perror("setsockopt"); }
315 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, &timeleft
,
316 sizeof(struct timeval
)) < 0)
317 { perror("setsockopt"); }
324 static void dgram_reset_rcv_timeout(BIO
*b
)
326 #if defined(SO_RCVTIMEO)
327 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
329 /* Is a timer active? */
330 if (data
->next_timeout
.tv_sec
> 0 || data
->next_timeout
.tv_usec
> 0)
332 #ifdef OPENSSL_SYS_WINDOWS
333 int timeout
= data
->socket_timeout
.tv_sec
* 1000 +
334 data
->socket_timeout
.tv_usec
/ 1000;
335 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
336 (void*)&timeout
, sizeof(timeout
)) < 0)
337 { perror("setsockopt"); }
339 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, &(data
->socket_timeout
),
340 sizeof(struct timeval
)) < 0)
341 { perror("setsockopt"); }
347 static int dgram_read(BIO
*b
, char *out
, int outl
)
350 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
354 * See commentary in b_sock.c. <appro>
356 union { size_t s
; int i
; } len
;
359 struct sockaddr_in sa_in
;
361 struct sockaddr_in6 sa_in6
;
367 sa
.len
.i
=sizeof(sa
.peer
);
371 clear_socket_error();
372 memset(&sa
.peer
, 0x00, sizeof(sa
.peer
));
373 dgram_adjust_rcv_timeout(b
);
374 ret
=recvfrom(b
->num
,out
,outl
,0,&sa
.peer
.sa
,(void *)&sa
.len
);
375 if (sizeof(sa
.len
.i
)!=sizeof(sa
.len
.s
) && sa
.len
.i
==0)
377 OPENSSL_assert(sa
.len
.s
<=sizeof(sa
.peer
));
378 sa
.len
.i
= (int)sa
.len
.s
;
381 if ( ! data
->connected
&& ret
>= 0)
382 BIO_ctrl(b
, BIO_CTRL_DGRAM_SET_PEER
, 0, &sa
.peer
);
384 BIO_clear_retry_flags(b
);
387 if (BIO_dgram_should_retry(ret
))
389 BIO_set_retry_read(b
);
390 data
->_errno
= get_last_socket_error();
394 dgram_reset_rcv_timeout(b
);
399 static int dgram_write(BIO
*b
, const char *in
, int inl
)
402 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
403 clear_socket_error();
405 if ( data
->connected
)
406 ret
=writesocket(b
->num
,in
,inl
);
409 int peerlen
= sizeof(data
->peer
);
411 if (data
->peer
.sa
.sa_family
== AF_INET
)
412 peerlen
= sizeof(data
->peer
.sa_in
);
414 else if (data
->peer
.sa
.sa_family
== AF_INET6
)
415 peerlen
= sizeof(data
->peer
.sa_in6
);
417 #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
418 ret
=sendto(b
->num
, (char *)in
, inl
, 0, &data
->peer
.sa
, peerlen
);
420 ret
=sendto(b
->num
, in
, inl
, 0, &data
->peer
.sa
, peerlen
);
424 BIO_clear_retry_flags(b
);
427 if (BIO_dgram_should_retry(ret
))
429 BIO_set_retry_write(b
);
430 data
->_errno
= get_last_socket_error();
432 #if 0 /* higher layers are responsible for querying MTU, if necessary */
433 if ( data
->_errno
== EMSGSIZE
)
434 /* retrieve the new MTU */
435 BIO_ctrl(b
, BIO_CTRL_DGRAM_QUERY_MTU
, 0, NULL
);
442 static long dgram_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
446 struct sockaddr
*to
= NULL
;
447 bio_dgram_data
*data
= NULL
;
448 #if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
449 long sockopt_val
= 0;
450 unsigned int sockopt_len
= 0;
452 #ifdef OPENSSL_SYS_LINUX
456 struct sockaddr_in s4
;
458 struct sockaddr_in6 s6
;
463 data
= (bio_dgram_data
*)b
->ptr
;
469 case BIO_C_FILE_SEEK
:
472 case BIO_C_FILE_TELL
:
478 b
->num
= *((int *)ptr
);
479 b
->shutdown
=(int)num
;
486 if (ip
!= NULL
) *ip
=b
->num
;
492 case BIO_CTRL_GET_CLOSE
:
495 case BIO_CTRL_SET_CLOSE
:
496 b
->shutdown
=(int)num
;
498 case BIO_CTRL_PENDING
:
499 case BIO_CTRL_WPENDING
:
506 case BIO_CTRL_DGRAM_CONNECT
:
507 to
= (struct sockaddr
*)ptr
;
509 if (connect(b
->num
, to
, sizeof(struct sockaddr
)) < 0)
510 { perror("connect"); ret
= 0; }
514 switch (to
->sa_family
)
517 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
521 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
525 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
532 /* (Linux)kernel sets DF bit on outgoing IP packets */
533 case BIO_CTRL_DGRAM_MTU_DISCOVER
:
534 #ifdef OPENSSL_SYS_LINUX
535 addr_len
= (socklen_t
)sizeof(addr
);
536 memset((void *)&addr
, 0, sizeof(addr
));
537 if (getsockname(b
->num
, &addr
.sa
, &addr_len
) < 0)
542 sockopt_len
= sizeof(sockopt_val
);
543 switch (addr
.sa
.sa_family
)
546 sockopt_val
= IP_PMTUDISC_DO
;
547 if ((ret
= setsockopt(b
->num
, IPPROTO_IP
, IP_MTU_DISCOVER
,
548 &sockopt_val
, sizeof(sockopt_val
))) < 0)
549 perror("setsockopt");
551 #if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
553 sockopt_val
= IPV6_PMTUDISC_DO
;
554 if ((ret
= setsockopt(b
->num
, IPPROTO_IPV6
, IPV6_MTU_DISCOVER
,
555 &sockopt_val
, sizeof(sockopt_val
))) < 0)
556 perror("setsockopt");
567 case BIO_CTRL_DGRAM_QUERY_MTU
:
568 #ifdef OPENSSL_SYS_LINUX
569 addr_len
= (socklen_t
)sizeof(addr
);
570 memset((void *)&addr
, 0, sizeof(addr
));
571 if (getsockname(b
->num
, &addr
.sa
, &addr_len
) < 0)
576 sockopt_len
= sizeof(sockopt_val
);
577 switch (addr
.sa
.sa_family
)
580 if ((ret
= getsockopt(b
->num
, IPPROTO_IP
, IP_MTU
, (void *)&sockopt_val
,
581 &sockopt_len
)) < 0 || sockopt_val
< 0)
587 /* we assume that the transport protocol is UDP and no
588 * IP options are used.
590 data
->mtu
= sockopt_val
- 8 - 20;
594 #if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
596 if ((ret
= getsockopt(b
->num
, IPPROTO_IPV6
, IPV6_MTU
, (void *)&sockopt_val
,
597 &sockopt_len
)) < 0 || sockopt_val
< 0)
603 /* we assume that the transport protocol is UDP and no
604 * IPV6 options are used.
606 data
->mtu
= sockopt_val
- 8 - 40;
619 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU
:
620 switch (data
->peer
.sa
.sa_family
)
627 #ifdef IN6_IS_ADDR_V4MAPPED
628 if (IN6_IS_ADDR_V4MAPPED(&data
->peer
.sa_in6
.sin6_addr
))
640 case BIO_CTRL_DGRAM_GET_MTU
:
643 case BIO_CTRL_DGRAM_SET_MTU
:
647 case BIO_CTRL_DGRAM_SET_CONNECTED
:
648 to
= (struct sockaddr
*)ptr
;
653 switch (to
->sa_family
)
656 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
660 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
664 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
671 memset(&(data
->peer
), 0x00, sizeof(data
->peer
));
674 case BIO_CTRL_DGRAM_GET_PEER
:
675 switch (data
->peer
.sa
.sa_family
)
678 ret
=sizeof(data
->peer
.sa_in
);
682 ret
=sizeof(data
->peer
.sa_in6
);
686 ret
=sizeof(data
->peer
.sa
);
689 if (num
==0 || num
>ret
)
691 memcpy(ptr
,&data
->peer
,(ret
=num
));
693 case BIO_CTRL_DGRAM_SET_PEER
:
694 to
= (struct sockaddr
*) ptr
;
695 switch (to
->sa_family
)
698 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
702 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
706 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
710 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
:
711 memcpy(&(data
->next_timeout
), ptr
, sizeof(struct timeval
));
713 #if defined(SO_RCVTIMEO)
714 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT
:
715 #ifdef OPENSSL_SYS_WINDOWS
717 struct timeval
*tv
= (struct timeval
*)ptr
;
718 int timeout
= tv
->tv_sec
* 1000 + tv
->tv_usec
/1000;
719 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
720 (void*)&timeout
, sizeof(timeout
)) < 0)
721 { perror("setsockopt"); ret
= -1; }
724 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, ptr
,
725 sizeof(struct timeval
)) < 0)
726 { perror("setsockopt"); ret
= -1; }
729 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT
:
730 #ifdef OPENSSL_SYS_WINDOWS
732 int timeout
, sz
= sizeof(timeout
);
733 struct timeval
*tv
= (struct timeval
*)ptr
;
734 if (getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
735 (void*)&timeout
, &sz
) < 0)
736 { perror("getsockopt"); ret
= -1; }
739 tv
->tv_sec
= timeout
/ 1000;
740 tv
->tv_usec
= (timeout
% 1000) * 1000;
745 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
746 ptr
, (void *)&ret
) < 0)
747 { perror("getsockopt"); ret
= -1; }
751 #if defined(SO_SNDTIMEO)
752 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT
:
753 #ifdef OPENSSL_SYS_WINDOWS
755 struct timeval
*tv
= (struct timeval
*)ptr
;
756 int timeout
= tv
->tv_sec
* 1000 + tv
->tv_usec
/1000;
757 if (setsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
758 (void*)&timeout
, sizeof(timeout
)) < 0)
759 { perror("setsockopt"); ret
= -1; }
762 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
, ptr
,
763 sizeof(struct timeval
)) < 0)
764 { perror("setsockopt"); ret
= -1; }
767 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT
:
768 #ifdef OPENSSL_SYS_WINDOWS
770 int timeout
, sz
= sizeof(timeout
);
771 struct timeval
*tv
= (struct timeval
*)ptr
;
772 if (getsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
773 (void*)&timeout
, &sz
) < 0)
774 { perror("getsockopt"); ret
= -1; }
777 tv
->tv_sec
= timeout
/ 1000;
778 tv
->tv_usec
= (timeout
% 1000) * 1000;
783 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
784 ptr
, (void *)&ret
) < 0)
785 { perror("getsockopt"); ret
= -1; }
789 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP
:
791 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP
:
792 #ifdef OPENSSL_SYS_WINDOWS
793 if ( data
->_errno
== WSAETIMEDOUT
)
795 if ( data
->_errno
== EAGAIN
)
805 case BIO_CTRL_DGRAM_MTU_EXCEEDED
:
806 if ( data
->_errno
== EMSGSIZE
)
822 static int dgram_puts(BIO
*bp
, const char *str
)
827 ret
=dgram_write(bp
,str
,n
);
831 #ifndef OPENSSL_NO_SCTP
832 BIO_METHOD
*BIO_s_datagram_sctp(void)
834 return(&methods_dgramp_sctp
);
837 BIO
*BIO_new_dgram_sctp(int fd
, int close_flag
)
840 int ret
, optval
= 20000;
841 int auth_data
= 0, auth_forward
= 0;
843 struct sctp_authchunk auth
;
844 struct sctp_authchunks
*authchunks
;
845 socklen_t sockopt_len
;
846 #ifdef SCTP_AUTHENTICATION_EVENT
848 struct sctp_event event
;
850 struct sctp_event_subscribe event
;
854 bio
=BIO_new(BIO_s_datagram_sctp());
855 if (bio
== NULL
) return(NULL
);
856 BIO_set_fd(bio
,fd
,close_flag
);
858 /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
859 auth
.sauth_chunk
= OPENSSL_SCTP_DATA_CHUNK_TYPE
;
860 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_AUTH_CHUNK
, &auth
, sizeof(struct sctp_authchunk
));
861 OPENSSL_assert(ret
>= 0);
862 auth
.sauth_chunk
= OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
;
863 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_AUTH_CHUNK
, &auth
, sizeof(struct sctp_authchunk
));
864 OPENSSL_assert(ret
>= 0);
866 /* Test if activation was successful. When using accept(),
867 * SCTP-AUTH has to be activated for the listening socket
868 * already, otherwise the connected socket won't use it. */
869 sockopt_len
= (socklen_t
)(sizeof(sctp_assoc_t
) + 256 * sizeof(uint8_t));
870 authchunks
= OPENSSL_malloc(sockopt_len
);
871 memset(authchunks
, 0, sizeof(sockopt_len
));
872 ret
= getsockopt(fd
, IPPROTO_SCTP
, SCTP_LOCAL_AUTH_CHUNKS
, authchunks
, &sockopt_len
);
873 OPENSSL_assert(ret
>= 0);
875 for (p
= (unsigned char*) authchunks
+ sizeof(sctp_assoc_t
);
876 p
< (unsigned char*) authchunks
+ sockopt_len
;
877 p
+= sizeof(uint8_t))
879 if (*p
== OPENSSL_SCTP_DATA_CHUNK_TYPE
) auth_data
= 1;
880 if (*p
== OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
) auth_forward
= 1;
883 OPENSSL_free(authchunks
);
885 OPENSSL_assert(auth_data
);
886 OPENSSL_assert(auth_forward
);
888 #ifdef SCTP_AUTHENTICATION_EVENT
890 memset(&event
, 0, sizeof(struct sctp_event
));
891 event
.se_assoc_id
= 0;
892 event
.se_type
= SCTP_AUTHENTICATION_EVENT
;
894 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
895 OPENSSL_assert(ret
>= 0);
897 sockopt_len
= (socklen_t
) sizeof(struct sctp_event_subscribe
);
898 ret
= getsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &sockopt_len
);
899 OPENSSL_assert(ret
>= 0);
901 event
.sctp_authentication_event
= 1;
903 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
904 OPENSSL_assert(ret
>= 0);
908 /* Disable partial delivery by setting the min size
909 * larger than the max record size of 2^14 + 2048 + 13
911 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_PARTIAL_DELIVERY_POINT
, &optval
, sizeof(optval
));
912 OPENSSL_assert(ret
>= 0);
917 int BIO_dgram_is_sctp(BIO
*bio
)
919 return (BIO_method_type(bio
) == BIO_TYPE_DGRAM_SCTP
);
922 static int dgram_sctp_new(BIO
*bi
)
924 bio_dgram_sctp_data
*data
= NULL
;
928 data
= OPENSSL_malloc(sizeof(bio_dgram_sctp_data
));
931 memset(data
, 0x00, sizeof(bio_dgram_sctp_data
));
932 #ifdef SCTP_PR_SCTP_NONE
933 data
->prinfo
.pr_policy
= SCTP_PR_SCTP_NONE
;
941 static int dgram_sctp_free(BIO
*a
)
943 bio_dgram_sctp_data
*data
;
945 if (a
== NULL
) return(0);
946 if ( ! dgram_clear(a
))
949 data
= (bio_dgram_sctp_data
*)a
->ptr
;
950 if(data
!= NULL
) OPENSSL_free(data
);
955 #ifdef SCTP_AUTHENTICATION_EVENT
956 void dgram_sctp_handle_auth_free_key_event(BIO
*b
, union sctp_notification
*snp
)
958 unsigned int sockopt_len
= 0;
960 struct sctp_authkey_event
* authkeyevent
= &snp
->sn_auth_event
;
962 if (authkeyevent
->auth_indication
== SCTP_AUTH_FREE_KEY
)
964 struct sctp_authkeyid authkeyid
;
967 authkeyid
.scact_keynumber
= authkeyevent
->auth_keynumber
;
968 sockopt_len
= sizeof(struct sctp_authkeyid
);
969 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DELETE_KEY
,
970 &authkeyid
, sockopt_len
);
975 static int dgram_sctp_read(BIO
*b
, char *out
, int outl
)
977 int ret
= 0, n
= 0, i
, optval
;
979 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
980 union sctp_notification
*snp
;
983 struct cmsghdr
*cmsg
;
988 clear_socket_error();
992 memset(&data
->rcvinfo
, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo
));
999 msg
.msg_control
= cmsgbuf
;
1000 msg
.msg_controllen
= 512;
1002 n
= recvmsg(b
->num
, &msg
, 0);
1004 if (msg
.msg_controllen
> 0)
1006 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
; cmsg
= CMSG_NXTHDR(&msg
, cmsg
))
1008 if (cmsg
->cmsg_level
!= IPPROTO_SCTP
)
1011 if (cmsg
->cmsg_type
== SCTP_RCVINFO
)
1013 struct sctp_rcvinfo
*rcvinfo
;
1015 rcvinfo
= (struct sctp_rcvinfo
*)CMSG_DATA(cmsg
);
1016 data
->rcvinfo
.rcv_sid
= rcvinfo
->rcv_sid
;
1017 data
->rcvinfo
.rcv_ssn
= rcvinfo
->rcv_ssn
;
1018 data
->rcvinfo
.rcv_flags
= rcvinfo
->rcv_flags
;
1019 data
->rcvinfo
.rcv_ppid
= rcvinfo
->rcv_ppid
;
1020 data
->rcvinfo
.rcv_tsn
= rcvinfo
->rcv_tsn
;
1021 data
->rcvinfo
.rcv_cumtsn
= rcvinfo
->rcv_cumtsn
;
1022 data
->rcvinfo
.rcv_context
= rcvinfo
->rcv_context
;
1026 if (cmsg
->cmsg_type
== SCTP_SNDRCV
)
1028 struct sctp_sndrcvinfo
*sndrcvinfo
;
1030 sndrcvinfo
= (struct sctp_sndrcvinfo
*)CMSG_DATA(cmsg
);
1031 data
->rcvinfo
.rcv_sid
= sndrcvinfo
->sinfo_stream
;
1032 data
->rcvinfo
.rcv_ssn
= sndrcvinfo
->sinfo_ssn
;
1033 data
->rcvinfo
.rcv_flags
= sndrcvinfo
->sinfo_flags
;
1034 data
->rcvinfo
.rcv_ppid
= sndrcvinfo
->sinfo_ppid
;
1035 data
->rcvinfo
.rcv_tsn
= sndrcvinfo
->sinfo_tsn
;
1036 data
->rcvinfo
.rcv_cumtsn
= sndrcvinfo
->sinfo_cumtsn
;
1037 data
->rcvinfo
.rcv_context
= sndrcvinfo
->sinfo_context
;
1050 if (msg
.msg_flags
& MSG_NOTIFICATION
)
1052 snp
= (union sctp_notification
*) out
;
1053 if (snp
->sn_header
.sn_type
== SCTP_SENDER_DRY_EVENT
)
1056 struct sctp_event event
;
1058 struct sctp_event_subscribe event
;
1059 socklen_t eventsize
;
1061 /* If a message has been delayed until the socket
1062 * is dry, it can be sent now.
1064 if (data
->saved_message
.length
> 0)
1066 dgram_sctp_write(data
->saved_message
.bio
, data
->saved_message
.data
,
1067 data
->saved_message
.length
);
1068 OPENSSL_free(data
->saved_message
.data
);
1069 data
->saved_message
.length
= 0;
1072 /* disable sender dry event */
1074 memset(&event
, 0, sizeof(struct sctp_event
));
1075 event
.se_assoc_id
= 0;
1076 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1078 i
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1079 OPENSSL_assert(i
>= 0);
1081 eventsize
= sizeof(struct sctp_event_subscribe
);
1082 i
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1083 OPENSSL_assert(i
>= 0);
1085 event
.sctp_sender_dry_event
= 0;
1087 i
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1088 OPENSSL_assert(i
>= 0);
1092 #ifdef SCTP_AUTHENTICATION_EVENT
1093 if (snp
->sn_header
.sn_type
== SCTP_AUTHENTICATION_EVENT
)
1094 dgram_sctp_handle_auth_free_key_event(b
, snp
);
1097 if (data
->handle_notifications
!= NULL
)
1098 data
->handle_notifications(b
, data
->notification_context
, (void*) out
);
1100 memset(out
, 0, outl
);
1105 while ((msg
.msg_flags
& MSG_NOTIFICATION
) && (msg
.msg_flags
& MSG_EOR
) && (ret
< outl
));
1107 if (ret
> 0 && !(msg
.msg_flags
& MSG_EOR
))
1109 /* Partial message read, this should never happen! */
1111 /* The buffer was too small, this means the peer sent
1112 * a message that was larger than allowed. */
1116 /* Test if socket buffer can handle max record
1117 * size (2^14 + 2048 + 13)
1119 optlen
= (socklen_t
) sizeof(int);
1120 ret
= getsockopt(b
->num
, SOL_SOCKET
, SO_RCVBUF
, &optval
, &optlen
);
1121 OPENSSL_assert(ret
>= 0);
1122 OPENSSL_assert(optval
>= 18445);
1124 /* Test if SCTP doesn't partially deliver below
1125 * max record size (2^14 + 2048 + 13)
1127 optlen
= (socklen_t
) sizeof(int);
1128 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_PARTIAL_DELIVERY_POINT
,
1130 OPENSSL_assert(ret
>= 0);
1131 OPENSSL_assert(optval
>= 18445);
1133 /* Partially delivered notification??? Probably a bug.... */
1134 OPENSSL_assert(!(msg
.msg_flags
& MSG_NOTIFICATION
));
1136 /* Everything seems ok till now, so it's most likely
1137 * a message dropped by PR-SCTP.
1139 memset(out
, 0, outl
);
1140 BIO_set_retry_read(b
);
1144 BIO_clear_retry_flags(b
);
1147 if (BIO_dgram_should_retry(ret
))
1149 BIO_set_retry_read(b
);
1150 data
->_errno
= get_last_socket_error();
1154 /* Test if peer uses SCTP-AUTH before continuing */
1155 if (!data
->peer_auth_tested
)
1157 int ii
, auth_data
= 0, auth_forward
= 0;
1159 struct sctp_authchunks
*authchunks
;
1161 optlen
= (socklen_t
)(sizeof(sctp_assoc_t
) + 256 * sizeof(uint8_t));
1162 authchunks
= OPENSSL_malloc(optlen
);
1163 memset(authchunks
, 0, sizeof(optlen
));
1164 ii
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_PEER_AUTH_CHUNKS
, authchunks
, &optlen
);
1165 OPENSSL_assert(ii
>= 0);
1167 for (p
= (unsigned char*) authchunks
+ sizeof(sctp_assoc_t
);
1168 p
< (unsigned char*) authchunks
+ optlen
;
1169 p
+= sizeof(uint8_t))
1171 if (*p
== OPENSSL_SCTP_DATA_CHUNK_TYPE
) auth_data
= 1;
1172 if (*p
== OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
) auth_forward
= 1;
1175 OPENSSL_free(authchunks
);
1177 if (!auth_data
|| !auth_forward
)
1179 BIOerr(BIO_F_DGRAM_SCTP_READ
,BIO_R_CONNECT_ERROR
);
1183 data
->peer_auth_tested
= 1;
1189 static int dgram_sctp_write(BIO
*b
, const char *in
, int inl
)
1192 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1193 struct bio_dgram_sctp_sndinfo
*sinfo
= &(data
->sndinfo
);
1194 struct bio_dgram_sctp_prinfo
*pinfo
= &(data
->prinfo
);
1195 struct bio_dgram_sctp_sndinfo handshake_sinfo
;
1196 struct iovec iov
[1];
1198 struct cmsghdr
*cmsg
;
1199 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1200 char cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndinfo
)) + CMSG_SPACE(sizeof(struct sctp_prinfo
))];
1201 struct sctp_sndinfo
*sndinfo
;
1202 struct sctp_prinfo
*prinfo
;
1204 char cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo
))];
1205 struct sctp_sndrcvinfo
*sndrcvinfo
;
1208 clear_socket_error();
1210 /* If we're send anything else than application data,
1211 * disable all user parameters and flags.
1214 memset(&handshake_sinfo
, 0x00, sizeof(struct bio_dgram_sctp_sndinfo
));
1215 #ifdef SCTP_SACK_IMMEDIATELY
1216 handshake_sinfo
.snd_flags
= SCTP_SACK_IMMEDIATELY
;
1218 sinfo
= &handshake_sinfo
;
1221 /* If we have to send a shutdown alert message and the
1222 * socket is not dry yet, we have to save it and send it
1223 * as soon as the socket gets dry.
1225 if (data
->save_shutdown
&& !BIO_dgram_sctp_wait_for_dry(b
))
1227 data
->saved_message
.bio
= b
;
1228 data
->saved_message
.length
= inl
;
1229 data
->saved_message
.data
= OPENSSL_malloc(inl
);
1230 memcpy(data
->saved_message
.data
, in
, inl
);
1234 iov
[0].iov_base
= (char *)in
;
1235 iov
[0].iov_len
= inl
;
1236 msg
.msg_name
= NULL
;
1237 msg
.msg_namelen
= 0;
1240 msg
.msg_control
= (caddr_t
)cmsgbuf
;
1241 msg
.msg_controllen
= 0;
1243 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1244 cmsg
= (struct cmsghdr
*)cmsgbuf
;
1245 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1246 cmsg
->cmsg_type
= SCTP_SNDINFO
;
1247 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_sndinfo
));
1248 sndinfo
= (struct sctp_sndinfo
*)CMSG_DATA(cmsg
);
1249 memset(sndinfo
, 0, sizeof(struct sctp_sndinfo
));
1250 sndinfo
->snd_sid
= sinfo
->snd_sid
;
1251 sndinfo
->snd_flags
= sinfo
->snd_flags
;
1252 sndinfo
->snd_ppid
= sinfo
->snd_ppid
;
1253 sndinfo
->snd_context
= sinfo
->snd_context
;
1254 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_sndinfo
));
1256 cmsg
= (struct cmsghdr
*)&cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndinfo
))];
1257 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1258 cmsg
->cmsg_type
= SCTP_PRINFO
;
1259 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_prinfo
));
1260 prinfo
= (struct sctp_prinfo
*)CMSG_DATA(cmsg
);
1261 memset(prinfo
, 0, sizeof(struct sctp_prinfo
));
1262 prinfo
->pr_policy
= pinfo
->pr_policy
;
1263 prinfo
->pr_value
= pinfo
->pr_value
;
1264 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_prinfo
));
1266 cmsg
= (struct cmsghdr
*)cmsgbuf
;
1267 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1268 cmsg
->cmsg_type
= SCTP_SNDRCV
;
1269 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_sndrcvinfo
));
1270 sndrcvinfo
= (struct sctp_sndrcvinfo
*)CMSG_DATA(cmsg
);
1271 memset(sndrcvinfo
, 0, sizeof(struct sctp_sndrcvinfo
));
1272 sndrcvinfo
->sinfo_stream
= sinfo
->snd_sid
;
1273 sndrcvinfo
->sinfo_flags
= sinfo
->snd_flags
;
1275 sndrcvinfo
->sinfo_flags
|= pinfo
->pr_policy
;
1277 sndrcvinfo
->sinfo_ppid
= sinfo
->snd_ppid
;
1278 sndrcvinfo
->sinfo_context
= sinfo
->snd_context
;
1279 sndrcvinfo
->sinfo_timetolive
= pinfo
->pr_value
;
1280 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_sndrcvinfo
));
1283 ret
= sendmsg(b
->num
, &msg
, 0);
1285 BIO_clear_retry_flags(b
);
1288 if (BIO_dgram_should_retry(ret
))
1290 BIO_set_retry_write(b
);
1291 data
->_errno
= get_last_socket_error();
1297 static long dgram_sctp_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
1300 bio_dgram_sctp_data
*data
= NULL
;
1301 unsigned int sockopt_len
= 0;
1302 struct sctp_authkeyid authkeyid
;
1303 struct sctp_authkey
*authkey
;
1305 data
= (bio_dgram_sctp_data
*)b
->ptr
;
1309 case BIO_CTRL_DGRAM_QUERY_MTU
:
1310 /* Set to maximum (2^14)
1311 * and ignore user input to enable transport
1312 * protocol fragmentation.
1313 * Returns always 2^14.
1318 case BIO_CTRL_DGRAM_SET_MTU
:
1319 /* Set to maximum (2^14)
1320 * and ignore input to enable transport
1321 * protocol fragmentation.
1322 * Returns always 2^14.
1327 case BIO_CTRL_DGRAM_SET_CONNECTED
:
1328 case BIO_CTRL_DGRAM_CONNECT
:
1329 /* Returns always -1. */
1332 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
:
1333 /* SCTP doesn't need the DTLS timer
1337 case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE
:
1339 data
->in_handshake
= 1;
1341 data
->in_handshake
= 0;
1343 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_NODELAY
, &data
->in_handshake
, sizeof(int));
1345 case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY
:
1346 /* New shared key for SCTP AUTH.
1347 * Returns 0 on success, -1 otherwise.
1350 /* Get active key */
1351 sockopt_len
= sizeof(struct sctp_authkeyid
);
1352 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1356 sockopt_len
= sizeof(struct sctp_authkey
) + 64 * sizeof(uint8_t);
1357 authkey
= OPENSSL_malloc(sockopt_len
);
1358 memset(authkey
, 0x00, sockopt_len
);
1359 authkey
->sca_keynumber
= authkeyid
.scact_keynumber
+ 1;
1361 /* This field is missing in FreeBSD 8.2 and earlier,
1362 * and FreeBSD 8.3 and higher work without it.
1364 authkey
->sca_keylength
= 64;
1366 memcpy(&authkey
->sca_key
[0], ptr
, 64 * sizeof(uint8_t));
1368 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_KEY
, authkey
, sockopt_len
);
1371 /* Reset active key */
1372 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
,
1373 &authkeyid
, sizeof(struct sctp_authkeyid
));
1377 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY
:
1378 /* Returns 0 on success, -1 otherwise. */
1380 /* Get active key */
1381 sockopt_len
= sizeof(struct sctp_authkeyid
);
1382 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1385 /* Set active key */
1386 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
+ 1;
1387 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
,
1388 &authkeyid
, sizeof(struct sctp_authkeyid
));
1391 /* CCS has been sent, so remember that and fall through
1392 * to check if we need to deactivate an old key
1396 case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD
:
1397 /* Returns 0 on success, -1 otherwise. */
1399 /* Has this command really been called or is this just a fall-through? */
1400 if (cmd
== BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD
)
1403 /* CSS has been both, received and sent, so deactivate an old key */
1404 if (data
->ccs_rcvd
== 1 && data
->ccs_sent
== 1)
1406 /* Get active key */
1407 sockopt_len
= sizeof(struct sctp_authkeyid
);
1408 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1411 /* Deactivate key or delete second last key if
1412 * SCTP_AUTHENTICATION_EVENT is not available.
1414 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
- 1;
1415 #ifdef SCTP_AUTH_DEACTIVATE_KEY
1416 sockopt_len
= sizeof(struct sctp_authkeyid
);
1417 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DEACTIVATE_KEY
,
1418 &authkeyid
, sockopt_len
);
1421 #ifndef SCTP_AUTHENTICATION_EVENT
1422 if (authkeyid
.scact_keynumber
> 0)
1424 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
- 1;
1425 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DELETE_KEY
,
1426 &authkeyid
, sizeof(struct sctp_authkeyid
));
1435 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO
:
1436 /* Returns the size of the copied struct. */
1437 if (num
> (long) sizeof(struct bio_dgram_sctp_sndinfo
))
1438 num
= sizeof(struct bio_dgram_sctp_sndinfo
);
1440 memcpy(ptr
, &(data
->sndinfo
), num
);
1443 case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO
:
1444 /* Returns the size of the copied struct. */
1445 if (num
> (long) sizeof(struct bio_dgram_sctp_sndinfo
))
1446 num
= sizeof(struct bio_dgram_sctp_sndinfo
);
1448 memcpy(&(data
->sndinfo
), ptr
, num
);
1450 case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO
:
1451 /* Returns the size of the copied struct. */
1452 if (num
> (long) sizeof(struct bio_dgram_sctp_rcvinfo
))
1453 num
= sizeof(struct bio_dgram_sctp_rcvinfo
);
1455 memcpy(ptr
, &data
->rcvinfo
, num
);
1459 case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO
:
1460 /* Returns the size of the copied struct. */
1461 if (num
> (long) sizeof(struct bio_dgram_sctp_rcvinfo
))
1462 num
= sizeof(struct bio_dgram_sctp_rcvinfo
);
1464 memcpy(&(data
->rcvinfo
), ptr
, num
);
1466 case BIO_CTRL_DGRAM_SCTP_GET_PRINFO
:
1467 /* Returns the size of the copied struct. */
1468 if (num
> (long) sizeof(struct bio_dgram_sctp_prinfo
))
1469 num
= sizeof(struct bio_dgram_sctp_prinfo
);
1471 memcpy(ptr
, &(data
->prinfo
), num
);
1474 case BIO_CTRL_DGRAM_SCTP_SET_PRINFO
:
1475 /* Returns the size of the copied struct. */
1476 if (num
> (long) sizeof(struct bio_dgram_sctp_prinfo
))
1477 num
= sizeof(struct bio_dgram_sctp_prinfo
);
1479 memcpy(&(data
->prinfo
), ptr
, num
);
1481 case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN
:
1482 /* Returns always 1. */
1484 data
->save_shutdown
= 1;
1486 data
->save_shutdown
= 0;
1490 /* Pass to default ctrl function to
1491 * process SCTP unspecific commands
1493 ret
=dgram_ctrl(b
, cmd
, num
, ptr
);
1499 int BIO_dgram_sctp_notification_cb(BIO
*b
,
1500 void (*handle_notifications
)(BIO
*bio
, void *context
, void *buf
),
1503 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*) b
->ptr
;
1505 if (handle_notifications
!= NULL
)
1507 data
->handle_notifications
= handle_notifications
;
1508 data
->notification_context
= context
;
1516 int BIO_dgram_sctp_wait_for_dry(BIO
*b
)
1519 int n
, sockflags
, ret
;
1520 union sctp_notification snp
;
1524 struct sctp_event event
;
1526 struct sctp_event_subscribe event
;
1527 socklen_t eventsize
;
1529 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1531 /* set sender dry event */
1533 memset(&event
, 0, sizeof(struct sctp_event
));
1534 event
.se_assoc_id
= 0;
1535 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1537 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1539 eventsize
= sizeof(struct sctp_event_subscribe
);
1540 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1544 event
.sctp_sender_dry_event
= 1;
1546 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1551 /* peek for notification */
1552 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1553 iov
.iov_base
= (char *)&snp
;
1554 iov
.iov_len
= sizeof(union sctp_notification
);
1555 msg
.msg_name
= NULL
;
1556 msg
.msg_namelen
= 0;
1559 msg
.msg_control
= NULL
;
1560 msg
.msg_controllen
= 0;
1563 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1566 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1572 /* if we find a notification, process it and try again if necessary */
1573 while (msg
.msg_flags
& MSG_NOTIFICATION
)
1575 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1576 iov
.iov_base
= (char *)&snp
;
1577 iov
.iov_len
= sizeof(union sctp_notification
);
1578 msg
.msg_name
= NULL
;
1579 msg
.msg_namelen
= 0;
1582 msg
.msg_control
= NULL
;
1583 msg
.msg_controllen
= 0;
1586 n
= recvmsg(b
->num
, &msg
, 0);
1589 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1595 if (snp
.sn_header
.sn_type
== SCTP_SENDER_DRY_EVENT
)
1599 /* disable sender dry event */
1601 memset(&event
, 0, sizeof(struct sctp_event
));
1602 event
.se_assoc_id
= 0;
1603 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1605 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1607 eventsize
= (socklen_t
) sizeof(struct sctp_event_subscribe
);
1608 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1612 event
.sctp_sender_dry_event
= 0;
1614 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1620 #ifdef SCTP_AUTHENTICATION_EVENT
1621 if (snp
.sn_header
.sn_type
== SCTP_AUTHENTICATION_EVENT
)
1622 dgram_sctp_handle_auth_free_key_event(b
, &snp
);
1625 if (data
->handle_notifications
!= NULL
)
1626 data
->handle_notifications(b
, data
->notification_context
, (void*) &snp
);
1628 /* found notification, peek again */
1629 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1630 iov
.iov_base
= (char *)&snp
;
1631 iov
.iov_len
= sizeof(union sctp_notification
);
1632 msg
.msg_name
= NULL
;
1633 msg
.msg_namelen
= 0;
1636 msg
.msg_control
= NULL
;
1637 msg
.msg_controllen
= 0;
1640 /* if we have seen the dry already, don't wait */
1643 sockflags
= fcntl(b
->num
, F_GETFL
, 0);
1644 fcntl(b
->num
, F_SETFL
, O_NONBLOCK
);
1647 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1651 fcntl(b
->num
, F_SETFL
, sockflags
);
1656 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1663 /* read anything else */
1667 int BIO_dgram_sctp_msg_waiting(BIO
*b
)
1670 union sctp_notification snp
;
1673 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1675 /* Check if there are any messages waiting to be read */
1678 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1679 iov
.iov_base
= (char *)&snp
;
1680 iov
.iov_len
= sizeof(union sctp_notification
);
1681 msg
.msg_name
= NULL
;
1682 msg
.msg_namelen
= 0;
1685 msg
.msg_control
= NULL
;
1686 msg
.msg_controllen
= 0;
1689 sockflags
= fcntl(b
->num
, F_GETFL
, 0);
1690 fcntl(b
->num
, F_SETFL
, O_NONBLOCK
);
1691 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1692 fcntl(b
->num
, F_SETFL
, sockflags
);
1694 /* if notification, process and try again */
1695 if (n
> 0 && (msg
.msg_flags
& MSG_NOTIFICATION
))
1697 #ifdef SCTP_AUTHENTICATION_EVENT
1698 if (snp
.sn_header
.sn_type
== SCTP_AUTHENTICATION_EVENT
)
1699 dgram_sctp_handle_auth_free_key_event(b
, &snp
);
1702 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1703 iov
.iov_base
= (char *)&snp
;
1704 iov
.iov_len
= sizeof(union sctp_notification
);
1705 msg
.msg_name
= NULL
;
1706 msg
.msg_namelen
= 0;
1709 msg
.msg_control
= NULL
;
1710 msg
.msg_controllen
= 0;
1712 n
= recvmsg(b
->num
, &msg
, 0);
1714 if (data
->handle_notifications
!= NULL
)
1715 data
->handle_notifications(b
, data
->notification_context
, (void*) &snp
);
1718 } while (n
> 0 && (msg
.msg_flags
& MSG_NOTIFICATION
));
1720 /* Return 1 if there is a message to be read, return 0 otherwise. */
1727 static int dgram_sctp_puts(BIO
*bp
, const char *str
)
1732 ret
=dgram_sctp_write(bp
,str
,n
);
1737 static int BIO_dgram_should_retry(int i
)
1741 if ((i
== 0) || (i
== -1))
1743 err
=get_last_socket_error();
1745 #if defined(OPENSSL_SYS_WINDOWS)
1746 /* If the socket return value (i) is -1
1747 * and err is unexpectedly 0 at this point,
1748 * the error code was overwritten by
1749 * another system call before this error
1750 * handling is called.
1754 return(BIO_dgram_non_fatal_error(err
));
1759 int BIO_dgram_non_fatal_error(int err
)
1763 #if defined(OPENSSL_SYS_WINDOWS)
1764 # if defined(WSAEWOULDBLOCK)
1765 case WSAEWOULDBLOCK
:
1768 # if 0 /* This appears to always be an error */
1769 # if defined(WSAENOTCONN)
1776 # ifdef WSAEWOULDBLOCK
1777 # if WSAEWOULDBLOCK != EWOULDBLOCK
1790 #if EWOULDBLOCK != EAGAIN
1815 static void get_current_time(struct timeval
*t
)
1817 #ifdef OPENSSL_SYS_WIN32
1820 t
->tv_sec
= (long)tb
.time
;
1821 t
->tv_usec
= (long)tb
.millitm
* 1000;
1822 #elif defined(OPENSSL_SYS_VMS)
1825 t
->tv_sec
= (long)tb
.time
;
1826 t
->tv_usec
= (long)tb
.millitm
* 1000;
1828 gettimeofday(t
, NULL
);