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