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_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 OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
85 #define IPPROTO_IPV6 41 /* windows is lame */
88 #if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
89 /* Standard definition causes type-punning problems. */
90 #undef IN6_IS_ADDR_V4MAPPED
91 #define s6_addr32 __u6_addr.__u6_addr32
92 #define IN6_IS_ADDR_V4MAPPED(a) \
93 (((a)->s6_addr32[0] == 0) && \
94 ((a)->s6_addr32[1] == 0) && \
95 ((a)->s6_addr32[2] == htonl(0x0000ffff)))
99 #define sock_write SockWrite /* Watt-32 uses same names */
100 #define sock_read SockRead
101 #define sock_puts SockPuts
104 static int dgram_write(BIO
*h
, const char *buf
, int num
);
105 static int dgram_read(BIO
*h
, char *buf
, int size
);
106 static int dgram_puts(BIO
*h
, const char *str
);
107 static long dgram_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
108 static int dgram_new(BIO
*h
);
109 static int dgram_free(BIO
*data
);
110 static int dgram_clear(BIO
*bio
);
112 #ifndef OPENSSL_NO_SCTP
113 static int dgram_sctp_write(BIO
*h
, const char *buf
, int num
);
114 static int dgram_sctp_read(BIO
*h
, char *buf
, int size
);
115 static int dgram_sctp_puts(BIO
*h
, const char *str
);
116 static long dgram_sctp_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
117 static int dgram_sctp_new(BIO
*h
);
118 static int dgram_sctp_free(BIO
*data
);
119 #ifdef SCTP_AUTHENTICATION_EVENT
120 static void dgram_sctp_handle_auth_free_key_event(BIO
*b
, union sctp_notification
*snp
);
124 static int BIO_dgram_should_retry(int s
);
126 static void get_current_time(struct timeval
*t
);
128 static BIO_METHOD methods_dgramp
=
135 NULL
, /* dgram_gets, */
142 #ifndef OPENSSL_NO_SCTP
143 static BIO_METHOD methods_dgramp_sctp
=
146 "datagram sctp socket",
150 NULL
, /* dgram_gets, */
158 typedef struct bio_dgram_data_st
162 struct sockaddr_in sa_in
;
164 struct sockaddr_in6 sa_in6
;
167 unsigned int connected
;
170 struct timeval next_timeout
;
171 struct timeval socket_timeout
;
174 #ifndef OPENSSL_NO_SCTP
175 typedef struct bio_dgram_sctp_save_message_st
180 } bio_dgram_sctp_save_message
;
182 typedef struct bio_dgram_sctp_data_st
186 struct sockaddr_in sa_in
;
188 struct sockaddr_in6 sa_in6
;
191 unsigned int connected
;
194 struct bio_dgram_sctp_sndinfo sndinfo
;
195 struct bio_dgram_sctp_rcvinfo rcvinfo
;
196 struct bio_dgram_sctp_prinfo prinfo
;
197 void (*handle_notifications
)(BIO
*bio
, void *context
, void *buf
);
198 void* notification_context
;
203 int peer_auth_tested
;
204 bio_dgram_sctp_save_message saved_message
;
205 } bio_dgram_sctp_data
;
208 BIO_METHOD
*BIO_s_datagram(void)
210 return(&methods_dgramp
);
213 BIO
*BIO_new_dgram(int fd
, int close_flag
)
217 ret
=BIO_new(BIO_s_datagram());
218 if (ret
== NULL
) return(NULL
);
219 BIO_set_fd(ret
,fd
,close_flag
);
223 static int dgram_new(BIO
*bi
)
225 bio_dgram_data
*data
= NULL
;
229 data
= OPENSSL_malloc(sizeof(bio_dgram_data
));
232 memset(data
, 0x00, sizeof(bio_dgram_data
));
239 static int dgram_free(BIO
*a
)
241 bio_dgram_data
*data
;
243 if (a
== NULL
) return(0);
244 if ( ! dgram_clear(a
))
247 data
= (bio_dgram_data
*)a
->ptr
;
248 if(data
!= NULL
) OPENSSL_free(data
);
253 static int dgram_clear(BIO
*a
)
255 if (a
== NULL
) return(0);
268 static void dgram_adjust_rcv_timeout(BIO
*b
)
270 #if defined(SO_RCVTIMEO)
271 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
272 union { size_t s
; int i
; } sz
= {0};
274 /* Is a timer active? */
275 if (data
->next_timeout
.tv_sec
> 0 || data
->next_timeout
.tv_usec
> 0)
277 struct timeval timenow
, timeleft
;
279 /* Read current socket timeout */
280 #ifdef OPENSSL_SYS_WINDOWS
283 sz
.i
= sizeof(timeout
);
284 if (getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
285 (void*)&timeout
, &sz
.i
) < 0)
286 { perror("getsockopt"); }
289 data
->socket_timeout
.tv_sec
= timeout
/ 1000;
290 data
->socket_timeout
.tv_usec
= (timeout
% 1000) * 1000;
293 sz
.i
= sizeof(data
->socket_timeout
);
294 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
295 &(data
->socket_timeout
), (void *)&sz
) < 0)
296 { perror("getsockopt"); }
297 else if (sizeof(sz
.s
)!=sizeof(sz
.i
) && sz
.i
==0)
298 OPENSSL_assert(sz
.s
<=sizeof(data
->socket_timeout
));
301 /* Get current time */
302 get_current_time(&timenow
);
304 /* Calculate time left until timer expires */
305 memcpy(&timeleft
, &(data
->next_timeout
), sizeof(struct timeval
));
306 timeleft
.tv_sec
-= timenow
.tv_sec
;
307 timeleft
.tv_usec
-= timenow
.tv_usec
;
308 if (timeleft
.tv_usec
< 0)
311 timeleft
.tv_usec
+= 1000000;
314 if (timeleft
.tv_sec
< 0)
317 timeleft
.tv_usec
= 1;
320 /* Adjust socket timeout if next handhake message timer
321 * will expire earlier.
323 if ((data
->socket_timeout
.tv_sec
== 0 && data
->socket_timeout
.tv_usec
== 0) ||
324 (data
->socket_timeout
.tv_sec
> timeleft
.tv_sec
) ||
325 (data
->socket_timeout
.tv_sec
== timeleft
.tv_sec
&&
326 data
->socket_timeout
.tv_usec
>= timeleft
.tv_usec
))
328 #ifdef OPENSSL_SYS_WINDOWS
329 timeout
= timeleft
.tv_sec
* 1000 + timeleft
.tv_usec
/ 1000;
330 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
331 (void*)&timeout
, sizeof(timeout
)) < 0)
332 { perror("setsockopt"); }
334 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, &timeleft
,
335 sizeof(struct timeval
)) < 0)
336 { perror("setsockopt"); }
343 static void dgram_reset_rcv_timeout(BIO
*b
)
345 #if defined(SO_RCVTIMEO)
346 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
348 /* Is a timer active? */
349 if (data
->next_timeout
.tv_sec
> 0 || data
->next_timeout
.tv_usec
> 0)
351 #ifdef OPENSSL_SYS_WINDOWS
352 int timeout
= data
->socket_timeout
.tv_sec
* 1000 +
353 data
->socket_timeout
.tv_usec
/ 1000;
354 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
355 (void*)&timeout
, sizeof(timeout
)) < 0)
356 { perror("setsockopt"); }
358 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, &(data
->socket_timeout
),
359 sizeof(struct timeval
)) < 0)
360 { perror("setsockopt"); }
366 static int dgram_read(BIO
*b
, char *out
, int outl
)
369 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
373 * See commentary in b_sock.c. <appro>
375 union { size_t s
; int i
; } len
;
378 struct sockaddr_in sa_in
;
380 struct sockaddr_in6 sa_in6
;
386 sa
.len
.i
=sizeof(sa
.peer
);
390 clear_socket_error();
391 memset(&sa
.peer
, 0x00, sizeof(sa
.peer
));
392 dgram_adjust_rcv_timeout(b
);
393 ret
=recvfrom(b
->num
,out
,outl
,0,&sa
.peer
.sa
,(void *)&sa
.len
);
394 if (sizeof(sa
.len
.i
)!=sizeof(sa
.len
.s
) && sa
.len
.i
==0)
396 OPENSSL_assert(sa
.len
.s
<=sizeof(sa
.peer
));
397 sa
.len
.i
= (int)sa
.len
.s
;
400 if ( ! data
->connected
&& ret
>= 0)
401 BIO_ctrl(b
, BIO_CTRL_DGRAM_SET_PEER
, 0, &sa
.peer
);
403 BIO_clear_retry_flags(b
);
406 if (BIO_dgram_should_retry(ret
))
408 BIO_set_retry_read(b
);
409 data
->_errno
= get_last_socket_error();
413 dgram_reset_rcv_timeout(b
);
418 static int dgram_write(BIO
*b
, const char *in
, int inl
)
421 bio_dgram_data
*data
= (bio_dgram_data
*)b
->ptr
;
422 clear_socket_error();
424 if ( data
->connected
)
425 ret
=writesocket(b
->num
,in
,inl
);
428 int peerlen
= sizeof(data
->peer
);
430 if (data
->peer
.sa
.sa_family
== AF_INET
)
431 peerlen
= sizeof(data
->peer
.sa_in
);
433 else if (data
->peer
.sa
.sa_family
== AF_INET6
)
434 peerlen
= sizeof(data
->peer
.sa_in6
);
436 #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
437 ret
=sendto(b
->num
, (char *)in
, inl
, 0, &data
->peer
.sa
, peerlen
);
439 ret
=sendto(b
->num
, in
, inl
, 0, &data
->peer
.sa
, peerlen
);
443 BIO_clear_retry_flags(b
);
446 if (BIO_dgram_should_retry(ret
))
448 BIO_set_retry_write(b
);
449 data
->_errno
= get_last_socket_error();
451 #if 0 /* higher layers are responsible for querying MTU, if necessary */
452 if ( data
->_errno
== EMSGSIZE
)
453 /* retrieve the new MTU */
454 BIO_ctrl(b
, BIO_CTRL_DGRAM_QUERY_MTU
, 0, NULL
);
461 static long dgram_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
465 struct sockaddr
*to
= NULL
;
466 bio_dgram_data
*data
= NULL
;
468 #if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
469 socklen_t sockopt_len
; /* assume that system supporting IP_MTU is
470 * modern enough to define socklen_t */
474 struct sockaddr_in s4
;
476 struct sockaddr_in6 s6
;
481 data
= (bio_dgram_data
*)b
->ptr
;
487 case BIO_C_FILE_SEEK
:
490 case BIO_C_FILE_TELL
:
496 b
->num
= *((int *)ptr
);
497 b
->shutdown
=(int)num
;
504 if (ip
!= NULL
) *ip
=b
->num
;
510 case BIO_CTRL_GET_CLOSE
:
513 case BIO_CTRL_SET_CLOSE
:
514 b
->shutdown
=(int)num
;
516 case BIO_CTRL_PENDING
:
517 case BIO_CTRL_WPENDING
:
524 case BIO_CTRL_DGRAM_CONNECT
:
525 to
= (struct sockaddr
*)ptr
;
527 if (connect(b
->num
, to
, sizeof(struct sockaddr
)) < 0)
528 { perror("connect"); ret
= 0; }
532 switch (to
->sa_family
)
535 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
539 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
543 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
550 /* (Linux)kernel sets DF bit on outgoing IP packets */
551 case BIO_CTRL_DGRAM_MTU_DISCOVER
:
552 #if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
553 addr_len
= (socklen_t
)sizeof(addr
);
554 memset((void *)&addr
, 0, sizeof(addr
));
555 if (getsockname(b
->num
, &addr
.sa
, &addr_len
) < 0)
560 switch (addr
.sa
.sa_family
)
563 sockopt_val
= IP_PMTUDISC_DO
;
564 if ((ret
= setsockopt(b
->num
, IPPROTO_IP
, IP_MTU_DISCOVER
,
565 &sockopt_val
, sizeof(sockopt_val
))) < 0)
566 perror("setsockopt");
568 #if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
570 sockopt_val
= IPV6_PMTUDISC_DO
;
571 if ((ret
= setsockopt(b
->num
, IPPROTO_IPV6
, IPV6_MTU_DISCOVER
,
572 &sockopt_val
, sizeof(sockopt_val
))) < 0)
573 perror("setsockopt");
584 case BIO_CTRL_DGRAM_QUERY_MTU
:
585 #if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
586 addr_len
= (socklen_t
)sizeof(addr
);
587 memset((void *)&addr
, 0, sizeof(addr
));
588 if (getsockname(b
->num
, &addr
.sa
, &addr_len
) < 0)
593 sockopt_len
= sizeof(sockopt_val
);
594 switch (addr
.sa
.sa_family
)
597 if ((ret
= getsockopt(b
->num
, IPPROTO_IP
, IP_MTU
, (void *)&sockopt_val
,
598 &sockopt_len
)) < 0 || sockopt_val
< 0)
604 /* we assume that the transport protocol is UDP and no
605 * IP options are used.
607 data
->mtu
= sockopt_val
- 8 - 20;
611 #if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
613 if ((ret
= getsockopt(b
->num
, IPPROTO_IPV6
, IPV6_MTU
, (void *)&sockopt_val
,
614 &sockopt_len
)) < 0 || sockopt_val
< 0)
620 /* we assume that the transport protocol is UDP and no
621 * IPV6 options are used.
623 data
->mtu
= sockopt_val
- 8 - 40;
636 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU
:
637 switch (data
->peer
.sa
.sa_family
)
644 #ifdef IN6_IS_ADDR_V4MAPPED
645 if (IN6_IS_ADDR_V4MAPPED(&data
->peer
.sa_in6
.sin6_addr
))
657 case BIO_CTRL_DGRAM_GET_MTU
:
660 case BIO_CTRL_DGRAM_SET_MTU
:
664 case BIO_CTRL_DGRAM_SET_CONNECTED
:
665 to
= (struct sockaddr
*)ptr
;
670 switch (to
->sa_family
)
673 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
677 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
681 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
688 memset(&(data
->peer
), 0x00, sizeof(data
->peer
));
691 case BIO_CTRL_DGRAM_GET_PEER
:
692 switch (data
->peer
.sa
.sa_family
)
695 ret
=sizeof(data
->peer
.sa_in
);
699 ret
=sizeof(data
->peer
.sa_in6
);
703 ret
=sizeof(data
->peer
.sa
);
706 if (num
==0 || num
>ret
)
708 memcpy(ptr
,&data
->peer
,(ret
=num
));
710 case BIO_CTRL_DGRAM_SET_PEER
:
711 to
= (struct sockaddr
*) ptr
;
712 switch (to
->sa_family
)
715 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in
));
719 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa_in6
));
723 memcpy(&data
->peer
,to
,sizeof(data
->peer
.sa
));
727 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
:
728 memcpy(&(data
->next_timeout
), ptr
, sizeof(struct timeval
));
730 #if defined(SO_RCVTIMEO)
731 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT
:
732 #ifdef OPENSSL_SYS_WINDOWS
734 struct timeval
*tv
= (struct timeval
*)ptr
;
735 int timeout
= tv
->tv_sec
* 1000 + tv
->tv_usec
/1000;
736 if (setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
737 (void*)&timeout
, sizeof(timeout
)) < 0)
738 { perror("setsockopt"); ret
= -1; }
741 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
, ptr
,
742 sizeof(struct timeval
)) < 0)
743 { perror("setsockopt"); ret
= -1; }
746 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT
:
748 union { size_t s
; int i
; } sz
= {0};
749 #ifdef OPENSSL_SYS_WINDOWS
751 struct timeval
*tv
= (struct timeval
*)ptr
;
753 sz
.i
= sizeof(timeout
);
754 if (getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
755 (void*)&timeout
, &sz
.i
) < 0)
756 { perror("getsockopt"); ret
= -1; }
759 tv
->tv_sec
= timeout
/ 1000;
760 tv
->tv_usec
= (timeout
% 1000) * 1000;
764 sz
.i
= sizeof(struct timeval
);
765 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_RCVTIMEO
,
766 ptr
, (void *)&sz
) < 0)
767 { perror("getsockopt"); ret
= -1; }
768 else if (sizeof(sz
.s
)!=sizeof(sz
.i
) && sz
.i
==0)
770 OPENSSL_assert(sz
.s
<=sizeof(struct timeval
));
779 #if defined(SO_SNDTIMEO)
780 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT
:
781 #ifdef OPENSSL_SYS_WINDOWS
783 struct timeval
*tv
= (struct timeval
*)ptr
;
784 int timeout
= tv
->tv_sec
* 1000 + tv
->tv_usec
/1000;
785 if (setsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
786 (void*)&timeout
, sizeof(timeout
)) < 0)
787 { perror("setsockopt"); ret
= -1; }
790 if ( setsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
, ptr
,
791 sizeof(struct timeval
)) < 0)
792 { perror("setsockopt"); ret
= -1; }
795 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT
:
797 union { size_t s
; int i
; } sz
= {0};
798 #ifdef OPENSSL_SYS_WINDOWS
800 struct timeval
*tv
= (struct timeval
*)ptr
;
802 sz
.i
= sizeof(timeout
);
803 if (getsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
804 (void*)&timeout
, &sz
.i
) < 0)
805 { perror("getsockopt"); ret
= -1; }
808 tv
->tv_sec
= timeout
/ 1000;
809 tv
->tv_usec
= (timeout
% 1000) * 1000;
813 sz
.i
= sizeof(struct timeval
);
814 if ( getsockopt(b
->num
, SOL_SOCKET
, SO_SNDTIMEO
,
815 ptr
, (void *)&sz
) < 0)
816 { perror("getsockopt"); ret
= -1; }
817 else if (sizeof(sz
.s
)!=sizeof(sz
.i
) && sz
.i
==0)
819 OPENSSL_assert(sz
.s
<=sizeof(struct timeval
));
828 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP
:
830 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP
:
831 #ifdef OPENSSL_SYS_WINDOWS
832 if ( data
->_errno
== WSAETIMEDOUT
)
834 if ( data
->_errno
== EAGAIN
)
844 case BIO_CTRL_DGRAM_MTU_EXCEEDED
:
845 if ( data
->_errno
== EMSGSIZE
)
854 case BIO_CTRL_DGRAM_SET_DONT_FRAG
:
855 sockopt_val
= num
? 1 : 0;
857 switch (data
->peer
.sa
.sa_family
)
860 #if defined(IP_DONTFRAG)
861 if ((ret
= setsockopt(b
->num
, IPPROTO_IP
, IP_DONTFRAG
,
862 &sockopt_val
, sizeof(sockopt_val
))) < 0)
863 { perror("setsockopt"); ret
= -1; }
864 #elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTUDISCOVER)
865 if ((sockopt_val
= num
? IP_PMTUDISC_PROBE
: IP_PMTUDISC_DONT
),
866 (ret
= setsockopt(b
->num
, IPPROTO_IP
, IP_MTU_DISCOVER
,
867 &sockopt_val
, sizeof(sockopt_val
))) < 0)
868 { perror("setsockopt"); ret
= -1; }
869 #elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
870 if ((ret
= setsockopt(b
->num
, IPPROTO_IP
, IP_DONTFRAGMENT
,
871 (const char *)&sockopt_val
, sizeof(sockopt_val
))) < 0)
872 { perror("setsockopt"); ret
= -1; }
879 #if defined(IPV6_DONTFRAG)
880 if ((ret
= setsockopt(b
->num
, IPPROTO_IPV6
, IPV6_DONTFRAG
,
881 (const void *)&sockopt_val
, sizeof(sockopt_val
))) < 0)
882 { perror("setsockopt"); ret
= -1; }
883 #elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
884 if ((sockopt_val
= num
? IP_PMTUDISC_PROBE
: IP_PMTUDISC_DONT
),
885 (ret
= setsockopt(b
->num
, IPPROTO_IPV6
, IPV6_MTU_DISCOVER
,
886 &sockopt_val
, sizeof(sockopt_val
))) < 0)
887 { perror("setsockopt"); ret
= -1; }
905 static int dgram_puts(BIO
*bp
, const char *str
)
910 ret
=dgram_write(bp
,str
,n
);
914 #ifndef OPENSSL_NO_SCTP
915 BIO_METHOD
*BIO_s_datagram_sctp(void)
917 return(&methods_dgramp_sctp
);
920 BIO
*BIO_new_dgram_sctp(int fd
, int close_flag
)
923 int ret
, optval
= 20000;
924 int auth_data
= 0, auth_forward
= 0;
926 struct sctp_authchunk auth
;
927 struct sctp_authchunks
*authchunks
;
928 socklen_t sockopt_len
;
929 #ifdef SCTP_AUTHENTICATION_EVENT
931 struct sctp_event event
;
933 struct sctp_event_subscribe event
;
937 bio
=BIO_new(BIO_s_datagram_sctp());
938 if (bio
== NULL
) return(NULL
);
939 BIO_set_fd(bio
,fd
,close_flag
);
941 /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
942 auth
.sauth_chunk
= OPENSSL_SCTP_DATA_CHUNK_TYPE
;
943 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_AUTH_CHUNK
, &auth
, sizeof(struct sctp_authchunk
));
944 OPENSSL_assert(ret
>= 0);
945 auth
.sauth_chunk
= OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
;
946 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_AUTH_CHUNK
, &auth
, sizeof(struct sctp_authchunk
));
947 OPENSSL_assert(ret
>= 0);
949 /* Test if activation was successful. When using accept(),
950 * SCTP-AUTH has to be activated for the listening socket
951 * already, otherwise the connected socket won't use it. */
952 sockopt_len
= (socklen_t
)(sizeof(sctp_assoc_t
) + 256 * sizeof(uint8_t));
953 authchunks
= OPENSSL_malloc(sockopt_len
);
954 memset(authchunks
, 0, sockopt_len
);
955 ret
= getsockopt(fd
, IPPROTO_SCTP
, SCTP_LOCAL_AUTH_CHUNKS
, authchunks
, &sockopt_len
);
956 OPENSSL_assert(ret
>= 0);
958 for (p
= (unsigned char*) authchunks
->gauth_chunks
;
959 p
< (unsigned char*) authchunks
+ sockopt_len
;
960 p
+= sizeof(uint8_t))
962 if (*p
== OPENSSL_SCTP_DATA_CHUNK_TYPE
) auth_data
= 1;
963 if (*p
== OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
) auth_forward
= 1;
966 OPENSSL_free(authchunks
);
968 OPENSSL_assert(auth_data
);
969 OPENSSL_assert(auth_forward
);
971 #ifdef SCTP_AUTHENTICATION_EVENT
973 memset(&event
, 0, sizeof(struct sctp_event
));
974 event
.se_assoc_id
= 0;
975 event
.se_type
= SCTP_AUTHENTICATION_EVENT
;
977 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
978 OPENSSL_assert(ret
>= 0);
980 sockopt_len
= (socklen_t
) sizeof(struct sctp_event_subscribe
);
981 ret
= getsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &sockopt_len
);
982 OPENSSL_assert(ret
>= 0);
984 event
.sctp_authentication_event
= 1;
986 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
987 OPENSSL_assert(ret
>= 0);
991 /* Disable partial delivery by setting the min size
992 * larger than the max record size of 2^14 + 2048 + 13
994 ret
= setsockopt(fd
, IPPROTO_SCTP
, SCTP_PARTIAL_DELIVERY_POINT
, &optval
, sizeof(optval
));
995 OPENSSL_assert(ret
>= 0);
1000 int BIO_dgram_is_sctp(BIO
*bio
)
1002 return (BIO_method_type(bio
) == BIO_TYPE_DGRAM_SCTP
);
1005 static int dgram_sctp_new(BIO
*bi
)
1007 bio_dgram_sctp_data
*data
= NULL
;
1011 data
= OPENSSL_malloc(sizeof(bio_dgram_sctp_data
));
1014 memset(data
, 0x00, sizeof(bio_dgram_sctp_data
));
1015 #ifdef SCTP_PR_SCTP_NONE
1016 data
->prinfo
.pr_policy
= SCTP_PR_SCTP_NONE
;
1024 static int dgram_sctp_free(BIO
*a
)
1026 bio_dgram_sctp_data
*data
;
1028 if (a
== NULL
) return(0);
1029 if ( ! dgram_clear(a
))
1032 data
= (bio_dgram_sctp_data
*)a
->ptr
;
1033 if(data
!= NULL
) OPENSSL_free(data
);
1038 #ifdef SCTP_AUTHENTICATION_EVENT
1039 void dgram_sctp_handle_auth_free_key_event(BIO
*b
, union sctp_notification
*snp
)
1042 struct sctp_authkey_event
* authkeyevent
= &snp
->sn_auth_event
;
1044 if (authkeyevent
->auth_indication
== SCTP_AUTH_FREE_KEY
)
1046 struct sctp_authkeyid authkeyid
;
1049 authkeyid
.scact_keynumber
= authkeyevent
->auth_keynumber
;
1050 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DELETE_KEY
,
1051 &authkeyid
, sizeof(struct sctp_authkeyid
));
1056 static int dgram_sctp_read(BIO
*b
, char *out
, int outl
)
1058 int ret
= 0, n
= 0, i
, optval
;
1060 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1061 union sctp_notification
*snp
;
1064 struct cmsghdr
*cmsg
;
1069 clear_socket_error();
1073 memset(&data
->rcvinfo
, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo
));
1076 msg
.msg_name
= NULL
;
1077 msg
.msg_namelen
= 0;
1080 msg
.msg_control
= cmsgbuf
;
1081 msg
.msg_controllen
= 512;
1083 n
= recvmsg(b
->num
, &msg
, 0);
1092 if (msg
.msg_controllen
> 0)
1094 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
; cmsg
= CMSG_NXTHDR(&msg
, cmsg
))
1096 if (cmsg
->cmsg_level
!= IPPROTO_SCTP
)
1099 if (cmsg
->cmsg_type
== SCTP_RCVINFO
)
1101 struct sctp_rcvinfo
*rcvinfo
;
1103 rcvinfo
= (struct sctp_rcvinfo
*)CMSG_DATA(cmsg
);
1104 data
->rcvinfo
.rcv_sid
= rcvinfo
->rcv_sid
;
1105 data
->rcvinfo
.rcv_ssn
= rcvinfo
->rcv_ssn
;
1106 data
->rcvinfo
.rcv_flags
= rcvinfo
->rcv_flags
;
1107 data
->rcvinfo
.rcv_ppid
= rcvinfo
->rcv_ppid
;
1108 data
->rcvinfo
.rcv_tsn
= rcvinfo
->rcv_tsn
;
1109 data
->rcvinfo
.rcv_cumtsn
= rcvinfo
->rcv_cumtsn
;
1110 data
->rcvinfo
.rcv_context
= rcvinfo
->rcv_context
;
1114 if (cmsg
->cmsg_type
== SCTP_SNDRCV
)
1116 struct sctp_sndrcvinfo
*sndrcvinfo
;
1118 sndrcvinfo
= (struct sctp_sndrcvinfo
*)CMSG_DATA(cmsg
);
1119 data
->rcvinfo
.rcv_sid
= sndrcvinfo
->sinfo_stream
;
1120 data
->rcvinfo
.rcv_ssn
= sndrcvinfo
->sinfo_ssn
;
1121 data
->rcvinfo
.rcv_flags
= sndrcvinfo
->sinfo_flags
;
1122 data
->rcvinfo
.rcv_ppid
= sndrcvinfo
->sinfo_ppid
;
1123 data
->rcvinfo
.rcv_tsn
= sndrcvinfo
->sinfo_tsn
;
1124 data
->rcvinfo
.rcv_cumtsn
= sndrcvinfo
->sinfo_cumtsn
;
1125 data
->rcvinfo
.rcv_context
= sndrcvinfo
->sinfo_context
;
1131 if (msg
.msg_flags
& MSG_NOTIFICATION
)
1133 snp
= (union sctp_notification
*) out
;
1134 if (snp
->sn_header
.sn_type
== SCTP_SENDER_DRY_EVENT
)
1137 struct sctp_event event
;
1139 struct sctp_event_subscribe event
;
1140 socklen_t eventsize
;
1142 /* If a message has been delayed until the socket
1143 * is dry, it can be sent now.
1145 if (data
->saved_message
.length
> 0)
1147 dgram_sctp_write(data
->saved_message
.bio
, data
->saved_message
.data
,
1148 data
->saved_message
.length
);
1149 OPENSSL_free(data
->saved_message
.data
);
1150 data
->saved_message
.length
= 0;
1153 /* disable sender dry event */
1155 memset(&event
, 0, sizeof(struct sctp_event
));
1156 event
.se_assoc_id
= 0;
1157 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1159 i
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1160 OPENSSL_assert(i
>= 0);
1162 eventsize
= sizeof(struct sctp_event_subscribe
);
1163 i
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1164 OPENSSL_assert(i
>= 0);
1166 event
.sctp_sender_dry_event
= 0;
1168 i
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1169 OPENSSL_assert(i
>= 0);
1173 #ifdef SCTP_AUTHENTICATION_EVENT
1174 if (snp
->sn_header
.sn_type
== SCTP_AUTHENTICATION_EVENT
)
1175 dgram_sctp_handle_auth_free_key_event(b
, snp
);
1178 if (data
->handle_notifications
!= NULL
)
1179 data
->handle_notifications(b
, data
->notification_context
, (void*) out
);
1181 memset(out
, 0, outl
);
1186 while ((msg
.msg_flags
& MSG_NOTIFICATION
) && (msg
.msg_flags
& MSG_EOR
) && (ret
< outl
));
1188 if (ret
> 0 && !(msg
.msg_flags
& MSG_EOR
))
1190 /* Partial message read, this should never happen! */
1192 /* The buffer was too small, this means the peer sent
1193 * a message that was larger than allowed. */
1197 /* Test if socket buffer can handle max record
1198 * size (2^14 + 2048 + 13)
1200 optlen
= (socklen_t
) sizeof(int);
1201 ret
= getsockopt(b
->num
, SOL_SOCKET
, SO_RCVBUF
, &optval
, &optlen
);
1202 OPENSSL_assert(ret
>= 0);
1203 OPENSSL_assert(optval
>= 18445);
1205 /* Test if SCTP doesn't partially deliver below
1206 * max record size (2^14 + 2048 + 13)
1208 optlen
= (socklen_t
) sizeof(int);
1209 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_PARTIAL_DELIVERY_POINT
,
1211 OPENSSL_assert(ret
>= 0);
1212 OPENSSL_assert(optval
>= 18445);
1214 /* Partially delivered notification??? Probably a bug.... */
1215 OPENSSL_assert(!(msg
.msg_flags
& MSG_NOTIFICATION
));
1217 /* Everything seems ok till now, so it's most likely
1218 * a message dropped by PR-SCTP.
1220 memset(out
, 0, outl
);
1221 BIO_set_retry_read(b
);
1225 BIO_clear_retry_flags(b
);
1228 if (BIO_dgram_should_retry(ret
))
1230 BIO_set_retry_read(b
);
1231 data
->_errno
= get_last_socket_error();
1235 /* Test if peer uses SCTP-AUTH before continuing */
1236 if (!data
->peer_auth_tested
)
1238 int ii
, auth_data
= 0, auth_forward
= 0;
1240 struct sctp_authchunks
*authchunks
;
1242 optlen
= (socklen_t
)(sizeof(sctp_assoc_t
) + 256 * sizeof(uint8_t));
1243 authchunks
= OPENSSL_malloc(optlen
);
1244 memset(authchunks
, 0, optlen
);
1245 ii
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_PEER_AUTH_CHUNKS
, authchunks
, &optlen
);
1246 OPENSSL_assert(ii
>= 0);
1248 for (p
= (unsigned char*) authchunks
->gauth_chunks
;
1249 p
< (unsigned char*) authchunks
+ optlen
;
1250 p
+= sizeof(uint8_t))
1252 if (*p
== OPENSSL_SCTP_DATA_CHUNK_TYPE
) auth_data
= 1;
1253 if (*p
== OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE
) auth_forward
= 1;
1256 OPENSSL_free(authchunks
);
1258 if (!auth_data
|| !auth_forward
)
1260 BIOerr(BIO_F_DGRAM_SCTP_READ
,BIO_R_CONNECT_ERROR
);
1264 data
->peer_auth_tested
= 1;
1270 static int dgram_sctp_write(BIO
*b
, const char *in
, int inl
)
1273 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1274 struct bio_dgram_sctp_sndinfo
*sinfo
= &(data
->sndinfo
);
1275 struct bio_dgram_sctp_prinfo
*pinfo
= &(data
->prinfo
);
1276 struct bio_dgram_sctp_sndinfo handshake_sinfo
;
1277 struct iovec iov
[1];
1279 struct cmsghdr
*cmsg
;
1280 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1281 char cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndinfo
)) + CMSG_SPACE(sizeof(struct sctp_prinfo
))];
1282 struct sctp_sndinfo
*sndinfo
;
1283 struct sctp_prinfo
*prinfo
;
1285 char cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo
))];
1286 struct sctp_sndrcvinfo
*sndrcvinfo
;
1289 clear_socket_error();
1291 /* If we're send anything else than application data,
1292 * disable all user parameters and flags.
1295 memset(&handshake_sinfo
, 0x00, sizeof(struct bio_dgram_sctp_sndinfo
));
1296 #ifdef SCTP_SACK_IMMEDIATELY
1297 handshake_sinfo
.snd_flags
= SCTP_SACK_IMMEDIATELY
;
1299 sinfo
= &handshake_sinfo
;
1302 /* If we have to send a shutdown alert message and the
1303 * socket is not dry yet, we have to save it and send it
1304 * as soon as the socket gets dry.
1306 if (data
->save_shutdown
&& !BIO_dgram_sctp_wait_for_dry(b
))
1308 data
->saved_message
.bio
= b
;
1309 data
->saved_message
.length
= inl
;
1310 data
->saved_message
.data
= OPENSSL_malloc(inl
);
1311 memcpy(data
->saved_message
.data
, in
, inl
);
1315 iov
[0].iov_base
= (char *)in
;
1316 iov
[0].iov_len
= inl
;
1317 msg
.msg_name
= NULL
;
1318 msg
.msg_namelen
= 0;
1321 msg
.msg_control
= (caddr_t
)cmsgbuf
;
1322 msg
.msg_controllen
= 0;
1324 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1325 cmsg
= (struct cmsghdr
*)cmsgbuf
;
1326 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1327 cmsg
->cmsg_type
= SCTP_SNDINFO
;
1328 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_sndinfo
));
1329 sndinfo
= (struct sctp_sndinfo
*)CMSG_DATA(cmsg
);
1330 memset(sndinfo
, 0, sizeof(struct sctp_sndinfo
));
1331 sndinfo
->snd_sid
= sinfo
->snd_sid
;
1332 sndinfo
->snd_flags
= sinfo
->snd_flags
;
1333 sndinfo
->snd_ppid
= sinfo
->snd_ppid
;
1334 sndinfo
->snd_context
= sinfo
->snd_context
;
1335 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_sndinfo
));
1337 cmsg
= (struct cmsghdr
*)&cmsgbuf
[CMSG_SPACE(sizeof(struct sctp_sndinfo
))];
1338 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1339 cmsg
->cmsg_type
= SCTP_PRINFO
;
1340 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_prinfo
));
1341 prinfo
= (struct sctp_prinfo
*)CMSG_DATA(cmsg
);
1342 memset(prinfo
, 0, sizeof(struct sctp_prinfo
));
1343 prinfo
->pr_policy
= pinfo
->pr_policy
;
1344 prinfo
->pr_value
= pinfo
->pr_value
;
1345 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_prinfo
));
1347 cmsg
= (struct cmsghdr
*)cmsgbuf
;
1348 cmsg
->cmsg_level
= IPPROTO_SCTP
;
1349 cmsg
->cmsg_type
= SCTP_SNDRCV
;
1350 cmsg
->cmsg_len
= CMSG_LEN(sizeof(struct sctp_sndrcvinfo
));
1351 sndrcvinfo
= (struct sctp_sndrcvinfo
*)CMSG_DATA(cmsg
);
1352 memset(sndrcvinfo
, 0, sizeof(struct sctp_sndrcvinfo
));
1353 sndrcvinfo
->sinfo_stream
= sinfo
->snd_sid
;
1354 sndrcvinfo
->sinfo_flags
= sinfo
->snd_flags
;
1356 sndrcvinfo
->sinfo_flags
|= pinfo
->pr_policy
;
1358 sndrcvinfo
->sinfo_ppid
= sinfo
->snd_ppid
;
1359 sndrcvinfo
->sinfo_context
= sinfo
->snd_context
;
1360 sndrcvinfo
->sinfo_timetolive
= pinfo
->pr_value
;
1361 msg
.msg_controllen
+= CMSG_SPACE(sizeof(struct sctp_sndrcvinfo
));
1364 ret
= sendmsg(b
->num
, &msg
, 0);
1366 BIO_clear_retry_flags(b
);
1369 if (BIO_dgram_should_retry(ret
))
1371 BIO_set_retry_write(b
);
1372 data
->_errno
= get_last_socket_error();
1378 static long dgram_sctp_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
1381 bio_dgram_sctp_data
*data
= NULL
;
1382 socklen_t sockopt_len
= 0;
1383 struct sctp_authkeyid authkeyid
;
1384 struct sctp_authkey
*authkey
= NULL
;
1386 data
= (bio_dgram_sctp_data
*)b
->ptr
;
1390 case BIO_CTRL_DGRAM_QUERY_MTU
:
1391 /* Set to maximum (2^14)
1392 * and ignore user input to enable transport
1393 * protocol fragmentation.
1394 * Returns always 2^14.
1399 case BIO_CTRL_DGRAM_SET_MTU
:
1400 /* Set to maximum (2^14)
1401 * and ignore input to enable transport
1402 * protocol fragmentation.
1403 * Returns always 2^14.
1408 case BIO_CTRL_DGRAM_SET_CONNECTED
:
1409 case BIO_CTRL_DGRAM_CONNECT
:
1410 /* Returns always -1. */
1413 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
:
1414 /* SCTP doesn't need the DTLS timer
1418 case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE
:
1420 data
->in_handshake
= 1;
1422 data
->in_handshake
= 0;
1424 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_NODELAY
, &data
->in_handshake
, sizeof(int));
1426 case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY
:
1427 /* New shared key for SCTP AUTH.
1428 * Returns 0 on success, -1 otherwise.
1431 /* Get active key */
1432 sockopt_len
= sizeof(struct sctp_authkeyid
);
1433 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1437 sockopt_len
= sizeof(struct sctp_authkey
) + 64 * sizeof(uint8_t);
1438 authkey
= OPENSSL_malloc(sockopt_len
);
1439 if (authkey
== NULL
)
1444 memset(authkey
, 0x00, sockopt_len
);
1445 authkey
->sca_keynumber
= authkeyid
.scact_keynumber
+ 1;
1447 /* This field is missing in FreeBSD 8.2 and earlier,
1448 * and FreeBSD 8.3 and higher work without it.
1450 authkey
->sca_keylength
= 64;
1452 memcpy(&authkey
->sca_key
[0], ptr
, 64 * sizeof(uint8_t));
1454 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_KEY
, authkey
, sockopt_len
);
1455 OPENSSL_free(authkey
);
1459 /* Reset active key */
1460 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
,
1461 &authkeyid
, sizeof(struct sctp_authkeyid
));
1465 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY
:
1466 /* Returns 0 on success, -1 otherwise. */
1468 /* Get active key */
1469 sockopt_len
= sizeof(struct sctp_authkeyid
);
1470 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1473 /* Set active key */
1474 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
+ 1;
1475 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
,
1476 &authkeyid
, sizeof(struct sctp_authkeyid
));
1479 /* CCS has been sent, so remember that and fall through
1480 * to check if we need to deactivate an old key
1484 case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD
:
1485 /* Returns 0 on success, -1 otherwise. */
1487 /* Has this command really been called or is this just a fall-through? */
1488 if (cmd
== BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD
)
1491 /* CSS has been both, received and sent, so deactivate an old key */
1492 if (data
->ccs_rcvd
== 1 && data
->ccs_sent
== 1)
1494 /* Get active key */
1495 sockopt_len
= sizeof(struct sctp_authkeyid
);
1496 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_ACTIVE_KEY
, &authkeyid
, &sockopt_len
);
1499 /* Deactivate key or delete second last key if
1500 * SCTP_AUTHENTICATION_EVENT is not available.
1502 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
- 1;
1503 #ifdef SCTP_AUTH_DEACTIVATE_KEY
1504 sockopt_len
= sizeof(struct sctp_authkeyid
);
1505 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DEACTIVATE_KEY
,
1506 &authkeyid
, sockopt_len
);
1509 #ifndef SCTP_AUTHENTICATION_EVENT
1510 if (authkeyid
.scact_keynumber
> 0)
1512 authkeyid
.scact_keynumber
= authkeyid
.scact_keynumber
- 1;
1513 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_AUTH_DELETE_KEY
,
1514 &authkeyid
, sizeof(struct sctp_authkeyid
));
1523 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO
:
1524 /* Returns the size of the copied struct. */
1525 if (num
> (long) sizeof(struct bio_dgram_sctp_sndinfo
))
1526 num
= sizeof(struct bio_dgram_sctp_sndinfo
);
1528 memcpy(ptr
, &(data
->sndinfo
), num
);
1531 case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO
:
1532 /* Returns the size of the copied struct. */
1533 if (num
> (long) sizeof(struct bio_dgram_sctp_sndinfo
))
1534 num
= sizeof(struct bio_dgram_sctp_sndinfo
);
1536 memcpy(&(data
->sndinfo
), ptr
, num
);
1538 case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO
:
1539 /* Returns the size of the copied struct. */
1540 if (num
> (long) sizeof(struct bio_dgram_sctp_rcvinfo
))
1541 num
= sizeof(struct bio_dgram_sctp_rcvinfo
);
1543 memcpy(ptr
, &data
->rcvinfo
, num
);
1547 case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO
:
1548 /* Returns the size of the copied struct. */
1549 if (num
> (long) sizeof(struct bio_dgram_sctp_rcvinfo
))
1550 num
= sizeof(struct bio_dgram_sctp_rcvinfo
);
1552 memcpy(&(data
->rcvinfo
), ptr
, num
);
1554 case BIO_CTRL_DGRAM_SCTP_GET_PRINFO
:
1555 /* Returns the size of the copied struct. */
1556 if (num
> (long) sizeof(struct bio_dgram_sctp_prinfo
))
1557 num
= sizeof(struct bio_dgram_sctp_prinfo
);
1559 memcpy(ptr
, &(data
->prinfo
), num
);
1562 case BIO_CTRL_DGRAM_SCTP_SET_PRINFO
:
1563 /* Returns the size of the copied struct. */
1564 if (num
> (long) sizeof(struct bio_dgram_sctp_prinfo
))
1565 num
= sizeof(struct bio_dgram_sctp_prinfo
);
1567 memcpy(&(data
->prinfo
), ptr
, num
);
1569 case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN
:
1570 /* Returns always 1. */
1572 data
->save_shutdown
= 1;
1574 data
->save_shutdown
= 0;
1578 /* Pass to default ctrl function to
1579 * process SCTP unspecific commands
1581 ret
=dgram_ctrl(b
, cmd
, num
, ptr
);
1587 int BIO_dgram_sctp_notification_cb(BIO
*b
,
1588 void (*handle_notifications
)(BIO
*bio
, void *context
, void *buf
),
1591 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*) b
->ptr
;
1593 if (handle_notifications
!= NULL
)
1595 data
->handle_notifications
= handle_notifications
;
1596 data
->notification_context
= context
;
1604 int BIO_dgram_sctp_wait_for_dry(BIO
*b
)
1607 int n
, sockflags
, ret
;
1608 union sctp_notification snp
;
1612 struct sctp_event event
;
1614 struct sctp_event_subscribe event
;
1615 socklen_t eventsize
;
1617 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1619 /* set sender dry event */
1621 memset(&event
, 0, sizeof(struct sctp_event
));
1622 event
.se_assoc_id
= 0;
1623 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1625 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1627 eventsize
= sizeof(struct sctp_event_subscribe
);
1628 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1632 event
.sctp_sender_dry_event
= 1;
1634 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1639 /* peek for notification */
1640 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1641 iov
.iov_base
= (char *)&snp
;
1642 iov
.iov_len
= sizeof(union sctp_notification
);
1643 msg
.msg_name
= NULL
;
1644 msg
.msg_namelen
= 0;
1647 msg
.msg_control
= NULL
;
1648 msg
.msg_controllen
= 0;
1651 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1654 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1660 /* if we find a notification, process it and try again if necessary */
1661 while (msg
.msg_flags
& MSG_NOTIFICATION
)
1663 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1664 iov
.iov_base
= (char *)&snp
;
1665 iov
.iov_len
= sizeof(union sctp_notification
);
1666 msg
.msg_name
= NULL
;
1667 msg
.msg_namelen
= 0;
1670 msg
.msg_control
= NULL
;
1671 msg
.msg_controllen
= 0;
1674 n
= recvmsg(b
->num
, &msg
, 0);
1677 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1683 if (snp
.sn_header
.sn_type
== SCTP_SENDER_DRY_EVENT
)
1687 /* disable sender dry event */
1689 memset(&event
, 0, sizeof(struct sctp_event
));
1690 event
.se_assoc_id
= 0;
1691 event
.se_type
= SCTP_SENDER_DRY_EVENT
;
1693 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENT
, &event
, sizeof(struct sctp_event
));
1695 eventsize
= (socklen_t
) sizeof(struct sctp_event_subscribe
);
1696 ret
= getsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, &eventsize
);
1700 event
.sctp_sender_dry_event
= 0;
1702 ret
= setsockopt(b
->num
, IPPROTO_SCTP
, SCTP_EVENTS
, &event
, sizeof(struct sctp_event_subscribe
));
1708 #ifdef SCTP_AUTHENTICATION_EVENT
1709 if (snp
.sn_header
.sn_type
== SCTP_AUTHENTICATION_EVENT
)
1710 dgram_sctp_handle_auth_free_key_event(b
, &snp
);
1713 if (data
->handle_notifications
!= NULL
)
1714 data
->handle_notifications(b
, data
->notification_context
, (void*) &snp
);
1716 /* found notification, peek again */
1717 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1718 iov
.iov_base
= (char *)&snp
;
1719 iov
.iov_len
= sizeof(union sctp_notification
);
1720 msg
.msg_name
= NULL
;
1721 msg
.msg_namelen
= 0;
1724 msg
.msg_control
= NULL
;
1725 msg
.msg_controllen
= 0;
1728 /* if we have seen the dry already, don't wait */
1731 sockflags
= fcntl(b
->num
, F_GETFL
, 0);
1732 fcntl(b
->num
, F_SETFL
, O_NONBLOCK
);
1735 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1739 fcntl(b
->num
, F_SETFL
, sockflags
);
1744 if ((n
< 0) && (get_last_socket_error() != EAGAIN
) && (get_last_socket_error() != EWOULDBLOCK
))
1751 /* read anything else */
1755 int BIO_dgram_sctp_msg_waiting(BIO
*b
)
1758 union sctp_notification snp
;
1761 bio_dgram_sctp_data
*data
= (bio_dgram_sctp_data
*)b
->ptr
;
1763 /* Check if there are any messages waiting to be read */
1766 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1767 iov
.iov_base
= (char *)&snp
;
1768 iov
.iov_len
= sizeof(union sctp_notification
);
1769 msg
.msg_name
= NULL
;
1770 msg
.msg_namelen
= 0;
1773 msg
.msg_control
= NULL
;
1774 msg
.msg_controllen
= 0;
1777 sockflags
= fcntl(b
->num
, F_GETFL
, 0);
1778 fcntl(b
->num
, F_SETFL
, O_NONBLOCK
);
1779 n
= recvmsg(b
->num
, &msg
, MSG_PEEK
);
1780 fcntl(b
->num
, F_SETFL
, sockflags
);
1782 /* if notification, process and try again */
1783 if (n
> 0 && (msg
.msg_flags
& MSG_NOTIFICATION
))
1785 #ifdef SCTP_AUTHENTICATION_EVENT
1786 if (snp
.sn_header
.sn_type
== SCTP_AUTHENTICATION_EVENT
)
1787 dgram_sctp_handle_auth_free_key_event(b
, &snp
);
1790 memset(&snp
, 0x00, sizeof(union sctp_notification
));
1791 iov
.iov_base
= (char *)&snp
;
1792 iov
.iov_len
= sizeof(union sctp_notification
);
1793 msg
.msg_name
= NULL
;
1794 msg
.msg_namelen
= 0;
1797 msg
.msg_control
= NULL
;
1798 msg
.msg_controllen
= 0;
1800 n
= recvmsg(b
->num
, &msg
, 0);
1802 if (data
->handle_notifications
!= NULL
)
1803 data
->handle_notifications(b
, data
->notification_context
, (void*) &snp
);
1806 } while (n
> 0 && (msg
.msg_flags
& MSG_NOTIFICATION
));
1808 /* Return 1 if there is a message to be read, return 0 otherwise. */
1815 static int dgram_sctp_puts(BIO
*bp
, const char *str
)
1820 ret
=dgram_sctp_write(bp
,str
,n
);
1825 static int BIO_dgram_should_retry(int i
)
1829 if ((i
== 0) || (i
== -1))
1831 err
=get_last_socket_error();
1833 #if defined(OPENSSL_SYS_WINDOWS)
1834 /* If the socket return value (i) is -1
1835 * and err is unexpectedly 0 at this point,
1836 * the error code was overwritten by
1837 * another system call before this error
1838 * handling is called.
1842 return(BIO_dgram_non_fatal_error(err
));
1847 int BIO_dgram_non_fatal_error(int err
)
1851 #if defined(OPENSSL_SYS_WINDOWS)
1852 # if defined(WSAEWOULDBLOCK)
1853 case WSAEWOULDBLOCK
:
1856 # if 0 /* This appears to always be an error */
1857 # if defined(WSAENOTCONN)
1864 # ifdef WSAEWOULDBLOCK
1865 # if WSAEWOULDBLOCK != EWOULDBLOCK
1878 #if EWOULDBLOCK != EAGAIN
1903 static void get_current_time(struct timeval
*t
)
1907 union { unsigned __int64 ul
; FILETIME ft
; } now
;
1910 SystemTimeToFileTime(&st
,&now
.ft
);
1912 now
.ul
-= 116444736000000000ULL;
1914 now
.ul
-= 116444736000000000UI
64; /* re-bias to 1/1/1970 */
1916 t
->tv_sec
= (long)(now
.ul
/10000000);
1917 t
->tv_usec
= ((int)(now
.ul
%10000000))/10;
1918 #elif defined(OPENSSL_SYS_VMS)
1921 t
->tv_sec
= (long)tb
.time
;
1922 t
->tv_usec
= (long)tb
.millitm
* 1000;
1924 gettimeofday(t
, NULL
);