1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* crypto/bio/bio_dgram.c */ 2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* 3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * DTLS implementation written by Nagendra Modadugu 4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ==================================================================== 7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without 10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions 11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met: 12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright 14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer. 15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer in 18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the documentation and/or other materials provided with the 19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * distribution. 20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this 22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * software must display the following acknowledgment: 23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * endorse or promote products derived from this software without 28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * prior written permission. For written permission, please contact 29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * openssl-core@OpenSSL.org. 30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL" 32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * nor may "OpenSSL" appear in their names without prior written 33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * permission of the OpenSSL Project. 34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following 36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * acknowledgment: 37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE. 52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ==================================================================== 53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young 55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com). This product includes software written by Tim 56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com). 57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h> 62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <errno.h> 63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define USE_SOCKETS 64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h" 65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/bio.h> 67480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#ifndef OPENSSL_NO_DGRAM 68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 69c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) 70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <sys/timeb.h> 71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef OPENSSL_NO_SCTP 742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#include <netinet/sctp.h> 752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#include <fcntl.h> 762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00 772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0 782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 807453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU) 81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define IP_MTU 14 /* linux is lame */ 82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 83c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 847453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED) 857453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org/* Standard definition causes type-punning problems. */ 867453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#undef IN6_IS_ADDR_V4MAPPED 877453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#define s6_addr32 __u6_addr.__u6_addr32 887453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#define IN6_IS_ADDR_V4MAPPED(a) \ 897453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org (((a)->s6_addr32[0] == 0) && \ 907453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ((a)->s6_addr32[1] == 0) && \ 917453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ((a)->s6_addr32[2] == htonl(0x0000ffff))) 927453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#endif 937453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org 94c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef WATT32 95c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define sock_write SockWrite /* Watt-32 uses same names */ 96c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define sock_read SockRead 97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define sock_puts SockPuts 98c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_write(BIO *h, const char *buf, int num); 101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_read(BIO *h, char *buf, int size); 102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_puts(BIO *h, const char *str); 103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); 104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_new(BIO *h); 105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_free(BIO *data); 106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_clear(BIO *bio); 107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef OPENSSL_NO_SCTP 1092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_write(BIO *h, const char *buf, int num); 1102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_read(BIO *h, char *buf, int size); 1112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_puts(BIO *h, const char *str); 1122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2); 1132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_new(BIO *h); 1142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_free(BIO *data); 1152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_AUTHENTICATION_EVENT 1162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp); 1172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 1182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 1192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int BIO_dgram_should_retry(int s); 121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void get_current_time(struct timeval *t); 123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic BIO_METHOD methods_dgramp= 125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_TYPE_DGRAM, 127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org "datagram socket", 128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dgram_write, 129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dgram_read, 130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dgram_puts, 131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org NULL, /* dgram_gets, */ 132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dgram_ctrl, 133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dgram_new, 134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dgram_free, 135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org NULL, 136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org }; 137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef OPENSSL_NO_SCTP 1392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic BIO_METHOD methods_dgramp_sctp= 1402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 1412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO_TYPE_DGRAM_SCTP, 1422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org "datagram sctp socket", 1432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_write, 1442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_read, 1452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_puts, 1462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org NULL, /* dgram_gets, */ 1472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_ctrl, 1482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_new, 1492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_free, 1502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org NULL, 1512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org }; 1522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 1532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef struct bio_dgram_data_st 155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org union { 157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr sa; 158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr_in sa_in; 159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr_in6 sa_in6; 161480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 162480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } peer; 163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int connected; 164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int _errno; 165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int mtu; 166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct timeval next_timeout; 167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct timeval socket_timeout; 168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } bio_dgram_data; 169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef OPENSSL_NO_SCTP 1712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgtypedef struct bio_dgram_sctp_save_message_st 1722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 1732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO *bio; 1742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org char *data; 1752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int length; 1762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } bio_dgram_sctp_save_message; 1772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 1782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgtypedef struct bio_dgram_sctp_data_st 1792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 1802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org union { 1812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sockaddr sa; 1822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sockaddr_in sa_in; 1832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#if OPENSSL_USE_IPV6 1842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sockaddr_in6 sa_in6; 1852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 1862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } peer; 1872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org unsigned int connected; 1882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org unsigned int _errno; 1892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org unsigned int mtu; 1902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct bio_dgram_sctp_sndinfo sndinfo; 1912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct bio_dgram_sctp_rcvinfo rcvinfo; 1922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct bio_dgram_sctp_prinfo prinfo; 1932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org void (*handle_notifications)(BIO *bio, void *context, void *buf); 1942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org void* notification_context; 1952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int in_handshake; 1962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ccs_rcvd; 1972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ccs_sent; 1982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int save_shutdown; 1992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int peer_auth_tested; 2002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_save_message saved_message; 2012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } bio_dgram_sctp_data; 2022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 2032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgBIO_METHOD *BIO_s_datagram(void) 205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(&methods_dgramp); 207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgBIO *BIO_new_dgram(int fd, int close_flag) 210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO *ret; 212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=BIO_new(BIO_s_datagram()); 214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == NULL) return(NULL); 215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_fd(ret,fd,close_flag); 216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_new(BIO *bi) 220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio_dgram_data *data = NULL; 222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bi->init=0; 224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bi->num=0; 225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data = OPENSSL_malloc(sizeof(bio_dgram_data)); 226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data == NULL) 227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org memset(data, 0x00, sizeof(bio_dgram_data)); 229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bi->ptr = data; 230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bi->flags=0; 232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_free(BIO *a) 236c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio_dgram_data *data; 238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (a == NULL) return(0); 240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( ! dgram_clear(a)) 241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data = (bio_dgram_data *)a->ptr; 244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(data != NULL) OPENSSL_free(data); 245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_clear(BIO *a) 250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (a == NULL) return(0); 252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (a->shutdown) 253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (a->init) 255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org SHUTDOWN2(a->num); 257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org a->init=0; 259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org a->flags=0; 260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 262c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void dgram_adjust_rcv_timeout(BIO *b) 265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(SO_RCVTIMEO) 267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio_dgram_data *data = (bio_dgram_data *)b->ptr; 2687453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org union { size_t s; int i; } sz = {0}; 269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Is a timer active? */ 271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) 272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct timeval timenow, timeleft; 274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Read current socket timeout */ 276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_WINDOWS 277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int timeout; 2787453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org 2797453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org sz.i = sizeof(timeout); 280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 2817453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org (void*)&timeout, &sz.i) < 0) 282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("getsockopt"); } 283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->socket_timeout.tv_sec = timeout / 1000; 286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->socket_timeout.tv_usec = (timeout % 1000) * 1000; 287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 2897453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org sz.i = sizeof(data->socket_timeout); 290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org &(data->socket_timeout), (void *)&sz) < 0) 292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("getsockopt"); } 2937453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 2947453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org OPENSSL_assert(sz.s<=sizeof(data->socket_timeout)); 295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Get current time */ 298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org get_current_time(&timenow); 299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Calculate time left until timer expires */ 301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); 302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org timeleft.tv_sec -= timenow.tv_sec; 303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org timeleft.tv_usec -= timenow.tv_usec; 304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (timeleft.tv_usec < 0) 305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org timeleft.tv_sec--; 307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org timeleft.tv_usec += 1000000; 308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (timeleft.tv_sec < 0) 311c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org timeleft.tv_sec = 0; 313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org timeleft.tv_usec = 1; 314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 316c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Adjust socket timeout if next handhake message timer 317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * will expire earlier. 318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 319c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) || 320c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (data->socket_timeout.tv_sec > timeleft.tv_sec) || 321c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (data->socket_timeout.tv_sec == timeleft.tv_sec && 322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->socket_timeout.tv_usec >= timeleft.tv_usec)) 323c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_WINDOWS 325c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; 326c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 327c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (void*)&timeout, sizeof(timeout)) < 0) 328c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("setsockopt"); } 329c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 330c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, 331c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sizeof(struct timeval)) < 0) 332c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("setsockopt"); } 333c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 335c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void dgram_reset_rcv_timeout(BIO *b) 340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(SO_RCVTIMEO) 342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio_dgram_data *data = (bio_dgram_data *)b->ptr; 343c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 344c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Is a timer active? */ 345c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) 346c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 347c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_WINDOWS 348c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int timeout = data->socket_timeout.tv_sec * 1000 + 349c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->socket_timeout.tv_usec / 1000; 350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (void*)&timeout, sizeof(timeout)) < 0) 352c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("setsockopt"); } 353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), 355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sizeof(struct timeval)) < 0) 356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("setsockopt"); } 357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 358c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 360c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 361c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_read(BIO *b, char *out, int outl) 363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret=0; 365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio_dgram_data *data = (bio_dgram_data *)b->ptr; 366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 367480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct { 368480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* 369480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * See commentary in b_sock.c. <appro> 370480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 371480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org union { size_t s; int i; } len; 372480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org union { 373480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr sa; 374480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr_in sa_in; 375480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 376480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr_in6 sa_in6; 377480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 378480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } peer; 379480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } sa; 380480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 381480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org sa.len.s=0; 382480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org sa.len.i=sizeof(sa.peer); 383c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 384c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (out != NULL) 385c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 386c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org clear_socket_error(); 387480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memset(&sa.peer, 0x00, sizeof(sa.peer)); 388c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dgram_adjust_rcv_timeout(b); 389480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len); 390480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) 391480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 392480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org OPENSSL_assert(sa.len.s<=sizeof(sa.peer)); 393480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org sa.len.i = (int)sa.len.s; 394480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 395c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 396c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( ! data->connected && ret >= 0) 397480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); 398c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 399c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_clear_retry_flags(b); 400c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret < 0) 401c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 402c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BIO_dgram_should_retry(ret)) 403c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 404c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_retry_read(b); 405c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->_errno = get_last_socket_error(); 406c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 407c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 408480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 409480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org dgram_reset_rcv_timeout(b); 410c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 411c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 412c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 413c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 414c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_write(BIO *b, const char *in, int inl) 415c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 416c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret; 417c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio_dgram_data *data = (bio_dgram_data *)b->ptr; 418c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org clear_socket_error(); 419c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 420480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if ( data->connected ) 421480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret=writesocket(b->num,in,inl); 422480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else 423480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 424480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int peerlen = sizeof(data->peer); 425480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 426480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (data->peer.sa.sa_family == AF_INET) 427480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org peerlen = sizeof(data->peer.sa_in); 428480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 429480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else if (data->peer.sa.sa_family == AF_INET6) 430480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org peerlen = sizeof(data->peer.sa_in6); 431480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 432c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) 433480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); 434c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 435480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); 436c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 437480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 438c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 439c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_clear_retry_flags(b); 440c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret <= 0) 441c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 442c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BIO_dgram_should_retry(ret)) 443c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 444c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_retry_write(b); 445c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->_errno = get_last_socket_error(); 446c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 447c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0 /* higher layers are responsible for querying MTU, if necessary */ 448c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( data->_errno == EMSGSIZE) 449c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* retrieve the new MTU */ 450c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); 451c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 452c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 453c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 454c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 455c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 456c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 457c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) 458c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 459c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org long ret=1; 460c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int *ip; 461c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct sockaddr *to = NULL; 462c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio_dgram_data *data = NULL; 4637453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU)) 4647453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org int sockopt_val = 0; 4657453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org socklen_t sockopt_len; /* assume that system supporting IP_MTU is 4667453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org * modern enough to define socklen_t */ 467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org socklen_t addr_len; 468480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org union { 469480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr sa; 470480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr_in s4; 471480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 472480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org struct sockaddr_in6 s6; 473480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 474480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } addr; 475c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 476c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 477c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data = (bio_dgram_data *)b->ptr; 478c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 479c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (cmd) 480c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 481c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_RESET: 482c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org num=0; 483c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_FILE_SEEK: 484c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 485c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 486c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_FILE_TELL: 487c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_INFO: 488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_SET_FD: 491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dgram_clear(b); 492c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->num= *((int *)ptr); 493c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->shutdown=(int)num; 494c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->init=1; 495c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 496c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_GET_FD: 497c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (b->init) 498c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ip=(int *)ptr; 500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ip != NULL) *ip=b->num; 501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=b->num; 502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret= -1; 505c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 506c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_GET_CLOSE: 507c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=b->shutdown; 508c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 509c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_SET_CLOSE: 510c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->shutdown=(int)num; 511c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 512c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_PENDING: 513c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_WPENDING: 514c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 515c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 516c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DUP: 517c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_FLUSH: 518c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=1; 519c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 520c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_CONNECT: 521c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org to = (struct sockaddr *)ptr; 522c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0 523c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (connect(b->num, to, sizeof(struct sockaddr)) < 0) 524c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("connect"); ret = 0; } 525c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 526c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 527c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 528480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org switch (to->sa_family) 529480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 530480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case AF_INET: 531480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa_in)); 532480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 533480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 534480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case AF_INET6: 535480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); 536480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 537480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 538480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org default: 539480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa)); 540480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 541480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 542c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0 543c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 544c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 545c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 546c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* (Linux)kernel sets DF bit on outgoing IP packets */ 547c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_MTU_DISCOVER: 5487453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) 549480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org addr_len = (socklen_t)sizeof(addr); 550480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memset((void *)&addr, 0, sizeof(addr)); 551480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (getsockname(b->num, &addr.sa, &addr_len) < 0) 552c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 553c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 0; 554c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 555c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 556480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org switch (addr.sa.sa_family) 557c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 558c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case AF_INET: 559c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sockopt_val = IP_PMTUDISC_DO; 560c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, 561c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org &sockopt_val, sizeof(sockopt_val))) < 0) 562c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org perror("setsockopt"); 563c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 5647453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) 565c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case AF_INET6: 566c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sockopt_val = IPV6_PMTUDISC_DO; 567c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, 568c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org &sockopt_val, sizeof(sockopt_val))) < 0) 569c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org perror("setsockopt"); 570c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 571480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 572c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 573c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = -1; 574c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 575c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 576c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = -1; 577c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 578c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 579c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 580c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_QUERY_MTU: 5817453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU) 582480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org addr_len = (socklen_t)sizeof(addr); 583480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memset((void *)&addr, 0, sizeof(addr)); 584480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (getsockname(b->num, &addr.sa, &addr_len) < 0) 585c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 586c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 0; 587c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 588c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 589c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sockopt_len = sizeof(sockopt_val); 590480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org switch (addr.sa.sa_family) 591c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 592c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case AF_INET: 593c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, 594c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org &sockopt_len)) < 0 || sockopt_val < 0) 595c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 596c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 0; 597c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 598c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 599c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 600c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* we assume that the transport protocol is UDP and no 601c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IP options are used. 602c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 603c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->mtu = sockopt_val - 8 - 20; 604c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = data->mtu; 605c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 606c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 607480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 && defined(IPV6_MTU) 608c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case AF_INET6: 609c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val, 610c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org &sockopt_len)) < 0 || sockopt_val < 0) 611c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 612c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 0; 613c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 614c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 615c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 616c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* we assume that the transport protocol is UDP and no 617c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IPV6 options are used. 618c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 619c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->mtu = sockopt_val - 8 - 40; 620c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = data->mtu; 621c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 622c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 623480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 624c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 625c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 0; 626c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 627c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 628c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 629c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 0; 630c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 631c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 6322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: 6332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org switch (data->peer.sa.sa_family) 6342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 6352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case AF_INET: 6362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = 576 - 20 - 8; 6372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 6382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#if OPENSSL_USE_IPV6 6392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case AF_INET6: 6402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef IN6_IS_ADDR_V4MAPPED 6412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) 6422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = 576 - 20 - 8; 6432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 6442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 6452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = 1280 - 40 - 8; 6462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 6472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 6482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org default: 6492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = 576 - 20 - 8; 6502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 6512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 6522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 653c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_GET_MTU: 654c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return data->mtu; 655c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 656c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_SET_MTU: 657c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->mtu = num; 658c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = num; 659c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 660c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_SET_CONNECTED: 661c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org to = (struct sockaddr *)ptr; 662c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 663c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( to != NULL) 664c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 665c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->connected = 1; 666480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org switch (to->sa_family) 667480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 668480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case AF_INET: 669480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa_in)); 670480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 671480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 672480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case AF_INET6: 673480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); 674480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 675480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 676480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org default: 677480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa)); 678480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 679480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 680c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 681c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 682c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 683c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->connected = 0; 684480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memset(&(data->peer), 0x00, sizeof(data->peer)); 685480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 686480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 687480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case BIO_CTRL_DGRAM_GET_PEER: 688480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org switch (data->peer.sa.sa_family) 689480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 690480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case AF_INET: 691480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret=sizeof(data->peer.sa_in); 692480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 693480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 694480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case AF_INET6: 695480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret=sizeof(data->peer.sa_in6); 696480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 697480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 698480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org default: 699480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ret=sizeof(data->peer.sa); 700480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 701480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 702480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (num==0 || num>ret) 703480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org num=ret; 704480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(ptr,&data->peer,(ret=num)); 705480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 706480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case BIO_CTRL_DGRAM_SET_PEER: 707480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org to = (struct sockaddr *) ptr; 708480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org switch (to->sa_family) 709480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 710480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case AF_INET: 711480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa_in)); 712480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 713480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if OPENSSL_USE_IPV6 714480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org case AF_INET6: 715480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); 716480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 717480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 718480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org default: 719480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&data->peer,to,sizeof(data->peer.sa)); 720480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 721c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 722c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 723c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: 724480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); 725c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 726c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(SO_RCVTIMEO) 727c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: 728c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_WINDOWS 729c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 730c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct timeval *tv = (struct timeval *)ptr; 731c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; 732c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 733c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (void*)&timeout, sizeof(timeout)) < 0) 734c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("setsockopt"); ret = -1; } 735c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 736c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 737c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, 738c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sizeof(struct timeval)) < 0) 739c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("setsockopt"); ret = -1; } 740c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 741c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 742c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: 743c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 7447453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org union { size_t s; int i; } sz = {0}; 7457453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#ifdef OPENSSL_SYS_WINDOWS 7467453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org int timeout; 747c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct timeval *tv = (struct timeval *)ptr; 7487453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org 7497453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org sz.i = sizeof(timeout); 750c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 7517453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org (void*)&timeout, &sz.i) < 0) 752c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("getsockopt"); ret = -1; } 753c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 754c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 755c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tv->tv_sec = timeout / 1000; 756c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tv->tv_usec = (timeout % 1000) * 1000; 757c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = sizeof(*tv); 758c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 759c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 7607453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org sz.i = sizeof(struct timeval); 761c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 7627453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ptr, (void *)&sz) < 0) 763c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("getsockopt"); ret = -1; } 7647453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 7657453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org { 7667453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org OPENSSL_assert(sz.s<=sizeof(struct timeval)); 7677453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ret = (int)sz.s; 7687453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org } 7697453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org else 7707453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ret = sz.i; 771c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 7727453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org } 773c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 774c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 775c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(SO_SNDTIMEO) 776c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: 777c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_WINDOWS 778c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 779c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct timeval *tv = (struct timeval *)ptr; 780c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; 781c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 782c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (void*)&timeout, sizeof(timeout)) < 0) 783c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("setsockopt"); ret = -1; } 784c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 785c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 786c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, 787c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sizeof(struct timeval)) < 0) 788c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("setsockopt"); ret = -1; } 789c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 790c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 791c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: 792c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 7937453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org union { size_t s; int i; } sz = {0}; 7947453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#ifdef OPENSSL_SYS_WINDOWS 7957453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org int timeout; 796c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct timeval *tv = (struct timeval *)ptr; 7977453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org 7987453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org sz.i = sizeof(timeout); 799c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 8007453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org (void*)&timeout, &sz.i) < 0) 801c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("getsockopt"); ret = -1; } 802c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 803c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 804c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tv->tv_sec = timeout / 1000; 805c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org tv->tv_usec = (timeout % 1000) * 1000; 806c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = sizeof(*tv); 807c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 808c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 8097453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org sz.i = sizeof(struct timeval); 810c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 8117453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ptr, (void *)&sz) < 0) 812c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { perror("getsockopt"); ret = -1; } 8137453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 8147453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org { 8157453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org OPENSSL_assert(sz.s<=sizeof(struct timeval)); 8167453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ret = (int)sz.s; 8177453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org } 8187453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org else 8197453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ret = sz.i; 820c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 8217453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org } 822c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 823c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 824c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: 825c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* fall-through */ 826c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: 827c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_WINDOWS 828c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( data->_errno == WSAETIMEDOUT) 829c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 830c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( data->_errno == EAGAIN) 831c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 832c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 833c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 1; 834c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->_errno = 0; 835c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 836c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 837c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 0; 838c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 839c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef EMSGSIZE 840c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DGRAM_MTU_EXCEEDED: 841c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ( data->_errno == EMSGSIZE) 842c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 843c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 1; 844c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->_errno = 0; 845c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 846c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 847c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = 0; 848c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 849c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 850c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 851c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 852c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 853c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 854c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 855c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 856c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 857c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int dgram_puts(BIO *bp, const char *str) 858c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 859c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int n,ret; 860c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 861c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org n=strlen(str); 862c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=dgram_write(bp,str,n); 863c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 864c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 865c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 8662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef OPENSSL_NO_SCTP 8672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgBIO_METHOD *BIO_s_datagram_sctp(void) 8682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 8692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return(&methods_dgramp_sctp); 8702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 8712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 8722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgBIO *BIO_new_dgram_sctp(int fd, int close_flag) 8732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 8742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO *bio; 8752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ret, optval = 20000; 8762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int auth_data = 0, auth_forward = 0; 8772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org unsigned char *p; 8782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_authchunk auth; 8792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_authchunks *authchunks; 8802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org socklen_t sockopt_len; 8812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_AUTHENTICATION_EVENT 8822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_EVENT 8832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_event event; 8842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 8852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_event_subscribe event; 8862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 8872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 8882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 8892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio=BIO_new(BIO_s_datagram_sctp()); 8902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (bio == NULL) return(NULL); 8912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO_set_fd(bio,fd,close_flag); 8922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 8932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */ 8942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE; 8952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk)); 8962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 8972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE; 8982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk)); 8992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 9002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Test if activation was successful. When using accept(), 9022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * SCTP-AUTH has to be activated for the listening socket 9032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * already, otherwise the connected socket won't use it. */ 9042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockopt_len = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); 9052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authchunks = OPENSSL_malloc(sockopt_len); 9062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(authchunks, 0, sizeof(sockopt_len)); 9072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len); 9082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 9092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t); 9112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org p < (unsigned char*) authchunks + sockopt_len; 9122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org p += sizeof(uint8_t)) 9132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 9142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1; 9152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1; 9162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 9172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_free(authchunks); 9192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(auth_data); 9212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(auth_forward); 9222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_AUTHENTICATION_EVENT 9242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_EVENT 9252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&event, 0, sizeof(struct sctp_event)); 9262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_assoc_id = 0; 9272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_type = SCTP_AUTHENTICATION_EVENT; 9282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_on = 1; 9292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 9302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 9312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 9322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe); 9332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len); 9342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 9352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.sctp_authentication_event = 1; 9372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 9392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 9402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 9412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 9422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Disable partial delivery by setting the min size 9442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * larger than the max record size of 2^14 + 2048 + 13 9452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 9462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval)); 9472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 9482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return(bio); 9502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 9512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgint BIO_dgram_is_sctp(BIO *bio) 9532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 9542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP); 9552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 9562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_new(BIO *bi) 9582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 9592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_data *data = NULL; 9602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bi->init=0; 9622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bi->num=0; 9632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data)); 9642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (data == NULL) 9652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 0; 9662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(data, 0x00, sizeof(bio_dgram_sctp_data)); 9672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_PR_SCTP_NONE 9682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->prinfo.pr_policy = SCTP_PR_SCTP_NONE; 9692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 9702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bi->ptr = data; 9712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bi->flags=0; 9732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return(1); 9742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 9752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_free(BIO *a) 9772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 9782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_data *data; 9792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (a == NULL) return(0); 9812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if ( ! dgram_clear(a)) 9822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 0; 9832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data = (bio_dgram_sctp_data *)a->ptr; 9852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if(data != NULL) OPENSSL_free(data); 9862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return(1); 9882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 9892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_AUTHENTICATION_EVENT 9912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgvoid dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp) 9922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 9932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ret; 9942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event; 9952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 9962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) 9972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 9982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_authkeyid authkeyid; 9992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* delete key */ 10012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authkeyid.scact_keynumber = authkeyevent->auth_keynumber; 10022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, 10037453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org &authkeyid, sizeof(struct sctp_authkeyid)); 10042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 10052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 10062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 10072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_read(BIO *b, char *out, int outl) 10092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ret = 0, n = 0, i, optval; 10112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org socklen_t optlen; 10122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 10132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org union sctp_notification *snp; 10142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct msghdr msg; 10152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct iovec iov; 10162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct cmsghdr *cmsg; 10172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org char cmsgbuf[512]; 10182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (out != NULL) 10202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org clear_socket_error(); 10222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org do 10242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo)); 10262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_base = out; 10272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_len = outl; 10282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_name = NULL; 10292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_namelen = 0; 10302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iov = &iov; 10312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iovlen = 1; 10322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_control = cmsgbuf; 10332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen = 512; 10342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_flags = 0; 10352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org n = recvmsg(b->num, &msg, 0); 10362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (msg.msg_controllen > 0) 10382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) 10402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (cmsg->cmsg_level != IPPROTO_SCTP) 10422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org continue; 10432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_RCVINFO 10442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (cmsg->cmsg_type == SCTP_RCVINFO) 10452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_rcvinfo *rcvinfo; 10472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg); 10492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_sid = rcvinfo->rcv_sid; 10502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn; 10512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_flags = rcvinfo->rcv_flags; 10522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid; 10532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn; 10542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn; 10552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_context = rcvinfo->rcv_context; 10562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 10572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 10582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_SNDRCV 10592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (cmsg->cmsg_type == SCTP_SNDRCV) 10602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_sndrcvinfo *sndrcvinfo; 10622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 10642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream; 10652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn; 10662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags; 10672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid; 10682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn; 10692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn; 10702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context; 10712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 10722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 10732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 10742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 10752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (n <= 0) 10772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (n < 0) 10792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = n; 10802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 10812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 10822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 10832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (msg.msg_flags & MSG_NOTIFICATION) 10842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org snp = (union sctp_notification*) out; 10862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) 10872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_EVENT 10892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_event event; 10902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 10912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_event_subscribe event; 10922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org socklen_t eventsize; 10932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 10942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* If a message has been delayed until the socket 10952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * is dry, it can be sent now. 10962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 10972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (data->saved_message.length > 0) 10982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 10992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_write(data->saved_message.bio, data->saved_message.data, 11002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->saved_message.length); 11012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_free(data->saved_message.data); 11022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->saved_message.length = 0; 11032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 11042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* disable sender dry event */ 11062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_EVENT 11072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&event, 0, sizeof(struct sctp_event)); 11082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_assoc_id = 0; 11092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_type = SCTP_SENDER_DRY_EVENT; 11102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_on = 0; 11112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 11122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(i >= 0); 11132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 11142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org eventsize = sizeof(struct sctp_event_subscribe); 11152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 11162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(i >= 0); 11172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.sctp_sender_dry_event = 0; 11192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 11212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(i >= 0); 11222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 11232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 11242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_AUTHENTICATION_EVENT 11262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 11272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_handle_auth_free_key_event(b, snp); 11282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 11292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (data->handle_notifications != NULL) 11312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->handle_notifications(b, data->notification_context, (void*) out); 11322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(out, 0, outl); 11342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 11352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 11362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret += n; 11372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 11382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl)); 11392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret > 0 && !(msg.msg_flags & MSG_EOR)) 11412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 11422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Partial message read, this should never happen! */ 11432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* The buffer was too small, this means the peer sent 11452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * a message that was larger than allowed. */ 11462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret == outl) 11472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 11482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Test if socket buffer can handle max record 11502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * size (2^14 + 2048 + 13) 11512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 11522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org optlen = (socklen_t) sizeof(int); 11532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen); 11542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 11552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(optval >= 18445); 11562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Test if SCTP doesn't partially deliver below 11582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * max record size (2^14 + 2048 + 13) 11592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 11602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org optlen = (socklen_t) sizeof(int); 11612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, 11622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org &optval, &optlen); 11632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ret >= 0); 11642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(optval >= 18445); 11652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Partially delivered notification??? Probably a bug.... */ 11672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION)); 11682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Everything seems ok till now, so it's most likely 11702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * a message dropped by PR-SCTP. 11712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 11722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(out, 0, outl); 11732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO_set_retry_read(b); 11742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 11752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 11762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO_clear_retry_flags(b); 11782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) 11792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 11802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (BIO_dgram_should_retry(ret)) 11812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 11822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO_set_retry_read(b); 11832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->_errno = get_last_socket_error(); 11842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 11852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 11862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Test if peer uses SCTP-AUTH before continuing */ 11882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!data->peer_auth_tested) 11892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 11902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ii, auth_data = 0, auth_forward = 0; 11912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org unsigned char *p; 11922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_authchunks *authchunks; 11932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 11942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org optlen = (socklen_t)(sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); 11952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authchunks = OPENSSL_malloc(optlen); 11962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(authchunks, 0, sizeof(optlen)); 11972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen); 11982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_assert(ii >= 0); 11992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t); 12012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org p < (unsigned char*) authchunks + optlen; 12022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org p += sizeof(uint8_t)) 12032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 12042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1; 12052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1; 12062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 12072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org OPENSSL_free(authchunks); 12092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!auth_data || !auth_forward) 12112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 12122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIOerr(BIO_F_DGRAM_SCTP_READ,BIO_R_CONNECT_ERROR); 12132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 12142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 12152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->peer_auth_tested = 1; 12172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 12182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 12192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return(ret); 12202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 12212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_write(BIO *b, const char *in, int inl) 12232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 12242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ret; 12252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 12262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo); 12272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo); 12282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct bio_dgram_sctp_sndinfo handshake_sinfo; 12292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct iovec iov[1]; 12302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct msghdr msg; 12312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct cmsghdr *cmsg; 12322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) 12332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + CMSG_SPACE(sizeof(struct sctp_prinfo))]; 12342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_sndinfo *sndinfo; 12352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_prinfo *prinfo; 12362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 12372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; 12382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_sndrcvinfo *sndrcvinfo; 12392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 12402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org clear_socket_error(); 12422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* If we're send anything else than application data, 12442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * disable all user parameters and flags. 12452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 12462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (in[0] != 23) { 12472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo)); 12482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_SACK_IMMEDIATELY 12492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY; 12502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 12512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sinfo = &handshake_sinfo; 12522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 12532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* If we have to send a shutdown alert message and the 12552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * socket is not dry yet, we have to save it and send it 12562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * as soon as the socket gets dry. 12572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 12582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) 12592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 12602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->saved_message.bio = b; 12612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->saved_message.length = inl; 12622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->saved_message.data = OPENSSL_malloc(inl); 12632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(data->saved_message.data, in, inl); 12642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return inl; 12652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 12662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov[0].iov_base = (char *)in; 12682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov[0].iov_len = inl; 12692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_name = NULL; 12702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_namelen = 0; 12712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iov = iov; 12722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iovlen = 1; 12732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_control = (caddr_t)cmsgbuf; 12742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen = 0; 12752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_flags = 0; 12762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) 12772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg = (struct cmsghdr *)cmsgbuf; 12782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_level = IPPROTO_SCTP; 12792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_type = SCTP_SNDINFO; 12802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); 12812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg); 12822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(sndinfo, 0, sizeof(struct sctp_sndinfo)); 12832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndinfo->snd_sid = sinfo->snd_sid; 12842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndinfo->snd_flags = sinfo->snd_flags; 12852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndinfo->snd_ppid = sinfo->snd_ppid; 12862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndinfo->snd_context = sinfo->snd_context; 12872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); 12882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 12892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg = (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))]; 12902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_level = IPPROTO_SCTP; 12912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_type = SCTP_PRINFO; 12922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); 12932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg); 12942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(prinfo, 0, sizeof(struct sctp_prinfo)); 12952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org prinfo->pr_policy = pinfo->pr_policy; 12962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org prinfo->pr_value = pinfo->pr_value; 12972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); 12982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 12992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg = (struct cmsghdr *)cmsgbuf; 13002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_level = IPPROTO_SCTP; 13012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_type = SCTP_SNDRCV; 13022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 13032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 13042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); 13052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndrcvinfo->sinfo_stream = sinfo->snd_sid; 13062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndrcvinfo->sinfo_flags = sinfo->snd_flags; 13072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef __FreeBSD__ 13082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndrcvinfo->sinfo_flags |= pinfo->pr_policy; 13092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 13102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndrcvinfo->sinfo_ppid = sinfo->snd_ppid; 13112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndrcvinfo->sinfo_context = sinfo->snd_context; 13122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sndrcvinfo->sinfo_timetolive = pinfo->pr_value; 13132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); 13142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 13152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 13162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = sendmsg(b->num, &msg, 0); 13172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 13182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO_clear_retry_flags(b); 13192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret <= 0) 13202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 13212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (BIO_dgram_should_retry(ret)) 13222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 13232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIO_set_retry_write(b); 13242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->_errno = get_last_socket_error(); 13252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 13262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 13272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return(ret); 13282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 13292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 13302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) 13312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 13322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org long ret=1; 13332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_data *data = NULL; 13347453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org socklen_t sockopt_len = 0; 13352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_authkeyid authkeyid; 13362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_authkey *authkey; 13372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 13382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data = (bio_dgram_sctp_data *)b->ptr; 13392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 13402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org switch (cmd) 13412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 13422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_QUERY_MTU: 13432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Set to maximum (2^14) 13442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * and ignore user input to enable transport 13452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * protocol fragmentation. 13462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * Returns always 2^14. 13472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 13482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->mtu = 16384; 13492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = data->mtu; 13502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 13512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SET_MTU: 13522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Set to maximum (2^14) 13532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * and ignore input to enable transport 13542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * protocol fragmentation. 13552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * Returns always 2^14. 13562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 13572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->mtu = 16384; 13582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = data->mtu; 13592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 13602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SET_CONNECTED: 13612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_CONNECT: 13622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns always -1. */ 13632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = -1; 13642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 13652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: 13662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* SCTP doesn't need the DTLS timer 13672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * Returns always 1. 13682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 13692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 13702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE: 13712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (num > 0) 13722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->in_handshake = 1; 13732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 13742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->in_handshake = 0; 13752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 13762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, &data->in_handshake, sizeof(int)); 13772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 13782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY: 13792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* New shared key for SCTP AUTH. 13802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * Returns 0 on success, -1 otherwise. 13812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 13822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 13832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Get active key */ 13842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockopt_len = sizeof(struct sctp_authkeyid); 13852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 13862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) break; 13872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 13882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Add new key */ 13892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t); 13902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authkey = OPENSSL_malloc(sockopt_len); 13912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(authkey, 0x00, sockopt_len); 13922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authkey->sca_keynumber = authkeyid.scact_keynumber + 1; 13932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef __FreeBSD__ 13942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* This field is missing in FreeBSD 8.2 and earlier, 13952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * and FreeBSD 8.3 and higher work without it. 13962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 13972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authkey->sca_keylength = 64; 13982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 13992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t)); 14002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len); 14022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) break; 14032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Reset active key */ 14052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, 14062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org &authkeyid, sizeof(struct sctp_authkeyid)); 14072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) break; 14082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 14102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY: 14112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns 0 on success, -1 otherwise. */ 14122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Get active key */ 14142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockopt_len = sizeof(struct sctp_authkeyid); 14152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 14162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) break; 14172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Set active key */ 14192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1; 14202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, 14212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org &authkeyid, sizeof(struct sctp_authkeyid)); 14222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) break; 14232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* CCS has been sent, so remember that and fall through 14252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * to check if we need to deactivate an old key 14262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 14272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->ccs_sent = 1; 14282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD: 14302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns 0 on success, -1 otherwise. */ 14312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Has this command really been called or is this just a fall-through? */ 14332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD) 14342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->ccs_rcvd = 1; 14352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* CSS has been both, received and sent, so deactivate an old key */ 14372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (data->ccs_rcvd == 1 && data->ccs_sent == 1) 14382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 14392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Get active key */ 14402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockopt_len = sizeof(struct sctp_authkeyid); 14412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 14422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) break; 14432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Deactivate key or delete second last key if 14452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * SCTP_AUTHENTICATION_EVENT is not available. 14462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 14472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; 14482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_AUTH_DEACTIVATE_KEY 14492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockopt_len = sizeof(struct sctp_authkeyid); 14502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY, 14512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org &authkeyid, sockopt_len); 14522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) break; 14532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 14542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef SCTP_AUTHENTICATION_EVENT 14552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (authkeyid.scact_keynumber > 0) 14562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 14572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; 14582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, 14592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org &authkeyid, sizeof(struct sctp_authkeyid)); 14602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) break; 14612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 14622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 14632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->ccs_rcvd = 0; 14652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->ccs_sent = 0; 14662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 14672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 14682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO: 14692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns the size of the copied struct. */ 14702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo)) 14712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org num = sizeof(struct bio_dgram_sctp_sndinfo); 14722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(ptr, &(data->sndinfo), num); 14742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = num; 14752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 14762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO: 14772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns the size of the copied struct. */ 14782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (num > (long) sizeof(struct bio_dgram_sctp_sndinfo)) 14792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org num = sizeof(struct bio_dgram_sctp_sndinfo); 14802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(&(data->sndinfo), ptr, num); 14822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 14832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO: 14842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns the size of the copied struct. */ 14852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo)) 14862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org num = sizeof(struct bio_dgram_sctp_rcvinfo); 14872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(ptr, &data->rcvinfo, num); 14892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = num; 14912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 14922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO: 14932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns the size of the copied struct. */ 14942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (num > (long) sizeof(struct bio_dgram_sctp_rcvinfo)) 14952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org num = sizeof(struct bio_dgram_sctp_rcvinfo); 14962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 14972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(&(data->rcvinfo), ptr, num); 14982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 14992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_GET_PRINFO: 15002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns the size of the copied struct. */ 15012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (num > (long) sizeof(struct bio_dgram_sctp_prinfo)) 15022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org num = sizeof(struct bio_dgram_sctp_prinfo); 15032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(ptr, &(data->prinfo), num); 15052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = num; 15062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 15072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_SET_PRINFO: 15082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns the size of the copied struct. */ 15092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (num > (long) sizeof(struct bio_dgram_sctp_prinfo)) 15102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org num = sizeof(struct bio_dgram_sctp_prinfo); 15112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(&(data->prinfo), ptr, num); 15132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 15142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN: 15152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Returns always 1. */ 15162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (num > 0) 15172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->save_shutdown = 1; 15182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 15192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->save_shutdown = 0; 15202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 15212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org default: 15232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Pass to default ctrl function to 15242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * process SCTP unspecific commands 15252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 15262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret=dgram_ctrl(b, cmd, num, ptr); 15272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org break; 15282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 15292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return(ret); 15302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 15312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgint BIO_dgram_sctp_notification_cb(BIO *b, 15332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org void (*handle_notifications)(BIO *bio, void *context, void *buf), 15342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org void *context) 15352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 15362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; 15372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (handle_notifications != NULL) 15392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 15402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->handle_notifications = handle_notifications; 15412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->notification_context = context; 15422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 15432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 15442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 15452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 0; 15472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 15482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgint BIO_dgram_sctp_wait_for_dry(BIO *b) 15502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org{ 15512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int is_dry = 0; 15522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int n, sockflags, ret; 15532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org union sctp_notification snp; 15542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct msghdr msg; 15552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct iovec iov; 15562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_EVENT 15572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_event event; 15582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 15592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct sctp_event_subscribe event; 15602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org socklen_t eventsize; 15612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 15622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 15632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* set sender dry event */ 15652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_EVENT 15662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&event, 0, sizeof(struct sctp_event)); 15672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_assoc_id = 0; 15682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_type = SCTP_SENDER_DRY_EVENT; 15692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_on = 1; 15702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 15712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 15722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org eventsize = sizeof(struct sctp_event_subscribe); 15732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 15742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) 15752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 15762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.sctp_sender_dry_event = 1; 15782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 15802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 15812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) 15822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 15832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* peek for notification */ 15852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&snp, 0x00, sizeof(union sctp_notification)); 15862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_base = (char *)&snp; 15872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_len = sizeof(union sctp_notification); 15882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_name = NULL; 15892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_namelen = 0; 15902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iov = &iov; 15912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iovlen = 1; 15922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_control = NULL; 15932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen = 0; 15942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_flags = 0; 15952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 15962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org n = recvmsg(b->num, &msg, MSG_PEEK); 15972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (n <= 0) 15982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 15992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 16002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 16012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 16022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 0; 16032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 16042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* if we find a notification, process it and try again if necessary */ 16062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org while (msg.msg_flags & MSG_NOTIFICATION) 16072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 16082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&snp, 0x00, sizeof(union sctp_notification)); 16092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_base = (char *)&snp; 16102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_len = sizeof(union sctp_notification); 16112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_name = NULL; 16122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_namelen = 0; 16132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iov = &iov; 16142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iovlen = 1; 16152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_control = NULL; 16162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen = 0; 16172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_flags = 0; 16182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org n = recvmsg(b->num, &msg, 0); 16202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (n <= 0) 16212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 16222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 16232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 16242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 16252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return is_dry; 16262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 16272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) 16292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 16302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org is_dry = 1; 16312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* disable sender dry event */ 16332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_EVENT 16342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&event, 0, sizeof(struct sctp_event)); 16352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_assoc_id = 0; 16362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_type = SCTP_SENDER_DRY_EVENT; 16372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.se_on = 0; 16382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); 16392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#else 16402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org eventsize = (socklen_t) sizeof(struct sctp_event_subscribe); 16412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 16422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) 16432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 16442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org event.sctp_sender_dry_event = 0; 16462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 16482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 16492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ret < 0) 16502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 16512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 16522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_AUTHENTICATION_EVENT 16542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 16552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_handle_auth_free_key_event(b, &snp); 16562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 16572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (data->handle_notifications != NULL) 16592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->handle_notifications(b, data->notification_context, (void*) &snp); 16602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* found notification, peek again */ 16622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&snp, 0x00, sizeof(union sctp_notification)); 16632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_base = (char *)&snp; 16642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_len = sizeof(union sctp_notification); 16652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_name = NULL; 16662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_namelen = 0; 16672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iov = &iov; 16682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iovlen = 1; 16692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_control = NULL; 16702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen = 0; 16712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_flags = 0; 16722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* if we have seen the dry already, don't wait */ 16742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (is_dry) 16752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 16762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockflags = fcntl(b->num, F_GETFL, 0); 16772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org fcntl(b->num, F_SETFL, O_NONBLOCK); 16782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 16792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16802c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org n = recvmsg(b->num, &msg, MSG_PEEK); 16812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16822c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (is_dry) 16832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 16842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org fcntl(b->num, F_SETFL, sockflags); 16852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 16862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (n <= 0) 16882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 16892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if ((n < 0) && (get_last_socket_error() != EAGAIN) && (get_last_socket_error() != EWOULDBLOCK)) 16902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return -1; 16912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 16922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return is_dry; 16932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 16942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 16952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 16962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* read anything else */ 16972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return is_dry; 16982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org} 16992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgint BIO_dgram_sctp_msg_waiting(BIO *b) 17012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 17022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int n, sockflags; 17032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org union sctp_notification snp; 17042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct msghdr msg; 17052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org struct iovec iov; 17062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 17072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Check if there are any messages waiting to be read */ 17092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org do 17102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 17112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&snp, 0x00, sizeof(union sctp_notification)); 17122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_base = (char *)&snp; 17132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_len = sizeof(union sctp_notification); 17142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_name = NULL; 17152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_namelen = 0; 17162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iov = &iov; 17172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iovlen = 1; 17182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_control = NULL; 17192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen = 0; 17202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_flags = 0; 17212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org sockflags = fcntl(b->num, F_GETFL, 0); 17232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org fcntl(b->num, F_SETFL, O_NONBLOCK); 17242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org n = recvmsg(b->num, &msg, MSG_PEEK); 17252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org fcntl(b->num, F_SETFL, sockflags); 17262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* if notification, process and try again */ 17282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) 17292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 17302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SCTP_AUTHENTICATION_EVENT 17312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 17322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dgram_sctp_handle_auth_free_key_event(b, &snp); 17332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 17342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memset(&snp, 0x00, sizeof(union sctp_notification)); 17362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_base = (char *)&snp; 17372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org iov.iov_len = sizeof(union sctp_notification); 17382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_name = NULL; 17392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_namelen = 0; 17402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iov = &iov; 17412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_iovlen = 1; 17422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_control = NULL; 17432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_controllen = 0; 17442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org msg.msg_flags = 0; 17452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org n = recvmsg(b->num, &msg, 0); 17462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (data->handle_notifications != NULL) 17482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org data->handle_notifications(b, data->notification_context, (void*) &snp); 17492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 17502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)); 17522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Return 1 if there is a message to be read, return 0 otherwise. */ 17542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (n > 0) 17552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 1; 17562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 17572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 0; 17582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 17592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgstatic int dgram_sctp_puts(BIO *bp, const char *str) 17612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 17622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int n,ret; 17632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 17642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org n=strlen(str); 17652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret=dgram_sctp_write(bp,str,n); 17662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return(ret); 17672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 17682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 17692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 1770c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int BIO_dgram_should_retry(int i) 1771c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1772c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int err; 1773c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1774c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((i == 0) || (i == -1)) 1775c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1776c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org err=get_last_socket_error(); 1777c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1778480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if defined(OPENSSL_SYS_WINDOWS) 1779480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* If the socket return value (i) is -1 1780480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * and err is unexpectedly 0 at this point, 1781480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * the error code was overwritten by 1782480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * another system call before this error 1783480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * handling is called. 1784480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */ 1785c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1786c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1787c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(BIO_dgram_non_fatal_error(err)); 1788c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1789c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(0); 1790c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1791c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1792c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint BIO_dgram_non_fatal_error(int err) 1793c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1794c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (err) 1795c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1796c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(OPENSSL_SYS_WINDOWS) 1797c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# if defined(WSAEWOULDBLOCK) 1798c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case WSAEWOULDBLOCK: 1799c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# endif 1800c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1801c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# if 0 /* This appears to always be an error */ 1802c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# if defined(WSAENOTCONN) 1803c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case WSAENOTCONN: 1804c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# endif 1805c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# endif 1806c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1807c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1808c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef EWOULDBLOCK 1809c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# ifdef WSAEWOULDBLOCK 1810c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# if WSAEWOULDBLOCK != EWOULDBLOCK 1811c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case EWOULDBLOCK: 1812c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# endif 1813c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# else 1814c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case EWOULDBLOCK: 1815c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# endif 1816c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1817c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1818c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef EINTR 1819c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case EINTR: 1820c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1821c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1822c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef EAGAIN 1823c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if EWOULDBLOCK != EAGAIN 1824c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case EAGAIN: 1825c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# endif 1826c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1827c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1828c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef EPROTO 1829c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case EPROTO: 1830c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1831c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1832c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef EINPROGRESS 1833c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case EINPROGRESS: 1834c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1835c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1836c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef EALREADY 1837c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case EALREADY: 1838c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1839c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1840c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 1841c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* break; */ 1842c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 1843c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 1844c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1845c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(0); 1846c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1847c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 1848c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void get_current_time(struct timeval *t) 1849c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 1850c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_WIN32 1851c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct _timeb tb; 1852c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org _ftime(&tb); 1853c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org t->tv_sec = (long)tb.time; 1854c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org t->tv_usec = (long)tb.millitm * 1000; 1855c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#elif defined(OPENSSL_SYS_VMS) 1856c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct timeb tb; 1857c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ftime(&tb); 1858c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org t->tv_sec = (long)tb.time; 1859c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org t->tv_usec = (long)tb.millitm * 1000; 1860c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 1861c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org gettimeofday(t, NULL); 1862c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 1863c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 1864480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 1865480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif 1866