OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
bss_dgram.c
Go to the documentation of this file.
1 /* crypto/bio/bio_dgram.c */
2 /*
3  * DTLS implementation written by Nagendra Modadugu
4  * ([email protected]) 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
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  * ([email protected]). This product includes software written by Tim
56  * Hudson ([email protected]).
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  {
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  {
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
162  {
164  char *data;
165  int length;
167 
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;
183  void (*handle_notifications)(BIO *bio, void *context, void *buf);
186  int ccs_rcvd;
187  int ccs_sent;
192 #endif
193 
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  {
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  {
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 
385  if (ret < 0)
386  {
387  if (BIO_dgram_should_retry(ret))
388  {
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;
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 
425  if (ret <= 0)
426  {
427  if (BIO_dgram_should_retry(ret))
428  {
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;
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 */
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
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;
620  switch (data->peer.sa.sa_family)
621  {
622  case AF_INET:
623  ret = 576 - 20 - 8;
624  break;
625 #if OPENSSL_USE_IPV6
626  case AF_INET6:
627 #ifdef IN6_IS_ADDR_V4MAPPED
628  if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
629  ret = 576 - 20 - 8;
630  else
631 #endif
632  ret = 1280 - 40 - 8;
633  break;
634 #endif
635  default:
636  ret = 576 - 20 - 8;
637  break;
638  }
639  break;
641  return data->mtu;
642  break;
644  data->mtu = num;
645  ret = num;
646  break;
648  to = (struct sockaddr *)ptr;
649 
650  if ( to != NULL)
651  {
652  data->connected = 1;
653  switch (to->sa_family)
654  {
655  case AF_INET:
656  memcpy(&data->peer,to,sizeof(data->peer.sa_in));
657  break;
658 #if OPENSSL_USE_IPV6
659  case AF_INET6:
660  memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
661  break;
662 #endif
663  default:
664  memcpy(&data->peer,to,sizeof(data->peer.sa));
665  break;
666  }
667  }
668  else
669  {
670  data->connected = 0;
671  memset(&(data->peer), 0x00, sizeof(data->peer));
672  }
673  break;
675  switch (data->peer.sa.sa_family)
676  {
677  case AF_INET:
678  ret=sizeof(data->peer.sa_in);
679  break;
680 #if OPENSSL_USE_IPV6
681  case AF_INET6:
682  ret=sizeof(data->peer.sa_in6);
683  break;
684 #endif
685  default:
686  ret=sizeof(data->peer.sa);
687  break;
688  }
689  if (num==0 || num>ret)
690  num=ret;
691  memcpy(ptr,&data->peer,(ret=num));
692  break;
694  to = (struct sockaddr *) ptr;
695  switch (to->sa_family)
696  {
697  case AF_INET:
698  memcpy(&data->peer,to,sizeof(data->peer.sa_in));
699  break;
700 #if OPENSSL_USE_IPV6
701  case AF_INET6:
702  memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
703  break;
704 #endif
705  default:
706  memcpy(&data->peer,to,sizeof(data->peer.sa));
707  break;
708  }
709  break;
711  memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
712  break;
713 #if defined(SO_RCVTIMEO)
715 #ifdef OPENSSL_SYS_WINDOWS
716  {
717  struct timeval *tv = (struct timeval *)ptr;
718  int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
719  if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
720  (void*)&timeout, sizeof(timeout)) < 0)
721  { perror("setsockopt"); ret = -1; }
722  }
723 #else
724  if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
725  sizeof(struct timeval)) < 0)
726  { perror("setsockopt"); ret = -1; }
727 #endif
728  break;
730 #ifdef OPENSSL_SYS_WINDOWS
731  {
732  int timeout, sz = sizeof(timeout);
733  struct timeval *tv = (struct timeval *)ptr;
734  if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
735  (void*)&timeout, &sz) < 0)
736  { perror("getsockopt"); ret = -1; }
737  else
738  {
739  tv->tv_sec = timeout / 1000;
740  tv->tv_usec = (timeout % 1000) * 1000;
741  ret = sizeof(*tv);
742  }
743  }
744 #else
745  if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
746  ptr, (void *)&ret) < 0)
747  { perror("getsockopt"); ret = -1; }
748 #endif
749  break;
750 #endif
751 #if defined(SO_SNDTIMEO)
753 #ifdef OPENSSL_SYS_WINDOWS
754  {
755  struct timeval *tv = (struct timeval *)ptr;
756  int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
757  if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
758  (void*)&timeout, sizeof(timeout)) < 0)
759  { perror("setsockopt"); ret = -1; }
760  }
761 #else
762  if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
763  sizeof(struct timeval)) < 0)
764  { perror("setsockopt"); ret = -1; }
765 #endif
766  break;
768 #ifdef OPENSSL_SYS_WINDOWS
769  {
770  int timeout, sz = sizeof(timeout);
771  struct timeval *tv = (struct timeval *)ptr;
772  if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
773  (void*)&timeout, &sz) < 0)
774  { perror("getsockopt"); ret = -1; }
775  else
776  {
777  tv->tv_sec = timeout / 1000;
778  tv->tv_usec = (timeout % 1000) * 1000;
779  ret = sizeof(*tv);
780  }
781  }
782 #else
783  if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
784  ptr, (void *)&ret) < 0)
785  { perror("getsockopt"); ret = -1; }
786 #endif
787  break;
788 #endif
790  /* fall-through */
792 #ifdef OPENSSL_SYS_WINDOWS
793  if ( data->_errno == WSAETIMEDOUT)
794 #else
795  if ( data->_errno == EAGAIN)
796 #endif
797  {
798  ret = 1;
799  data->_errno = 0;
800  }
801  else
802  ret = 0;
803  break;
804 #ifdef EMSGSIZE
806  if ( data->_errno == EMSGSIZE)
807  {
808  ret = 1;
809  data->_errno = 0;
810  }
811  else
812  ret = 0;
813  break;
814 #endif
815  default:
816  ret=0;
817  break;
818  }
819  return(ret);
820  }
821 
822 static int dgram_puts(BIO *bp, const char *str)
823  {
824  int n,ret;
825 
826  n=strlen(str);
827  ret=dgram_write(bp,str,n);
828  return(ret);
829  }
830 
831 #ifndef OPENSSL_NO_SCTP
833  {
834  return(&methods_dgramp_sctp);
835  }
836 
837 BIO *BIO_new_dgram_sctp(int fd, int close_flag)
838  {
839  BIO *bio;
840  int ret, optval = 20000;
841  int auth_data = 0, auth_forward = 0;
842  unsigned char *p;
843  struct sctp_authchunk auth;
844  struct sctp_authchunks *authchunks;
845  socklen_t sockopt_len;
846 #ifdef SCTP_AUTHENTICATION_EVENT
847 #ifdef SCTP_EVENT
848  struct sctp_event event;
849 #else
850  struct sctp_event_subscribe event;
851 #endif
852 #endif
853 
855  if (bio == NULL) return(NULL);
856  BIO_set_fd(bio,fd,close_flag);
857 
858  /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
859  auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
860  ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
861  OPENSSL_assert(ret >= 0);
862  auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
863  ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
864  OPENSSL_assert(ret >= 0);
865 
866  /* Test if activation was successful. When using accept(),
867  * SCTP-AUTH has to be activated for the listening socket
868  * already, otherwise the connected socket won't use it. */
869  sockopt_len = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
870  authchunks = OPENSSL_malloc(sockopt_len);
871  memset(authchunks, 0, sizeof(sockopt_len));
872  ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len);
873  OPENSSL_assert(ret >= 0);
874 
875  for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t);
876  p < (unsigned char*) authchunks + sockopt_len;
877  p += sizeof(uint8_t))
878  {
879  if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
880  if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
881  }
882 
883  OPENSSL_free(authchunks);
884 
885  OPENSSL_assert(auth_data);
886  OPENSSL_assert(auth_forward);
887 
888 #ifdef SCTP_AUTHENTICATION_EVENT
889 #ifdef SCTP_EVENT
890  memset(&event, 0, sizeof(struct sctp_event));
891  event.se_assoc_id = 0;
892  event.se_type = SCTP_AUTHENTICATION_EVENT;
893  event.se_on = 1;
894  ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
895  OPENSSL_assert(ret >= 0);
896 #else
897  sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
898  ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
899  OPENSSL_assert(ret >= 0);
900 
901  event.sctp_authentication_event = 1;
902 
903  ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
904  OPENSSL_assert(ret >= 0);
905 #endif
906 #endif
907 
908  /* Disable partial delivery by setting the min size
909  * larger than the max record size of 2^14 + 2048 + 13
910  */
911  ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval));
912  OPENSSL_assert(ret >= 0);
913 
914  return(bio);
915  }
916 
918  {
919  return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
920  }
921 
922 static int dgram_sctp_new(BIO *bi)
923  {
924  bio_dgram_sctp_data *data = NULL;
925 
926  bi->init=0;
927  bi->num=0;
928  data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data));
929  if (data == NULL)
930  return 0;
931  memset(data, 0x00, sizeof(bio_dgram_sctp_data));
932 #ifdef SCTP_PR_SCTP_NONE
933  data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
934 #endif
935  bi->ptr = data;
936 
937  bi->flags=0;
938  return(1);
939  }
940 
941 static int dgram_sctp_free(BIO *a)
942  {
944 
945  if (a == NULL) return(0);
946  if ( ! dgram_clear(a))
947  return 0;
948 
949  data = (bio_dgram_sctp_data *)a->ptr;
950  if(data != NULL) OPENSSL_free(data);
951 
952  return(1);
953  }
954 
955 #ifdef SCTP_AUTHENTICATION_EVENT
956 void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
957  {
958  unsigned int sockopt_len = 0;
959  int ret;
960  struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
961 
962  if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY)
963  {
964  struct sctp_authkeyid authkeyid;
965 
966  /* delete key */
967  authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
968  sockopt_len = sizeof(struct sctp_authkeyid);
969  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
970  &authkeyid, sockopt_len);
971  }
972  }
973 #endif
974 
975 static int dgram_sctp_read(BIO *b, char *out, int outl)
976  {
977  int ret = 0, n = 0, i, optval;
978  socklen_t optlen;
980  union sctp_notification *snp;
981  struct msghdr msg;
982  struct iovec iov;
983  struct cmsghdr *cmsg;
984  char cmsgbuf[512];
985 
986  if (out != NULL)
987  {
989 
990  do
991  {
992  memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo));
993  iov.iov_base = out;
994  iov.iov_len = outl;
995  msg.msg_name = NULL;
996  msg.msg_namelen = 0;
997  msg.msg_iov = &iov;
998  msg.msg_iovlen = 1;
999  msg.msg_control = cmsgbuf;
1000  msg.msg_controllen = 512;
1001  msg.msg_flags = 0;
1002  n = recvmsg(b->num, &msg, 0);
1003 
1004  if (msg.msg_controllen > 0)
1005  {
1006  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
1007  {
1008  if (cmsg->cmsg_level != IPPROTO_SCTP)
1009  continue;
1010 #ifdef SCTP_RCVINFO
1011  if (cmsg->cmsg_type == SCTP_RCVINFO)
1012  {
1013  struct sctp_rcvinfo *rcvinfo;
1014 
1015  rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
1016  data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
1017  data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
1018  data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
1019  data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
1020  data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
1021  data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
1022  data->rcvinfo.rcv_context = rcvinfo->rcv_context;
1023  }
1024 #endif
1025 #ifdef SCTP_SNDRCV
1026  if (cmsg->cmsg_type == SCTP_SNDRCV)
1027  {
1028  struct sctp_sndrcvinfo *sndrcvinfo;
1029 
1030  sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1031  data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
1032  data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
1033  data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
1034  data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
1035  data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
1036  data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
1037  data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
1038  }
1039 #endif
1040  }
1041  }
1042 
1043  if (n <= 0)
1044  {
1045  if (n < 0)
1046  ret = n;
1047  break;
1048  }
1049 
1050  if (msg.msg_flags & MSG_NOTIFICATION)
1051  {
1052  snp = (union sctp_notification*) out;
1053  if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
1054  {
1055 #ifdef SCTP_EVENT
1056  struct sctp_event event;
1057 #else
1058  struct sctp_event_subscribe event;
1059  socklen_t eventsize;
1060 #endif
1061  /* If a message has been delayed until the socket
1062  * is dry, it can be sent now.
1063  */
1064  if (data->saved_message.length > 0)
1065  {
1066  dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
1067  data->saved_message.length);
1069  data->saved_message.length = 0;
1070  }
1071 
1072  /* disable sender dry event */
1073 #ifdef SCTP_EVENT
1074  memset(&event, 0, sizeof(struct sctp_event));
1075  event.se_assoc_id = 0;
1076  event.se_type = SCTP_SENDER_DRY_EVENT;
1077  event.se_on = 0;
1078  i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1079  OPENSSL_assert(i >= 0);
1080 #else
1081  eventsize = sizeof(struct sctp_event_subscribe);
1082  i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1083  OPENSSL_assert(i >= 0);
1084 
1085  event.sctp_sender_dry_event = 0;
1086 
1087  i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1088  OPENSSL_assert(i >= 0);
1089 #endif
1090  }
1091 
1092 #ifdef SCTP_AUTHENTICATION_EVENT
1093  if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1094  dgram_sctp_handle_auth_free_key_event(b, snp);
1095 #endif
1096 
1097  if (data->handle_notifications != NULL)
1098  data->handle_notifications(b, data->notification_context, (void*) out);
1099 
1100  memset(out, 0, outl);
1101  }
1102  else
1103  ret += n;
1104  }
1105  while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl));
1106 
1107  if (ret > 0 && !(msg.msg_flags & MSG_EOR))
1108  {
1109  /* Partial message read, this should never happen! */
1110 
1111  /* The buffer was too small, this means the peer sent
1112  * a message that was larger than allowed. */
1113  if (ret == outl)
1114  return -1;
1115 
1116  /* Test if socket buffer can handle max record
1117  * size (2^14 + 2048 + 13)
1118  */
1119  optlen = (socklen_t) sizeof(int);
1120  ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
1121  OPENSSL_assert(ret >= 0);
1122  OPENSSL_assert(optval >= 18445);
1123 
1124  /* Test if SCTP doesn't partially deliver below
1125  * max record size (2^14 + 2048 + 13)
1126  */
1127  optlen = (socklen_t) sizeof(int);
1128  ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
1129  &optval, &optlen);
1130  OPENSSL_assert(ret >= 0);
1131  OPENSSL_assert(optval >= 18445);
1132 
1133  /* Partially delivered notification??? Probably a bug.... */
1134  OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
1135 
1136  /* Everything seems ok till now, so it's most likely
1137  * a message dropped by PR-SCTP.
1138  */
1139  memset(out, 0, outl);
1140  BIO_set_retry_read(b);
1141  return -1;
1142  }
1143 
1145  if (ret < 0)
1146  {
1147  if (BIO_dgram_should_retry(ret))
1148  {
1149  BIO_set_retry_read(b);
1150  data->_errno = get_last_socket_error();
1151  }
1152  }
1153 
1154  /* Test if peer uses SCTP-AUTH before continuing */
1155  if (!data->peer_auth_tested)
1156  {
1157  int ii, auth_data = 0, auth_forward = 0;
1158  unsigned char *p;
1159  struct sctp_authchunks *authchunks;
1160 
1161  optlen = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
1162  authchunks = OPENSSL_malloc(optlen);
1163  memset(authchunks, 0, sizeof(optlen));
1164  ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen);
1165  OPENSSL_assert(ii >= 0);
1166 
1167  for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t);
1168  p < (unsigned char*) authchunks + optlen;
1169  p += sizeof(uint8_t))
1170  {
1171  if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
1172  if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
1173  }
1174 
1175  OPENSSL_free(authchunks);
1176 
1177  if (!auth_data || !auth_forward)
1178  {
1180  return -1;
1181  }
1182 
1183  data->peer_auth_tested = 1;
1184  }
1185  }
1186  return(ret);
1187  }
1188 
1189 static int dgram_sctp_write(BIO *b, const char *in, int inl)
1190  {
1191  int ret;
1193  struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
1194  struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
1195  struct bio_dgram_sctp_sndinfo handshake_sinfo;
1196  struct iovec iov[1];
1197  struct msghdr msg;
1198  struct cmsghdr *cmsg;
1199 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1200  char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))];
1201  struct sctp_sndinfo *sndinfo;
1202  struct sctp_prinfo *prinfo;
1203 #else
1204  char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
1205  struct sctp_sndrcvinfo *sndrcvinfo;
1206 #endif
1207 
1209 
1210  /* If we're send anything else than application data,
1211  * disable all user parameters and flags.
1212  */
1213  if (in[0] != 23) {
1214  memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo));
1215 #ifdef SCTP_SACK_IMMEDIATELY
1216  handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
1217 #endif
1218  sinfo = &handshake_sinfo;
1219  }
1220 
1221  /* If we have to send a shutdown alert message and the
1222  * socket is not dry yet, we have to save it and send it
1223  * as soon as the socket gets dry.
1224  */
1225  if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
1226  {
1227  data->saved_message.bio = b;
1228  data->saved_message.length = inl;
1229  data->saved_message.data = OPENSSL_malloc(inl);
1230  memcpy(data->saved_message.data, in, inl);
1231  return inl;
1232  }
1233 
1234  iov[0].iov_base = (char *)in;
1235  iov[0].iov_len = inl;
1236  msg.msg_name = NULL;
1237  msg.msg_namelen = 0;
1238  msg.msg_iov = iov;
1239  msg.msg_iovlen = 1;
1240  msg.msg_control = (caddr_t)cmsgbuf;
1241  msg.msg_controllen = 0;
1242  msg.msg_flags = 0;
1243 #if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
1244  cmsg = (struct cmsghdr *)cmsgbuf;
1245  cmsg->cmsg_level = IPPROTO_SCTP;
1246  cmsg->cmsg_type = SCTP_SNDINFO;
1247  cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
1248  sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
1249  memset(sndinfo, 0, sizeof(struct sctp_sndinfo));
1250  sndinfo->snd_sid = sinfo->snd_sid;
1251  sndinfo->snd_flags = sinfo->snd_flags;
1252  sndinfo->snd_ppid = sinfo->snd_ppid;
1253  sndinfo->snd_context = sinfo->snd_context;
1254  msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
1255 
1256  cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
1257  cmsg->cmsg_level = IPPROTO_SCTP;
1258  cmsg->cmsg_type = SCTP_PRINFO;
1259  cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
1260  prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
1261  memset(prinfo, 0, sizeof(struct sctp_prinfo));
1262  prinfo->pr_policy = pinfo->pr_policy;
1263  prinfo->pr_value = pinfo->pr_value;
1264  msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
1265 #else
1266  cmsg = (struct cmsghdr *)cmsgbuf;
1267  cmsg->cmsg_level = IPPROTO_SCTP;
1268  cmsg->cmsg_type = SCTP_SNDRCV;
1269  cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
1270  sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
1271  memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
1272  sndrcvinfo->sinfo_stream = sinfo->snd_sid;
1273  sndrcvinfo->sinfo_flags = sinfo->snd_flags;
1274 #ifdef __FreeBSD__
1275  sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
1276 #endif
1277  sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
1278  sndrcvinfo->sinfo_context = sinfo->snd_context;
1279  sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
1280  msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
1281 #endif
1282 
1283  ret = sendmsg(b->num, &msg, 0);
1284 
1286  if (ret <= 0)
1287  {
1288  if (BIO_dgram_should_retry(ret))
1289  {
1290  BIO_set_retry_write(b);
1291  data->_errno = get_last_socket_error();
1292  }
1293  }
1294  return(ret);
1295  }
1296 
1297 static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1298  {
1299  long ret=1;
1300  bio_dgram_sctp_data *data = NULL;
1301  unsigned int sockopt_len = 0;
1302  struct sctp_authkeyid authkeyid;
1303  struct sctp_authkey *authkey;
1304 
1305  data = (bio_dgram_sctp_data *)b->ptr;
1306 
1307  switch (cmd)
1308  {
1310  /* Set to maximum (2^14)
1311  * and ignore user input to enable transport
1312  * protocol fragmentation.
1313  * Returns always 2^14.
1314  */
1315  data->mtu = 16384;
1316  ret = data->mtu;
1317  break;
1319  /* Set to maximum (2^14)
1320  * and ignore input to enable transport
1321  * protocol fragmentation.
1322  * Returns always 2^14.
1323  */
1324  data->mtu = 16384;
1325  ret = data->mtu;
1326  break;
1329  /* Returns always -1. */
1330  ret = -1;
1331  break;
1333  /* SCTP doesn't need the DTLS timer
1334  * Returns always 1.
1335  */
1336  break;
1338  if (num > 0)
1339  data->in_handshake = 1;
1340  else
1341  data->in_handshake = 0;
1342 
1343  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, &data->in_handshake, sizeof(int));
1344  break;
1346  /* New shared key for SCTP AUTH.
1347  * Returns 0 on success, -1 otherwise.
1348  */
1349 
1350  /* Get active key */
1351  sockopt_len = sizeof(struct sctp_authkeyid);
1352  ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1353  if (ret < 0) break;
1354 
1355  /* Add new key */
1356  sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
1357  authkey = OPENSSL_malloc(sockopt_len);
1358  memset(authkey, 0x00, sockopt_len);
1359  authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
1360 #ifndef __FreeBSD__
1361  /* This field is missing in FreeBSD 8.2 and earlier,
1362  * and FreeBSD 8.3 and higher work without it.
1363  */
1364  authkey->sca_keylength = 64;
1365 #endif
1366  memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
1367 
1368  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len);
1369  if (ret < 0) break;
1370 
1371  /* Reset active key */
1372  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1373  &authkeyid, sizeof(struct sctp_authkeyid));
1374  if (ret < 0) break;
1375 
1376  break;
1378  /* Returns 0 on success, -1 otherwise. */
1379 
1380  /* Get active key */
1381  sockopt_len = sizeof(struct sctp_authkeyid);
1382  ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1383  if (ret < 0) break;
1384 
1385  /* Set active key */
1386  authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
1387  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1388  &authkeyid, sizeof(struct sctp_authkeyid));
1389  if (ret < 0) break;
1390 
1391  /* CCS has been sent, so remember that and fall through
1392  * to check if we need to deactivate an old key
1393  */
1394  data->ccs_sent = 1;
1395 
1397  /* Returns 0 on success, -1 otherwise. */
1398 
1399  /* Has this command really been called or is this just a fall-through? */
1401  data->ccs_rcvd = 1;
1402 
1403  /* CSS has been both, received and sent, so deactivate an old key */
1404  if (data->ccs_rcvd == 1 && data->ccs_sent == 1)
1405  {
1406  /* Get active key */
1407  sockopt_len = sizeof(struct sctp_authkeyid);
1408  ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1409  if (ret < 0) break;
1410 
1411  /* Deactivate key or delete second last key if
1412  * SCTP_AUTHENTICATION_EVENT is not available.
1413  */
1414  authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1415 #ifdef SCTP_AUTH_DEACTIVATE_KEY
1416  sockopt_len = sizeof(struct sctp_authkeyid);
1417  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
1418  &authkeyid, sockopt_len);
1419  if (ret < 0) break;
1420 #endif
1421 #ifndef SCTP_AUTHENTICATION_EVENT
1422  if (authkeyid.scact_keynumber > 0)
1423  {
1424  authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1425  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1426  &authkeyid, sizeof(struct sctp_authkeyid));
1427  if (ret < 0) break;
1428  }
1429 #endif
1430 
1431  data->ccs_rcvd = 0;
1432  data->ccs_sent = 0;
1433  }
1434  break;
1436  /* Returns the size of the copied struct. */
1437  if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
1438  num = sizeof(struct bio_dgram_sctp_sndinfo);
1439 
1440  memcpy(ptr, &(data->sndinfo), num);
1441  ret = num;
1442  break;
1444  /* Returns the size of the copied struct. */
1445  if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo))
1446  num = sizeof(struct bio_dgram_sctp_sndinfo);
1447 
1448  memcpy(&(data->sndinfo), ptr, num);
1449  break;
1451  /* Returns the size of the copied struct. */
1452  if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
1453  num = sizeof(struct bio_dgram_sctp_rcvinfo);
1454 
1455  memcpy(ptr, &data->rcvinfo, num);
1456 
1457  ret = num;
1458  break;
1460  /* Returns the size of the copied struct. */
1461  if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo))
1462  num = sizeof(struct bio_dgram_sctp_rcvinfo);
1463 
1464  memcpy(&(data->rcvinfo), ptr, num);
1465  break;
1467  /* Returns the size of the copied struct. */
1468  if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
1469  num = sizeof(struct bio_dgram_sctp_prinfo);
1470 
1471  memcpy(ptr, &(data->prinfo), num);
1472  ret = num;
1473  break;
1475  /* Returns the size of the copied struct. */
1476  if (num > (long) sizeof(struct bio_dgram_sctp_prinfo))
1477  num = sizeof(struct bio_dgram_sctp_prinfo);
1478 
1479  memcpy(&(data->prinfo), ptr, num);
1480  break;
1482  /* Returns always 1. */
1483  if (num > 0)
1484  data->save_shutdown = 1;
1485  else
1486  data->save_shutdown = 0;
1487  break;
1488 
1489  default:
1490  /* Pass to default ctrl function to
1491  * process SCTP unspecific commands
1492  */
1493  ret=dgram_ctrl(b, cmd, num, ptr);
1494  break;
1495  }
1496  return(ret);
1497  }
1498 
1500  void (*handle_notifications)(BIO *bio, void *context, void *buf),
1501  void *context)
1502  {
1504 
1505  if (handle_notifications != NULL)
1506  {
1507  data->handle_notifications = handle_notifications;
1508  data->notification_context = context;
1509  }
1510  else
1511  return -1;
1512 
1513  return 0;
1514  }
1515 
1517 {
1518  int is_dry = 0;
1519  int n, sockflags, ret;
1520  union sctp_notification snp;
1521  struct msghdr msg;
1522  struct iovec iov;
1523 #ifdef SCTP_EVENT
1524  struct sctp_event event;
1525 #else
1526  struct sctp_event_subscribe event;
1527  socklen_t eventsize;
1528 #endif
1530 
1531  /* set sender dry event */
1532 #ifdef SCTP_EVENT
1533  memset(&event, 0, sizeof(struct sctp_event));
1534  event.se_assoc_id = 0;
1535  event.se_type = SCTP_SENDER_DRY_EVENT;
1536  event.se_on = 1;
1537  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1538 #else
1539  eventsize = sizeof(struct sctp_event_subscribe);
1540  ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1541  if (ret < 0)
1542  return -1;
1543 
1544  event.sctp_sender_dry_event = 1;
1545 
1546  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1547 #endif
1548  if (ret < 0)
1549  return -1;
1550 
1551  /* peek for notification */
1552  memset(&snp, 0x00, sizeof(union sctp_notification));
1553  iov.iov_base = (char *)&snp;
1554  iov.iov_len = sizeof(union sctp_notification);
1555  msg.msg_name = NULL;
1556  msg.msg_namelen = 0;
1557  msg.msg_iov = &iov;
1558  msg.msg_iovlen = 1;
1559  msg.msg_control = NULL;
1560  msg.msg_controllen = 0;
1561  msg.msg_flags = 0;
1562 
1563  n = recvmsg(b->num, &msg, MSG_PEEK);
1564  if (n <= 0)
1565  {
1566  if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1567  return -1;
1568  else
1569  return 0;
1570  }
1571 
1572  /* if we find a notification, process it and try again if necessary */
1573  while (msg.msg_flags & MSG_NOTIFICATION)
1574  {
1575  memset(&snp, 0x00, sizeof(union sctp_notification));
1576  iov.iov_base = (char *)&snp;
1577  iov.iov_len = sizeof(union sctp_notification);
1578  msg.msg_name = NULL;
1579  msg.msg_namelen = 0;
1580  msg.msg_iov = &iov;
1581  msg.msg_iovlen = 1;
1582  msg.msg_control = NULL;
1583  msg.msg_controllen = 0;
1584  msg.msg_flags = 0;
1585 
1586  n = recvmsg(b->num, &msg, 0);
1587  if (n <= 0)
1588  {
1589  if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1590  return -1;
1591  else
1592  return is_dry;
1593  }
1594 
1595  if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT)
1596  {
1597  is_dry = 1;
1598 
1599  /* disable sender dry event */
1600 #ifdef SCTP_EVENT
1601  memset(&event, 0, sizeof(struct sctp_event));
1602  event.se_assoc_id = 0;
1603  event.se_type = SCTP_SENDER_DRY_EVENT;
1604  event.se_on = 0;
1605  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
1606 #else
1607  eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
1608  ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1609  if (ret < 0)
1610  return -1;
1611 
1612  event.sctp_sender_dry_event = 0;
1613 
1614  ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1615 #endif
1616  if (ret < 0)
1617  return -1;
1618  }
1619 
1620 #ifdef SCTP_AUTHENTICATION_EVENT
1621  if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1622  dgram_sctp_handle_auth_free_key_event(b, &snp);
1623 #endif
1624 
1625  if (data->handle_notifications != NULL)
1626  data->handle_notifications(b, data->notification_context, (void*) &snp);
1627 
1628  /* found notification, peek again */
1629  memset(&snp, 0x00, sizeof(union sctp_notification));
1630  iov.iov_base = (char *)&snp;
1631  iov.iov_len = sizeof(union sctp_notification);
1632  msg.msg_name = NULL;
1633  msg.msg_namelen = 0;
1634  msg.msg_iov = &iov;
1635  msg.msg_iovlen = 1;
1636  msg.msg_control = NULL;
1637  msg.msg_controllen = 0;
1638  msg.msg_flags = 0;
1639 
1640  /* if we have seen the dry already, don't wait */
1641  if (is_dry)
1642  {
1643  sockflags = fcntl(b->num, F_GETFL, 0);
1644  fcntl(b->num, F_SETFL, O_NONBLOCK);
1645  }
1646 
1647  n = recvmsg(b->num, &msg, MSG_PEEK);
1648 
1649  if (is_dry)
1650  {
1651  fcntl(b->num, F_SETFL, sockflags);
1652  }
1653 
1654  if (n <= 0)
1655  {
1656  if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK))
1657  return -1;
1658  else
1659  return is_dry;
1660  }
1661  }
1662 
1663  /* read anything else */
1664  return is_dry;
1665 }
1666 
1668  {
1669  int n, sockflags;
1670  union sctp_notification snp;
1671  struct msghdr msg;
1672  struct iovec iov;
1674 
1675  /* Check if there are any messages waiting to be read */
1676  do
1677  {
1678  memset(&snp, 0x00, sizeof(union sctp_notification));
1679  iov.iov_base = (char *)&snp;
1680  iov.iov_len = sizeof(union sctp_notification);
1681  msg.msg_name = NULL;
1682  msg.msg_namelen = 0;
1683  msg.msg_iov = &iov;
1684  msg.msg_iovlen = 1;
1685  msg.msg_control = NULL;
1686  msg.msg_controllen = 0;
1687  msg.msg_flags = 0;
1688 
1689  sockflags = fcntl(b->num, F_GETFL, 0);
1690  fcntl(b->num, F_SETFL, O_NONBLOCK);
1691  n = recvmsg(b->num, &msg, MSG_PEEK);
1692  fcntl(b->num, F_SETFL, sockflags);
1693 
1694  /* if notification, process and try again */
1695  if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION))
1696  {
1697 #ifdef SCTP_AUTHENTICATION_EVENT
1698  if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1699  dgram_sctp_handle_auth_free_key_event(b, &snp);
1700 #endif
1701 
1702  memset(&snp, 0x00, sizeof(union sctp_notification));
1703  iov.iov_base = (char *)&snp;
1704  iov.iov_len = sizeof(union sctp_notification);
1705  msg.msg_name = NULL;
1706  msg.msg_namelen = 0;
1707  msg.msg_iov = &iov;
1708  msg.msg_iovlen = 1;
1709  msg.msg_control = NULL;
1710  msg.msg_controllen = 0;
1711  msg.msg_flags = 0;
1712  n = recvmsg(b->num, &msg, 0);
1713 
1714  if (data->handle_notifications != NULL)
1715  data->handle_notifications(b, data->notification_context, (void*) &snp);
1716  }
1717 
1718  } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
1719 
1720  /* Return 1 if there is a message to be read, return 0 otherwise. */
1721  if (n > 0)
1722  return 1;
1723  else
1724  return 0;
1725  }
1726 
1727 static int dgram_sctp_puts(BIO *bp, const char *str)
1728  {
1729  int n,ret;
1730 
1731  n=strlen(str);
1732  ret=dgram_sctp_write(bp,str,n);
1733  return(ret);
1734  }
1735 #endif
1736 
1737 static int BIO_dgram_should_retry(int i)
1738  {
1739  int err;
1740 
1741  if ((i == 0) || (i == -1))
1742  {
1743  err=get_last_socket_error();
1744 
1745 #if defined(OPENSSL_SYS_WINDOWS)
1746  /* If the socket return value (i) is -1
1747  * and err is unexpectedly 0 at this point,
1748  * the error code was overwritten by
1749  * another system call before this error
1750  * handling is called.
1751  */
1752 #endif
1753 
1754  return(BIO_dgram_non_fatal_error(err));
1755  }
1756  return(0);
1757  }
1758 
1760  {
1761  switch (err)
1762  {
1763 #if defined(OPENSSL_SYS_WINDOWS)
1764 # if defined(WSAEWOULDBLOCK)
1765  case WSAEWOULDBLOCK:
1766 # endif
1767 
1768 # if 0 /* This appears to always be an error */
1769 # if defined(WSAENOTCONN)
1770  case WSAENOTCONN:
1771 # endif
1772 # endif
1773 #endif
1774 
1775 #ifdef EWOULDBLOCK
1776 # ifdef WSAEWOULDBLOCK
1777 # if WSAEWOULDBLOCK != EWOULDBLOCK
1778  case EWOULDBLOCK:
1779 # endif
1780 # else
1781  case EWOULDBLOCK:
1782 # endif
1783 #endif
1784 
1785 #ifdef EINTR
1786  case EINTR:
1787 #endif
1788 
1789 #ifdef EAGAIN
1790 #if EWOULDBLOCK != EAGAIN
1791  case EAGAIN:
1792 # endif
1793 #endif
1794 
1795 #ifdef EPROTO
1796  case EPROTO:
1797 #endif
1798 
1799 #ifdef EINPROGRESS
1800  case EINPROGRESS:
1801 #endif
1802 
1803 #ifdef EALREADY
1804  case EALREADY:
1805 #endif
1806 
1807  return(1);
1808  /* break; */
1809  default:
1810  break;
1811  }
1812  return(0);
1813  }
1814 
1815 static void get_current_time(struct timeval *t)
1816  {
1817 #ifdef OPENSSL_SYS_WIN32
1818  struct _timeb tb;
1819  _ftime(&tb);
1820  t->tv_sec = (long)tb.time;
1821  t->tv_usec = (long)tb.millitm * 1000;
1822 #elif defined(OPENSSL_SYS_VMS)
1823  struct timeb tb;
1824  ftime(&tb);
1825  t->tv_sec = (long)tb.time;
1826  t->tv_usec = (long)tb.millitm * 1000;
1827 #else
1828  gettimeofday(t, NULL);
1829 #endif
1830  }
1831 
1832 #endif