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 #if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
81 #define IP_MTU 14 /* linux is lame */
84 #if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
85 /* Standard definition causes type-punning problems. */
86 #undef IN6_IS_ADDR_V4MAPPED
87 #define s6_addr32 __u6_addr.__u6_addr32
88 #define IN6_IS_ADDR_V4MAPPED(a) \
89 (((a)->s6_addr32[0] == 0) && \
90 ((a)->s6_addr32[1] == 0) && \
91 ((a)->s6_addr32[2] == htonl(0x0000ffff)))
95 #define sock_write SockWrite /* Watt-32 uses same names */
96 #define sock_read SockRead
97 #define sock_puts SockPuts
100 static int dgram_write(BIO
*h
, const char *buf
, int num
);
101 static int dgram_read(BIO
*h
, char *buf
, int size
);
102 static int dgram_puts(BIO
*h
, const char *str
);
103 static long dgram_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
104 static int dgram_new(BIO
*h
);
105 static int dgram_free(BIO
*data
);
106 static int dgram_clear(BIO
*bio
);
108 #ifndef OPENSSL_NO_SCTP
109 static int dgram_sctp_write(BIO
*h
, const char *buf
, int num
);
110 static int dgram_sctp_read(BIO
*h
, char *buf
, int size
);
111 static int dgram_sctp_puts(BIO
*h
, const char *str
);
112 static long dgram_sctp_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
113 static int dgram_sctp_new(BIO
*h
);
114 static int dgram_sctp_free(BIO
*data
);
115 #ifdef SCTP_AUTHENTICATION_EVENT
116 static void dgram_sctp_handle_auth_free_key_event(BIO
*b
, union sctp_notification
*snp
);
120 static int BIO_dgram_should_retry(int s
);
122 static void get_current_time(struct timeval
*t
);
124 static BIO_METHOD methods_dgramp
=
131 NULL
, /* dgram_gets, */
138 #ifndef OPENSSL_NO_SCTP
139 static BIO_METHOD methods_dgramp_sctp
=
142 "datagram sctp socket",
146 NULL
, /* dgram_gets, */
154 typedef struct bio_dgram_data_st
158 struct sockaddr_in sa_in
;
160 struct sockaddr_in6 sa_in6
;
163 unsigned int connected
;
166 struct timeval next_timeout
;
167 struct timeval socket_timeout
;
170 #ifndef OPENSSL_NO_SCTP
171 typedef struct bio_dgram_sctp_save_message_st
176 } bio_dgram_sctp_save_message
;
178 typedef struct bio_dgram_sctp_data_st
182 struct sockaddr_in sa_in
;
184 struct sockaddr_in6 sa_in6
;
187 unsigned int connected
;
190 struct bio_dgram_sctp_sndinfo sndinfo
;
191 struct bio_dgram_sctp_rcvinfo rcvinfo
;
192 struct bio_dgram_sctp_prinfo prinfo
;
193 void (*handle_notifications
)(BIO
*bio
, void *context
, void *buf
);
194 void* notification_context
;
199 int peer_auth_tested
;
200 bio_dgram_sctp_save_message saved_message
;
201 } bio_dgram_sctp_data
;
204 BIO_METHOD
*BIO_s_datagram(void)
206 return(&methods_dgramp
);
209 BIO
*BIO_new_dgram(int fd
, int close_flag
)
213 ret
=BIO_new(BIO_s_datagram());
214 if (ret
== NULL
) return(NULL
);
215 BIO_set_fd(ret
,fd
,close_flag
);
219 static int dgram_new(BIO
*bi
)
221 bio_dgram_data
*data
= NULL
;
225 data
= OPENSSL_malloc(sizeof(bio_dgram_data
));
228 memset(data
, 0x00, sizeof(bio_dgram_data
));
235 static int dgram_free(BIO
*a
)
237 bio_dgram_data
*data
;
239 if (a
== NULL
) return(0);
240 if ( ! dgram_clear(a
))
243 data
= (bio_dgram_data
*)a
->ptr
;
244 if(data
!= NULL
) OPENSSL_free(data
);
249 static int dgram_clear(BIO
*a
)
251 if (a
== NULL
) return(0);
264 static void dgram_adjust_rcv_timeout(BIO
*b
)
266 #if defined(SO_RCVTIMEO)
267 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
268 union { size_t s
; int i
; } sz
= {0};
270 /* Is a timer active? */
271 if (data
->next_timeout
.tv_sec
> 0 || data
->next_timeout
.tv_usec
> 0)
273 struct timeval timenow
, timeleft
;
275 /* Read current socket timeout */
276 #ifdef OPENSSL_SYS_WINDOWS
279 sz
.i
= sizeof(timeout
);
280 if (getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
281 (void*)&timeout
, &sz
.i
) < 0)
282 { perror("getsockopt"); }
285 data
->socket_timeout
.tv_sec
= timeout
/ 1000;
286 data
->socket_timeout
.tv_usec
= (timeout
% 1000) * 1000;
289 sz
.i
= sizeof(data
->socket_timeout
);
290 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
291 &(data
->socket_timeout
), (void *)&sz
) < 0)
292 { perror("getsockopt"); }
293 else if (sizeof(sz
.s
)!=sizeof(sz
.i
) && sz
.i
==0)
294 OPENSSL_assert(sz
.s
<=sizeof(data
->socket_timeout
));
297 /* Get current time */
298 get_current_time(&timenow
);
300 /* Calculate time left until timer expires */
301 memcpy(&timeleft
, &(data
->next_timeout
), sizeof(struct timeval
));
302 timeleft
.tv_sec
-= timenow
.tv_sec
;
303 timeleft
.tv_usec
-= timenow
.tv_usec
;
304 if (timeleft
.tv_usec
< 0)
307 timeleft
.tv_usec
+= 1000000;
310 if (timeleft
.tv_sec
< 0)
313 timeleft
.tv_usec
= 1;
316 /* Adjust socket timeout if next handhake message timer
317 * will expire earlier.
319 if ((data
->socket_timeout
.tv_sec
== 0 && data
->socket_timeout
.tv_usec
== 0) ||
320 (data
->socket_timeout
.tv_sec
> timeleft
.tv_sec
) ||
321 (data
->socket_timeout
.tv_sec
== timeleft
.tv_sec
&&
322 data
->socket_timeout
.tv_usec
>= timeleft
.tv_usec
))
324 #ifdef OPENSSL_SYS_WINDOWS
325 timeout
= timeleft
.tv_sec
* 1000 + timeleft
.tv_usec
/ 1000;
326 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
327 (void*)&timeout
, sizeof(timeout
)) < 0)
328 { perror("setsockopt"); }
330 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, &timeleft
,
331 sizeof(struct timeval
)) < 0)
332 { perror("setsockopt"); }
339 static void dgram_reset_rcv_timeout(BIO
*b
)
341 #if defined(SO_RCVTIMEO)
342 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
344 /* Is a timer active? */
345 if (data
->next_timeout
.tv_sec
> 0 || data
->next_timeout
.tv_usec
> 0)
347 #ifdef OPENSSL_SYS_WINDOWS
348 int timeout
= data
->socket_timeout
.tv_sec
* 1000 +
349 data
->socket_timeout
.tv_usec
/ 1000;
350 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
351 (void*)&timeout
, sizeof(timeout
)) < 0)
352 { perror("setsockopt"); }
354 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, &(data
->socket_timeout
),
355 sizeof(struct timeval
)) < 0)
356 { perror("setsockopt"); }
362 static int dgram_read(BIO
*b
, char *out
, int outl
)
365 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
369 * See commentary in b_sock.c. <appro>
371 union { size_t s
; int i
; } len
;
374 struct sockaddr_in sa_in
;
376 struct sockaddr_in6 sa_in6
;
382 sa
.len
.i
=sizeof(sa
.peer
);
386 clear_socket_error();
387 memset(&sa
.peer
, 0x00, sizeof(sa
.peer
));
388 dgram_adjust_rcv_timeout(b
);
389 ret
=recvfrom(b
->num
,out
,outl
,0,&sa
.peer
.sa
,(void *)&sa
.len
);
390 if (sizeof(sa
.len
.i
)!=sizeof(sa
.len
.s
) && sa
.len
.i
==0)
392 OPENSSL_assert(sa
.len
.s
<=sizeof(sa
.peer
));
393 sa
.len
.i
= (int)sa
.len
.s
;
396 if ( ! data
->connected
&& ret
>= 0)
397 BIO_ctrl(b
, BIO_CTRL_DGRAM_SET_PEER
, 0, &sa
.peer
);
399 BIO_clear_retry_flags(b
);
402 if (BIO_dgram_should_retry(ret
))
404 BIO_set_retry_read(b
);
405 data
->_errno
= get_last_socket_error();
409 dgram_reset_rcv_timeout(b
);
414 static int dgram_write(BIO
*b
, const char *in
, int inl
)
417 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
418 clear_socket_error();
420 if ( data
->connected
)
421 ret
=writesocket(b
->num
,in
,inl
);
424 int peerlen
= sizeof(data
->peer
);
426 if (data
->peer
.sa
.sa_family
== AF_INET
)
427 peerlen
= sizeof(data
->peer
.sa_in
);
429 else if (data
->peer
.sa
.sa_family
== AF_INET6
)
430 peerlen
= sizeof(data
->peer
.sa_in6
);
432 #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
433 ret
=sendto(b
->num
, (char *)in
, inl
, 0, &data
->peer
.sa
, peerlen
);
435 ret
=sendto(b
->num
, in
, inl
, 0, &data
->peer
.sa
, peerlen
);
439 BIO_clear_retry_flags(b
);
442 if (BIO_dgram_should_retry(ret
))
444 BIO_set_retry_write(b
);
445 data
->_errno
= get_last_socket_error();
447 #if 0 /* higher layers are responsible for querying MTU, if necessary */
448 if ( data
->_errno
== EMSGSIZE
)
449 /* retrieve the new MTU */
450 BIO_ctrl(b
, BIO_CTRL_DGRAM_QUERY_MTU
, 0, NULL
);
457 static long dgram_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
461 struct sockaddr
*to
= NULL
;
462 bio_dgram_data
*data
= NULL
;
463 #if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
465 socklen_t sockopt_len
; /* assume that system supporting IP_MTU is
466 * modern enough to define socklen_t */
470 struct sockaddr_in s4
;
472 struct sockaddr_in6 s6
;
477 data
= (bio_dgram_data
*)b
->ptr
;
483 case BIO_C_FILE_SEEK
:
486 case BIO_C_FILE_TELL
:
492 b
->num
= *((int *)ptr
);
493 b
->shutdown
=(int)num
;
500 if (ip
!= NULL
) *ip
=b
->num
;
506 case BIO_CTRL_GET_CLOSE
:
509 case BIO_CTRL_SET_CLOSE
:
510 b
->shutdown
=(int)num
;
512 case BIO_CTRL_PENDING
:
513 case BIO_CTRL_WPENDING
:
520 case BIO_CTRL_DGRAM_CONNECT
:
521 to
= (struct sockaddr
*)ptr
;
523 if (connect(b
->num
, to
, sizeof(struct sockaddr
)) < 0)
524 { perror("connect"); ret
= 0; }
528 switch (to
->sa_family
)
531 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
535 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
539 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
546 /* (Linux)kernel sets DF bit on outgoing IP packets */
547 case BIO_CTRL_DGRAM_MTU_DISCOVER
:
548 #if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
549 addr_len
= (socklen_t
)sizeof(addr
);
550 memset((void *)&addr
, 0, sizeof(addr
));
551 if (getsockname(b
->num
, &addr
.sa
, &addr_len
) < 0)
556 switch (addr
.sa
.sa_family
)
559 sockopt_val
= IP_PMTUDISC_DO
;
560 if ((ret
= setsockopt(b
->num
, IPPROTO_IP
, IP_MTU_DISCOVER
,
561 &sockopt_val
, sizeof(sockopt_val
))) < 0)
562 perror("setsockopt");
564 #if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
566 sockopt_val
= IPV6_PMTUDISC_DO
;
567 if ((ret
= setsockopt(b
->num
, IPPROTO_IPV6
, IPV6_MTU_DISCOVER
,
568 &sockopt_val
, sizeof(sockopt_val
))) < 0)
569 perror("setsockopt");
580 case BIO_CTRL_DGRAM_QUERY_MTU
:
581 #if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
582 addr_len
= (socklen_t
)sizeof(addr
);
583 memset((void *)&addr
, 0, sizeof(addr
));
584 if (getsockname(b
->num
, &addr
.sa
, &addr_len
) < 0)
589 sockopt_len
= sizeof(sockopt_val
);
590 switch (addr
.sa
.sa_family
)
593 if ((ret
= getsockopt(b
->num
, IPPROTO_IP
, IP_MTU
, (void *)&sockopt_val
,
594 &sockopt_len
)) < 0 || sockopt_val
< 0)
600 /* we assume that the transport protocol is UDP and no
601 * IP options are used.
603 data
->mtu
= sockopt_val
- 8 - 20;
607 #if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
609 if ((ret
= getsockopt(b
->num
, IPPROTO_IPV6
, IPV6_MTU
, (void *)&sockopt_val
,
610 &sockopt_len
)) < 0 || sockopt_val
< 0)
616 /* we assume that the transport protocol is UDP and no
617 * IPV6 options are used.
619 data
->mtu
= sockopt_val
- 8 - 40;
632 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU
:
633 switch (data
->peer
.sa
.sa_family
)
640 #ifdef IN6_IS_ADDR_V4MAPPED
641 if (IN6_IS_ADDR_V4MAPPED(&data
->peer
.sa_in6
.sin6_addr
))
653 case BIO_CTRL_DGRAM_GET_MTU
:
656 case BIO_CTRL_DGRAM_SET_MTU
:
660 case BIO_CTRL_DGRAM_SET_CONNECTED
:
661 to
= (struct sockaddr
*)ptr
;
666 switch (to
->sa_family
)
669 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
673 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
677 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
684 memset(&(data
->peer
), 0x00, sizeof(data
->peer
));
687 case BIO_CTRL_DGRAM_GET_PEER
:
688 switch (data
->peer
.sa
.sa_family
)
691 ret
=sizeof(data
->peer
.sa_in
);
695 ret
=sizeof(data
->peer
.sa_in6
);
699 ret
=sizeof(data
->peer
.sa
);
702 if (num
==0 || num
>ret
)
704 memcpy(ptr
,&data
->peer
,(ret
=num
));
706 case BIO_CTRL_DGRAM_SET_PEER
:
707 to
= (struct sockaddr
*) ptr
;
708 switch (to
->sa_family
)
711 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
715 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
719 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
723 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
:
724 memcpy(&(data
->next_timeout
), ptr
, sizeof(struct timeval
));
726 #if defined(SO_RCVTIMEO)
727 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT
:
728 #ifdef OPENSSL_SYS_WINDOWS
730 struct timeval
*tv
= (struct timeval
*)ptr
;
731 int timeout
= tv
->tv_sec
* 1000 + tv
->tv_usec
/1000;
732 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
733 (void*)&timeout
, sizeof(timeout
)) < 0)
734 { perror("setsockopt"); ret
= -1; }
737 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, ptr
,
738 sizeof(struct timeval
)) < 0)
739 { perror("setsockopt"); ret
= -1; }
742 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT
:
744 union { size_t s
; int i
; } sz
= {0};
745 #ifdef OPENSSL_SYS_WINDOWS
747 struct timeval
*tv
= (struct timeval
*)ptr
;
749 sz
.i
= sizeof(timeout
);
750 if (getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
751 (void*)&timeout
, &sz
.i
) < 0)
752 { perror("getsockopt"); ret
= -1; }
755 tv
->tv_sec
= timeout
/ 1000;
756 tv
->tv_usec
= (timeout
% 1000) * 1000;
760 sz
.i
= sizeof(struct timeval
);
761 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
762 ptr
, (void *)&sz
) < 0)
763 { perror("getsockopt"); ret
= -1; }
764 else if (sizeof(sz
.s
)!=sizeof(sz
.i
) && sz
.i
==0)
766 OPENSSL_assert(sz
.s
<=sizeof(struct timeval
));
775 #if defined(SO_SNDTIMEO)
776 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT
:
777 #ifdef OPENSSL_SYS_WINDOWS
779 struct timeval
*tv
= (struct timeval
*)ptr
;
780 int timeout
= tv
->tv_sec
* 1000 + tv
->tv_usec
/1000;
781 if (setsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
782 (void*)&timeout
, sizeof(timeout
)) < 0)
783 { perror("setsockopt"); ret
= -1; }
786 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
, ptr
,
787 sizeof(struct timeval
)) < 0)
788 { perror("setsockopt"); ret
= -1; }
791 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT
:
793 union { size_t s
; int i
; } sz
= {0};
794 #ifdef OPENSSL_SYS_WINDOWS
796 struct timeval
*tv
= (struct timeval
*)ptr
;
798 sz
.i
= sizeof(timeout
);
799 if (getsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
800 (void*)&timeout
, &sz
.i
) < 0)
801 { perror("getsockopt"); ret
= -1; }
804 tv
->tv_sec
= timeout
/ 1000;
805 tv
->tv_usec
= (timeout
% 1000) * 1000;
809 sz
.i
= sizeof(struct timeval
);
810 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
811 ptr
, (void *)&sz
) < 0)
812 { perror("getsockopt"); ret
= -1; }
813 else if (sizeof(sz
.s
)!=sizeof(sz
.i
) && sz
.i
==0)
815 OPENSSL_assert(sz
.s
<=sizeof(struct timeval
));
824 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP
:
826 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP
:
827 #ifdef OPENSSL_SYS_WINDOWS
828 if ( data
->_errno
== WSAETIMEDOUT
)
830 if ( data
->_errno
== EAGAIN
)
840 case BIO_CTRL_DGRAM_MTU_EXCEEDED
:
841 if ( data
->_errno
== EMSGSIZE
)
857 static int dgram_puts(BIO
*bp
, const char *str
)
862 ret
=dgram_write(bp
,str
,n
);
866 #ifndef OPENSSL_NO_SCTP
867 BIO_METHOD
*BIO_s_datagram_sctp(void)
869 return(&methods_dgramp_sctp
);
872 BIO
*BIO_new_dgram_sctp(int fd
, int close_flag
)
875 int ret
, optval
= 20000;
876 int auth_data
= 0, auth_forward
= 0;
878 struct sctp_authchunk auth
;
879 struct sctp_authchunks
*authchunks
;
880 socklen_t sockopt_len
;
881 #ifdef SCTP_AUTHENTICATION_EVENT
883 struct sctp_event event
;
885 struct sctp_event_subscribe event
;
889 bio
=BIO_new(BIO_s_datagram_sctp());
890 if (bio
== NULL
) return(NULL
);
891 BIO_set_fd(bio
,fd
,close_flag
);
893 /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
894 auth
.sauth_chunk
= OPENSSL_SCTP_DATA_CHUNK_TYPE
;
895 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_AUTH_CHUNK
, &auth
, sizeof(struct sctp_authchunk
));
896 OPENSSL_assert(ret
>= 0);
897 auth
.sauth_chunk
= OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
;
898 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_AUTH_CHUNK
, &auth
, sizeof(struct sctp_authchunk
));
899 OPENSSL_assert(ret
>= 0);
901 /* Test if activation was successful. When using accept(),
902 * SCTP-AUTH has to be activated for the listening socket
903 * already, otherwise the connected socket won't use it. */
904 sockopt_len
= (socklen_t
)(sizeof(sctp_assoc_t
) + 256 * sizeof(uint8_t));
905 authchunks
= OPENSSL_malloc(sockopt_len
);
906 memset(authchunks
, 0, sizeof(sockopt_len
));
907 ret
= getsockopt(fd
, IPPROTO_SCTP
, SCTP_LOCAL_AUTH_CHUNKS
, authchunks
, &sockopt_len
);
908 OPENSSL_assert(ret
>= 0);
910 for (p
= (unsigned char*) authchunks
->gauth_chunks
;
911 p
< (unsigned char*) authchunks
+ sockopt_len
;
912 p
+= sizeof(uint8_t))
914 if (*p
== OPENSSL_SCTP_DATA_CHUNK_TYPE
) auth_data
= 1;
915 if (*p
== OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
) auth_forward
= 1;
918 OPENSSL_free(authchunks
);
920 OPENSSL_assert(auth_data
);
921 OPENSSL_assert(auth_forward
);
923 #ifdef SCTP_AUTHENTICATION_EVENT
925 memset(&event
, 0, sizeof(struct sctp_event
));
926 event
.se_assoc_id
= 0;
927 event
.se_type
= SCTP_AUTHENTICATION_EVENT
;
929 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
930 OPENSSL_assert(ret
>= 0);
932 sockopt_len
= (socklen_t
) sizeof(struct sctp_event_subscribe
);
933 ret
= getsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &sockopt_len
);
934 OPENSSL_assert(ret
>= 0);
936 event
.sctp_authentication_event
= 1;
938 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
939 OPENSSL_assert(ret
>= 0);
943 /* Disable partial delivery by setting the min size
944 * larger than the max record size of 2^14 + 2048 + 13
946 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_PARTIAL_DELIVERY_POINT
, &optval
, sizeof(optval
));
947 OPENSSL_assert(ret
>= 0);
952 int BIO_dgram_is_sctp(BIO
*bio
)
954 return (BIO_method_type(bio
) == BIO_TYPE_DGRAM_SCTP
);
957 static int dgram_sctp_new(BIO
*bi
)
959 bio_dgram_sctp_data
*data
= NULL
;
963 data
= OPENSSL_malloc(sizeof(bio_dgram_sctp_data
));
966 memset(data
, 0x00, sizeof(bio_dgram_sctp_data
));
967 #ifdef SCTP_PR_SCTP_NONE
968 data
->prinfo
.pr_policy
= SCTP_PR_SCTP_NONE
;
976 static int dgram_sctp_free(BIO
*a
)
978 bio_dgram_sctp_data
*data
;
980 if (a
== NULL
) return(0);
981 if ( ! dgram_clear(a
))
984 data
= (bio_dgram_sctp_data
*)a
->ptr
;
985 if(data
!= NULL
) OPENSSL_free(data
);
990 #ifdef SCTP_AUTHENTICATION_EVENT
991 void dgram_sctp_handle_auth_free_key_event(BIO
*b
, union sctp_notification
*snp
)
994 struct sctp_authkey_event
* authkeyevent
= &snp
->sn_auth_event
;
996 if (authkeyevent
->auth_indication
== SCTP_AUTH_FREE_KEY
)
998 struct sctp_authkeyid authkeyid
;
1001 authkeyid
.scact_keynumber
= authkeyevent
->auth_keynumber
;
1002 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DELETE_KEY
,
1003 &authkeyid
, sizeof(struct sctp_authkeyid
));
1008 static int dgram_sctp_read(BIO
*b
, char *out
, int outl
)
1010 int ret
= 0, n
= 0, i
, optval
;
1012 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1013 union sctp_notification
*snp
;
1016 struct cmsghdr
*cmsg
;
1021 clear_socket_error();
1025 memset(&data
->rcvinfo
, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo
));
1028 msg
.msg_name
= NULL
;
1029 msg
.msg_namelen
= 0;
1032 msg
.msg_control
= cmsgbuf
;
1033 msg
.msg_controllen
= 512;
1035 n
= recvmsg(b
->num
, &msg
, 0);
1037 if (msg
.msg_controllen
> 0)
1039 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
; cmsg
= CMSG_NXTHDR(&msg
, cmsg
))
1041 if (cmsg
->cmsg_level
!= IPPROTO_SCTP
)
1044 if (cmsg
->cmsg_type
== SCTP_RCVINFO
)
1046 struct sctp_rcvinfo
*rcvinfo
;
1048 rcvinfo
= (struct sctp_rcvinfo
*)CMSG_DATA(cmsg
);
1049 data
->rcvinfo
.rcv_sid
= rcvinfo
->rcv_sid
;
1050 data
->rcvinfo
.rcv_ssn
= rcvinfo
->rcv_ssn
;
1051 data
->rcvinfo
.rcv_flags
= rcvinfo
->rcv_flags
;
1052 data
->rcvinfo
.rcv_ppid
= rcvinfo
->rcv_ppid
;
1053 data
->rcvinfo
.rcv_tsn
= rcvinfo
->rcv_tsn
;
1054 data
->rcvinfo
.rcv_cumtsn
= rcvinfo
->rcv_cumtsn
;
1055 data
->rcvinfo
.rcv_context
= rcvinfo
->rcv_context
;
1059 if (cmsg
->cmsg_type
== SCTP_SNDRCV
)
1061 struct sctp_sndrcvinfo
*sndrcvinfo
;
1063 sndrcvinfo
= (struct sctp_sndrcvinfo
*)CMSG_DATA(cmsg
);
1064 data
->rcvinfo
.rcv_sid
= sndrcvinfo
->sinfo_stream
;
1065 data
->rcvinfo
.rcv_ssn
= sndrcvinfo
->sinfo_ssn
;
1066 data
->rcvinfo
.rcv_flags
= sndrcvinfo
->sinfo_flags
;
1067 data
->rcvinfo
.rcv_ppid
= sndrcvinfo
->sinfo_ppid
;
1068 data
->rcvinfo
.rcv_tsn
= sndrcvinfo
->sinfo_tsn
;
1069 data
->rcvinfo
.rcv_cumtsn
= sndrcvinfo
->sinfo_cumtsn
;
1070 data
->rcvinfo
.rcv_context
= sndrcvinfo
->sinfo_context
;
1083 if (msg
.msg_flags
& MSG_NOTIFICATION
)
1085 snp
= (union sctp_notification
*) out
;
1086 if (snp
->sn_header
.sn_type
== SCTP_SENDER_DRY_EVENT
)
1089 struct sctp_event event
;
1091 struct sctp_event_subscribe event
;
1092 socklen_t eventsize
;
1094 /* If a message has been delayed until the socket
1095 * is dry, it can be sent now.
1097 if (data
->saved_message
.length
> 0)
1099 dgram_sctp_write(data
->saved_message
.bio
, data
->saved_message
.data
,
1100 data
->saved_message
.length
);
1101 OPENSSL_free(data
->saved_message
.data
);
1102 data
->saved_message
.length
= 0;
1105 /* disable sender dry event */
1107 memset(&event
, 0, sizeof(struct sctp_event
));
1108 event
.se_assoc_id
= 0;
1109 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1111 i
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1112 OPENSSL_assert(i
>= 0);
1114 eventsize
= sizeof(struct sctp_event_subscribe
);
1115 i
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1116 OPENSSL_assert(i
>= 0);
1118 event
.sctp_sender_dry_event
= 0;
1120 i
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1121 OPENSSL_assert(i
>= 0);
1125 #ifdef SCTP_AUTHENTICATION_EVENT
1126 if (snp
->sn_header
.sn_type
== SCTP_AUTHENTICATION_EVENT
)
1127 dgram_sctp_handle_auth_free_key_event(b
, snp
);
1130 if (data
->handle_notifications
!= NULL
)
1131 data
->handle_notifications(b
, data
->notification_context
, (void*) out
);
1133 memset(out
, 0, outl
);
1138 while ((msg
.msg_flags
& MSG_NOTIFICATION
) && (msg
.msg_flags
& MSG_EOR
) && (ret
< outl
));
1140 if (ret
> 0 && !(msg
.msg_flags
& MSG_EOR
))
1142 /* Partial message read, this should never happen! */
1144 /* The buffer was too small, this means the peer sent
1145 * a message that was larger than allowed. */
1149 /* Test if socket buffer can handle max record
1150 * size (2^14 + 2048 + 13)
1152 optlen
= (socklen_t
) sizeof(int);
1153 ret
= getsockopt(b
->num
, SOL_SOCKET
, SO_RCVBUF
, &optval
, &optlen
);
1154 OPENSSL_assert(ret
>= 0);
1155 OPENSSL_assert(optval
>= 18445);
1157 /* Test if SCTP doesn't partially deliver below
1158 * max record size (2^14 + 2048 + 13)
1160 optlen
= (socklen_t
) sizeof(int);
1161 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_PARTIAL_DELIVERY_POINT
,
1163 OPENSSL_assert(ret
>= 0);
1164 OPENSSL_assert(optval
>= 18445);
1166 /* Partially delivered notification??? Probably a bug.... */
1167 OPENSSL_assert(!(msg
.msg_flags
& MSG_NOTIFICATION
));
1169 /* Everything seems ok till now, so it's most likely
1170 * a message dropped by PR-SCTP.
1172 memset(out
, 0, outl
);
1173 BIO_set_retry_read(b
);
1177 BIO_clear_retry_flags(b
);
1180 if (BIO_dgram_should_retry(ret
))
1182 BIO_set_retry_read(b
);
1183 data
->_errno
= get_last_socket_error();
1187 /* Test if peer uses SCTP-AUTH before continuing */
1188 if (!data
->peer_auth_tested
)
1190 int ii
, auth_data
= 0, auth_forward
= 0;
1192 struct sctp_authchunks
*authchunks
;
1194 optlen
= (socklen_t
)(sizeof(sctp_assoc_t
) + 256 * sizeof(uint8_t));
1195 authchunks
= OPENSSL_malloc(optlen
);
1196 memset(authchunks
, 0, sizeof(optlen
));
1197 ii
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_PEER_AUTH_CHUNKS
, authchunks
, &optlen
);
1198 OPENSSL_assert(ii
>= 0);
1200 for (p
= (unsigned char*) authchunks
->gauth_chunks
;
1201 p
< (unsigned char*) authchunks
+ optlen
;
1202 p
+= sizeof(uint8_t))
1204 if (*p
== OPENSSL_SCTP_DATA_CHUNK_TYPE
) auth_data
= 1;
1205 if (*p
== OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
) auth_forward
= 1;
1208 OPENSSL_free(authchunks
);
1210 if (!auth_data
|| !auth_forward
)
1212 BIOerr(BIO_F_DGRAM_SCTP_READ
,BIO_R_CONNECT_ERROR
);
1216 data
->peer_auth_tested
= 1;
1222 static int dgram_sctp_write(BIO
*b
, const char *in
, int inl
)
1225 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1226 struct bio_dgram_sctp_sndinfo
*sinfo
= &(data
->sndinfo
);
1227 struct bio_dgram_sctp_prinfo
*pinfo
= &(data
->prinfo
);
1228 struct bio_dgram_sctp_sndinfo handshake_sinfo
;
1229 struct iovec iov
[1];
1231 struct cmsghdr
*cmsg
;
1232 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1233 char cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndinfo
)) + CMSG_SPACE(sizeof(struct sctp_prinfo
))];
1234 struct sctp_sndinfo
*sndinfo
;
1235 struct sctp_prinfo
*prinfo
;
1237 char cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo
))];
1238 struct sctp_sndrcvinfo
*sndrcvinfo
;
1241 clear_socket_error();
1243 /* If we're send anything else than application data,
1244 * disable all user parameters and flags.
1247 memset(&handshake_sinfo
, 0x00, sizeof(struct bio_dgram_sctp_sndinfo
));
1248 #ifdef SCTP_SACK_IMMEDIATELY
1249 handshake_sinfo
.snd_flags
= SCTP_SACK_IMMEDIATELY
;
1251 sinfo
= &handshake_sinfo
;
1254 /* If we have to send a shutdown alert message and the
1255 * socket is not dry yet, we have to save it and send it
1256 * as soon as the socket gets dry.
1258 if (data
->save_shutdown
&& !BIO_dgram_sctp_wait_for_dry(b
))
1260 data
->saved_message
.bio
= b
;
1261 data
->saved_message
.length
= inl
;
1262 data
->saved_message
.data
= OPENSSL_malloc(inl
);
1263 memcpy(data
->saved_message
.data
, in
, inl
);
1267 iov
[0].iov_base
= (char *)in
;
1268 iov
[0].iov_len
= inl
;
1269 msg
.msg_name
= NULL
;
1270 msg
.msg_namelen
= 0;
1273 msg
.msg_control
= (caddr_t
)cmsgbuf
;
1274 msg
.msg_controllen
= 0;
1276 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1277 cmsg
= (struct cmsghdr
*)cmsgbuf
;
1278 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1279 cmsg
->cmsg_type
= SCTP_SNDINFO
;
1280 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_sndinfo
));
1281 sndinfo
= (struct sctp_sndinfo
*)CMSG_DATA(cmsg
);
1282 memset(sndinfo
, 0, sizeof(struct sctp_sndinfo
));
1283 sndinfo
->snd_sid
= sinfo
->snd_sid
;
1284 sndinfo
->snd_flags
= sinfo
->snd_flags
;
1285 sndinfo
->snd_ppid
= sinfo
->snd_ppid
;
1286 sndinfo
->snd_context
= sinfo
->snd_context
;
1287 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_sndinfo
));
1289 cmsg
= (struct cmsghdr
*)&cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndinfo
))];
1290 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1291 cmsg
->cmsg_type
= SCTP_PRINFO
;
1292 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_prinfo
));
1293 prinfo
= (struct sctp_prinfo
*)CMSG_DATA(cmsg
);
1294 memset(prinfo
, 0, sizeof(struct sctp_prinfo
));
1295 prinfo
->pr_policy
= pinfo
->pr_policy
;
1296 prinfo
->pr_value
= pinfo
->pr_value
;
1297 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_prinfo
));
1299 cmsg
= (struct cmsghdr
*)cmsgbuf
;
1300 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1301 cmsg
->cmsg_type
= SCTP_SNDRCV
;
1302 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_sndrcvinfo
));
1303 sndrcvinfo
= (struct sctp_sndrcvinfo
*)CMSG_DATA(cmsg
);
1304 memset(sndrcvinfo
, 0, sizeof(struct sctp_sndrcvinfo
));
1305 sndrcvinfo
->sinfo_stream
= sinfo
->snd_sid
;
1306 sndrcvinfo
->sinfo_flags
= sinfo
->snd_flags
;
1308 sndrcvinfo
->sinfo_flags
|= pinfo
->pr_policy
;
1310 sndrcvinfo
->sinfo_ppid
= sinfo
->snd_ppid
;
1311 sndrcvinfo
->sinfo_context
= sinfo
->snd_context
;
1312 sndrcvinfo
->sinfo_timetolive
= pinfo
->pr_value
;
1313 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_sndrcvinfo
));
1316 ret
= sendmsg(b
->num
, &msg
, 0);
1318 BIO_clear_retry_flags(b
);
1321 if (BIO_dgram_should_retry(ret
))
1323 BIO_set_retry_write(b
);
1324 data
->_errno
= get_last_socket_error();
1330 static long dgram_sctp_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
1333 bio_dgram_sctp_data
*data
= NULL
;
1334 socklen_t sockopt_len
= 0;
1335 struct sctp_authkeyid authkeyid
;
1336 struct sctp_authkey
*authkey
= NULL
;
1338 data
= (bio_dgram_sctp_data
*)b
->ptr
;
1342 case BIO_CTRL_DGRAM_QUERY_MTU
:
1343 /* Set to maximum (2^14)
1344 * and ignore user input to enable transport
1345 * protocol fragmentation.
1346 * Returns always 2^14.
1351 case BIO_CTRL_DGRAM_SET_MTU
:
1352 /* Set to maximum (2^14)
1353 * and ignore input to enable transport
1354 * protocol fragmentation.
1355 * Returns always 2^14.
1360 case BIO_CTRL_DGRAM_SET_CONNECTED
:
1361 case BIO_CTRL_DGRAM_CONNECT
:
1362 /* Returns always -1. */
1365 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
:
1366 /* SCTP doesn't need the DTLS timer
1370 case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE
:
1372 data
->in_handshake
= 1;
1374 data
->in_handshake
= 0;
1376 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_NODELAY
, &data
->in_handshake
, sizeof(int));
1378 case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY
:
1379 /* New shared key for SCTP AUTH.
1380 * Returns 0 on success, -1 otherwise.
1383 /* Get active key */
1384 sockopt_len
= sizeof(struct sctp_authkeyid
);
1385 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1389 sockopt_len
= sizeof(struct sctp_authkey
) + 64 * sizeof(uint8_t);
1390 authkey
= OPENSSL_malloc(sockopt_len
);
1391 if (authkey
== NULL
)
1396 memset(authkey
, 0x00, sockopt_len
);
1397 authkey
->sca_keynumber
= authkeyid
.scact_keynumber
+ 1;
1399 /* This field is missing in FreeBSD 8.2 and earlier,
1400 * and FreeBSD 8.3 and higher work without it.
1402 authkey
->sca_keylength
= 64;
1404 memcpy(&authkey
->sca_key
[0], ptr
, 64 * sizeof(uint8_t));
1406 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_KEY
, authkey
, sockopt_len
);
1407 OPENSSL_free(authkey
);
1411 /* Reset active key */
1412 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
,
1413 &authkeyid
, sizeof(struct sctp_authkeyid
));
1417 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY
:
1418 /* Returns 0 on success, -1 otherwise. */
1420 /* Get active key */
1421 sockopt_len
= sizeof(struct sctp_authkeyid
);
1422 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1425 /* Set active key */
1426 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
+ 1;
1427 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
,
1428 &authkeyid
, sizeof(struct sctp_authkeyid
));
1431 /* CCS has been sent, so remember that and fall through
1432 * to check if we need to deactivate an old key
1436 case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD
:
1437 /* Returns 0 on success, -1 otherwise. */
1439 /* Has this command really been called or is this just a fall-through? */
1440 if (cmd
== BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD
)
1443 /* CSS has been both, received and sent, so deactivate an old key */
1444 if (data
->ccs_rcvd
== 1 && data
->ccs_sent
== 1)
1446 /* Get active key */
1447 sockopt_len
= sizeof(struct sctp_authkeyid
);
1448 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1451 /* Deactivate key or delete second last key if
1452 * SCTP_AUTHENTICATION_EVENT is not available.
1454 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
- 1;
1455 #ifdef SCTP_AUTH_DEACTIVATE_KEY
1456 sockopt_len
= sizeof(struct sctp_authkeyid
);
1457 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DEACTIVATE_KEY
,
1458 &authkeyid
, sockopt_len
);
1461 #ifndef SCTP_AUTHENTICATION_EVENT
1462 if (authkeyid
.scact_keynumber
> 0)
1464 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
- 1;
1465 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DELETE_KEY
,
1466 &authkeyid
, sizeof(struct sctp_authkeyid
));
1475 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO
:
1476 /* Returns the size of the copied struct. */
1477 if (num
> (long) sizeof(struct bio_dgram_sctp_sndinfo
))
1478 num
= sizeof(struct bio_dgram_sctp_sndinfo
);
1480 memcpy(ptr
, &(data
->sndinfo
), num
);
1483 case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO
:
1484 /* Returns the size of the copied struct. */
1485 if (num
> (long) sizeof(struct bio_dgram_sctp_sndinfo
))
1486 num
= sizeof(struct bio_dgram_sctp_sndinfo
);
1488 memcpy(&(data
->sndinfo
), ptr
, num
);
1490 case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO
:
1491 /* Returns the size of the copied struct. */
1492 if (num
> (long) sizeof(struct bio_dgram_sctp_rcvinfo
))
1493 num
= sizeof(struct bio_dgram_sctp_rcvinfo
);
1495 memcpy(ptr
, &data
->rcvinfo
, num
);
1499 case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO
:
1500 /* Returns the size of the copied struct. */
1501 if (num
> (long) sizeof(struct bio_dgram_sctp_rcvinfo
))
1502 num
= sizeof(struct bio_dgram_sctp_rcvinfo
);
1504 memcpy(&(data
->rcvinfo
), ptr
, num
);
1506 case BIO_CTRL_DGRAM_SCTP_GET_PRINFO
:
1507 /* Returns the size of the copied struct. */
1508 if (num
> (long) sizeof(struct bio_dgram_sctp_prinfo
))
1509 num
= sizeof(struct bio_dgram_sctp_prinfo
);
1511 memcpy(ptr
, &(data
->prinfo
), num
);
1514 case BIO_CTRL_DGRAM_SCTP_SET_PRINFO
:
1515 /* Returns the size of the copied struct. */
1516 if (num
> (long) sizeof(struct bio_dgram_sctp_prinfo
))
1517 num
= sizeof(struct bio_dgram_sctp_prinfo
);
1519 memcpy(&(data
->prinfo
), ptr
, num
);
1521 case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN
:
1522 /* Returns always 1. */
1524 data
->save_shutdown
= 1;
1526 data
->save_shutdown
= 0;
1530 /* Pass to default ctrl function to
1531 * process SCTP unspecific commands
1533 ret
=dgram_ctrl(b
, cmd
, num
, ptr
);
1539 int BIO_dgram_sctp_notification_cb(BIO
*b
,
1540 void (*handle_notifications
)(BIO
*bio
, void *context
, void *buf
),
1543 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*) b
->ptr
;
1545 if (handle_notifications
!= NULL
)
1547 data
->handle_notifications
= handle_notifications
;
1548 data
->notification_context
= context
;
1556 int BIO_dgram_sctp_wait_for_dry(BIO
*b
)
1559 int n
, sockflags
, ret
;
1560 union sctp_notification snp
;
1564 struct sctp_event event
;
1566 struct sctp_event_subscribe event
;
1567 socklen_t eventsize
;
1569 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1571 /* set sender dry event */
1573 memset(&event
, 0, sizeof(struct sctp_event
));
1574 event
.se_assoc_id
= 0;
1575 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1577 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1579 eventsize
= sizeof(struct sctp_event_subscribe
);
1580 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1584 event
.sctp_sender_dry_event
= 1;
1586 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1591 /* peek for notification */
1592 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1593 iov
.iov_base
= (char *)&snp
;
1594 iov
.iov_len
= sizeof(union sctp_notification
);
1595 msg
.msg_name
= NULL
;
1596 msg
.msg_namelen
= 0;
1599 msg
.msg_control
= NULL
;
1600 msg
.msg_controllen
= 0;
1603 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1606 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1612 /* if we find a notification, process it and try again if necessary */
1613 while (msg
.msg_flags
& MSG_NOTIFICATION
)
1615 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1616 iov
.iov_base
= (char *)&snp
;
1617 iov
.iov_len
= sizeof(union sctp_notification
);
1618 msg
.msg_name
= NULL
;
1619 msg
.msg_namelen
= 0;
1622 msg
.msg_control
= NULL
;
1623 msg
.msg_controllen
= 0;
1626 n
= recvmsg(b
->num
, &msg
, 0);
1629 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1635 if (snp
.sn_header
.sn_type
== SCTP_SENDER_DRY_EVENT
)
1639 /* disable sender dry event */
1641 memset(&event
, 0, sizeof(struct sctp_event
));
1642 event
.se_assoc_id
= 0;
1643 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1645 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1647 eventsize
= (socklen_t
) sizeof(struct sctp_event_subscribe
);
1648 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1652 event
.sctp_sender_dry_event
= 0;
1654 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1660 #ifdef SCTP_AUTHENTICATION_EVENT
1661 if (snp
.sn_header
.sn_type
== SCTP_AUTHENTICATION_EVENT
)
1662 dgram_sctp_handle_auth_free_key_event(b
, &snp
);
1665 if (data
->handle_notifications
!= NULL
)
1666 data
->handle_notifications(b
, data
->notification_context
, (void*) &snp
);
1668 /* found notification, peek again */
1669 memset(&snp
, 0x00, sizeof(union sctp_notification
));
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 /* if we have seen the dry already, don't wait */
1683 sockflags
= fcntl(b
->num
, F_GETFL
, 0);
1684 fcntl(b
->num
, F_SETFL
, O_NONBLOCK
);
1687 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1691 fcntl(b
->num
, F_SETFL
, sockflags
);
1696 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1703 /* read anything else */
1707 int BIO_dgram_sctp_msg_waiting(BIO
*b
)
1710 union sctp_notification snp
;
1713 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1715 /* Check if there are any messages waiting to be read */
1718 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1719 iov
.iov_base
= (char *)&snp
;
1720 iov
.iov_len
= sizeof(union sctp_notification
);
1721 msg
.msg_name
= NULL
;
1722 msg
.msg_namelen
= 0;
1725 msg
.msg_control
= NULL
;
1726 msg
.msg_controllen
= 0;
1729 sockflags
= fcntl(b
->num
, F_GETFL
, 0);
1730 fcntl(b
->num
, F_SETFL
, O_NONBLOCK
);
1731 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1732 fcntl(b
->num
, F_SETFL
, sockflags
);
1734 /* if notification, process and try again */
1735 if (n
> 0 && (msg
.msg_flags
& MSG_NOTIFICATION
))
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
);
1742 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1743 iov
.iov_base
= (char *)&snp
;
1744 iov
.iov_len
= sizeof(union sctp_notification
);
1745 msg
.msg_name
= NULL
;
1746 msg
.msg_namelen
= 0;
1749 msg
.msg_control
= NULL
;
1750 msg
.msg_controllen
= 0;
1752 n
= recvmsg(b
->num
, &msg
, 0);
1754 if (data
->handle_notifications
!= NULL
)
1755 data
->handle_notifications(b
, data
->notification_context
, (void*) &snp
);
1758 } while (n
> 0 && (msg
.msg_flags
& MSG_NOTIFICATION
));
1760 /* Return 1 if there is a message to be read, return 0 otherwise. */
1767 static int dgram_sctp_puts(BIO
*bp
, const char *str
)
1772 ret
=dgram_sctp_write(bp
,str
,n
);
1777 static int BIO_dgram_should_retry(int i
)
1781 if ((i
== 0) || (i
== -1))
1783 err
=get_last_socket_error();
1785 #if defined(OPENSSL_SYS_WINDOWS)
1786 /* If the socket return value (i) is -1
1787 * and err is unexpectedly 0 at this point,
1788 * the error code was overwritten by
1789 * another system call before this error
1790 * handling is called.
1794 return(BIO_dgram_non_fatal_error(err
));
1799 int BIO_dgram_non_fatal_error(int err
)
1803 #if defined(OPENSSL_SYS_WINDOWS)
1804 # if defined(WSAEWOULDBLOCK)
1805 case WSAEWOULDBLOCK
:
1808 # if 0 /* This appears to always be an error */
1809 # if defined(WSAENOTCONN)
1816 # ifdef WSAEWOULDBLOCK
1817 # if WSAEWOULDBLOCK != EWOULDBLOCK
1830 #if EWOULDBLOCK != EAGAIN
1855 static void get_current_time(struct timeval
*t
)
1857 #ifdef OPENSSL_SYS_WIN32
1860 t
->tv_sec
= (long)tb
.time
;
1861 t
->tv_usec
= (long)tb
.millitm
* 1000;
1862 #elif defined(OPENSSL_SYS_VMS)
1865 t
->tv_sec
= (long)tb
.time
;
1866 t
->tv_usec
= (long)tb
.millitm
* 1000;
1868 gettimeofday(t
, NULL
);