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