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