1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* crypto/bio/bss_conn.c */ 2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * All rights reserved. 4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This package is an SSL implementation written 6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * by Eric Young (eay@cryptsoft.com). 7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The implementation was written so as to conform with Netscapes SSL. 8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This library is free for commercial and non-commercial use as long as 10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the following conditions are aheared to. The following conditions 11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * apply to all code found in this distribution, be it the RC4, RSA, 12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * included with this distribution is covered by the same copyright terms 14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright remains Eric Young's, and as such any Copyright notices in 17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the code are not to be removed. 18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * If this package is used in a product, Eric Young should be given attribution 19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * as the author of the parts of the library used. 20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This can be in the form of a textual message at program startup or 21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * in documentation (online or textual) provided with the package. 22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without 24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions 25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met: 26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the copyright 27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer. 28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer in the 30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * documentation and/or other materials provided with the distribution. 31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this software 32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * must display the following acknowledgement: 33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes cryptographic software written by 34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Eric Young (eay@cryptsoft.com)" 35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The word 'cryptographic' can be left out if the rouines from the library 36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * being used are not cryptographic related :-). 37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. If you include any Windows specific code (or a derivative thereof) from 38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the apps directory (application code) you must include an acknowledgement: 39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SUCH DAMAGE. 52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The licence and distribution terms for any publically available version or 54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * derivative of this code cannot be changed. i.e. this code cannot simply be 55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * copied and put under another distribution licence 56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * [including the GNU Public Licence.] 57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h> 60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <errno.h> 61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define USE_SOCKETS 62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h" 63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/bio.h> 64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifndef OPENSSL_NO_SOCK 66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_SYS_WIN16 68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ 69c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define SOCKET_PROTOCOL IPPROTO_TCP 71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 73c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) 74c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ 75c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#undef FIONBIO 76c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 77c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 78c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef struct bio_connect_st 80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int state; 82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 83c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org char *param_hostname; 84c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org char *param_port; 85c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int nbio; 86c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 87c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char ip[4]; 88c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned short port; 89c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org struct sockaddr_in them; 91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 92c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* int socket; this will be kept in bio->num so that it is 93c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * compatible with the bss_sock bio */ 94c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 95c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* called when the connection is initially made 96c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * callback(BIO,state,ret); The callback should return 97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 'ret'. state is for compatibility with the ssl info_callback */ 98c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int (*info_callback)(const BIO *bio,int state,int ret); 99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } BIO_CONNECT; 100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_write(BIO *h, const char *buf, int num); 102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_read(BIO *h, char *buf, int size); 103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_puts(BIO *h, const char *str); 104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2); 105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_new(BIO *h); 106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_free(BIO *data); 107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *); 108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_state(BIO *b, BIO_CONNECT *c); 110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void conn_close_socket(BIO *data); 111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgBIO_CONNECT *BIO_CONNECT_new(void ); 112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid BIO_CONNECT_free(BIO_CONNECT *a); 113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic BIO_METHOD methods_connectp= 115c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_TYPE_CONNECT, 117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org "socket connect", 118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_write, 119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_read, 120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_puts, 121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org NULL, /* connect_gets, */ 122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_ctrl, 123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_new, 124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_free, 125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_callback_ctrl, 126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org }; 127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_state(BIO *b, BIO_CONNECT *c) 129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret= -1,i; 131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned long l; 132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org char *p,*q; 133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int (*cb)(const BIO *,int,int)=NULL; 134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (c->info_callback != NULL) 136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org cb=c->info_callback; 137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (;;) 139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (c->state) 141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CONN_S_BEFORE: 143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p=c->param_hostname; 144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (p == NULL) 145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIOerr(BIO_F_CONN_STATE,BIO_R_NO_HOSTNAME_SPECIFIED); 147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for ( ; *p != '\0'; p++) 150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((*p == ':') || (*p == '/')) break; 152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i= *p; 155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((i == ':') || (i == '/')) 156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *(p++)='\0'; 159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i == ':') 160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (q=p; *q; q++) 162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (*q == '/') 163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *q='\0'; 165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (c->param_port != NULL) 168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(c->param_port); 169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->param_port=BUF_strdup(p); 170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (c->param_port == NULL) 174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIOerr(BIO_F_CONN_STATE,BIO_R_NO_PORT_SPECIFIED); 176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ERR_add_error_data(2,"host=",c->param_hostname); 177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_GET_IP; 180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CONN_S_GET_IP: 183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BIO_get_host_ip(c->param_hostname,&(c->ip[0])) <= 0) 184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_GET_PORT; 186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CONN_S_GET_PORT: 189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (c->param_port == NULL) 190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* abort(); */ 192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (BIO_get_port(c->param_port,&c->port) <= 0) 195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_CREATE_SOCKET; 197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CONN_S_CREATE_SOCKET: 200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* now setup address */ 201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org memset((char *)&c->them,0,sizeof(c->them)); 202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->them.sin_family=AF_INET; 203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->them.sin_port=htons((unsigned short)c->port); 204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org l=(unsigned long) 205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ((unsigned long)c->ip[0]<<24L)| 206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ((unsigned long)c->ip[1]<<16L)| 207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ((unsigned long)c->ip[2]<< 8L)| 208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ((unsigned long)c->ip[3]); 209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->them.sin_addr.s_addr=htonl(l); 210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_CREATE_SOCKET; 211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); 213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == INVALID_SOCKET) 214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org SYSerr(SYS_F_SOCKET,get_last_socket_error()); 216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ERR_add_error_data(4,"host=",c->param_hostname, 217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ":",c->param_port); 218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIOerr(BIO_F_CONN_STATE,BIO_R_UNABLE_TO_CREATE_SOCKET); 219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->num=ret; 222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_NBIO; 223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CONN_S_NBIO: 226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (c->nbio) 227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BIO_socket_nbio(b->num,1)) 229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIOerr(BIO_F_CONN_STATE,BIO_R_ERROR_SETTING_NBIO); 231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ERR_add_error_data(4,"host=", 232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->param_hostname, 233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ":",c->param_port); 234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 236c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_CONNECT; 238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) 240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=1; 241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=setsockopt(b->num,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); 242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i < 0) 243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org SYSerr(SYS_F_SOCKET,get_last_socket_error()); 245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ERR_add_error_data(4,"host=",c->param_hostname, 246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ":",c->param_port); 247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIOerr(BIO_F_CONN_STATE,BIO_R_KEEPALIVE); 248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CONN_S_CONNECT: 254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_clear_retry_flags(b); 255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=connect(b->num, 256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (struct sockaddr *)&c->them, 257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sizeof(c->them)); 258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->retry_reason=0; 259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret < 0) 260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BIO_sock_should_retry(ret)) 262c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_retry_special(b); 264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_BLOCKED_CONNECT; 265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->retry_reason=BIO_RR_CONNECT; 266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org SYSerr(SYS_F_CONNECT,get_last_socket_error()); 270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ERR_add_error_data(4,"host=", 271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->param_hostname, 272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ":",c->param_port); 273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIOerr(BIO_F_CONN_STATE,BIO_R_CONNECT_ERROR); 274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_OK; 279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CONN_S_BLOCKED_CONNECT: 282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=BIO_sock_error(b->num); 283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i) 284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_clear_retry_flags(b); 286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org SYSerr(SYS_F_CONNECT,i); 287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ERR_add_error_data(4,"host=", 288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->param_hostname, 289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ":",c->param_port); 290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIOerr(BIO_F_CONN_STATE,BIO_R_NBIO_CONNECT_ERROR); 291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 293c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c->state=BIO_CONN_S_OK; 296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CONN_S_OK: 299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=1; 300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* abort(); */ 303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto exit_loop; 304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (cb != NULL) 307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(ret=cb((BIO *)b,c->state,ret))) 309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto end; 310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 311c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Loop does not exit */ 314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgexit_loop: 315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (cb != NULL) 316c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=cb((BIO *)b,c->state,ret); 317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgend: 318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 319c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 320c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 321c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgBIO_CONNECT *BIO_CONNECT_new(void) 322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 323c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_CONNECT *ret; 324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 325c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((ret=(BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL) 326c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(NULL); 327c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->state=BIO_CONN_S_BEFORE; 328c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->param_hostname=NULL; 329c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->param_port=NULL; 330c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->info_callback=NULL; 331c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->nbio=0; 332c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->ip[0]=0; 333c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->ip[1]=0; 334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->ip[2]=0; 335c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->ip[3]=0; 336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->port=0; 337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org memset((char *)&ret->them,0,sizeof(ret->them)); 338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid BIO_CONNECT_free(BIO_CONNECT *a) 342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 343c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(a == NULL) 344c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return; 345c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 346c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (a->param_hostname != NULL) 347c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(a->param_hostname); 348c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (a->param_port != NULL) 349c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(a->param_port); 350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(a); 351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 352c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgBIO_METHOD *BIO_s_connect(void) 354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(&methods_connectp); 356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 358c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_new(BIO *bi) 359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 360c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bi->init=0; 361c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bi->num=INVALID_SOCKET; 362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bi->flags=0; 363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((bi->ptr=(char *)BIO_CONNECT_new()) == NULL) 364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(0); 365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 368c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 369c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void conn_close_socket(BIO *bio) 370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_CONNECT *c; 372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 373c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c=(BIO_CONNECT *)bio->ptr; 374c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (bio->num != INVALID_SOCKET) 375c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 376c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Only do a shutdown if things were established */ 377c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (c->state == BIO_CONN_S_OK) 378c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org shutdown(bio->num,2); 379c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org closesocket(bio->num); 380c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bio->num=INVALID_SOCKET; 381c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 382c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 383c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 384c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_free(BIO *a) 385c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 386c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_CONNECT *data; 387c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 388c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (a == NULL) return(0); 389c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data=(BIO_CONNECT *)a->ptr; 390c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 391c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (a->shutdown) 392c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 393c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_close_socket(a); 394c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_CONNECT_free(data); 395c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org a->ptr=NULL; 396c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org a->flags=0; 397c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org a->init=0; 398c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 399c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(1); 400c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 401c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 402c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_read(BIO *b, char *out, int outl) 403c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 404c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret=0; 405c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_CONNECT *data; 406c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 407c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data=(BIO_CONNECT *)b->ptr; 408c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->state != BIO_CONN_S_OK) 409c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 410c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=conn_state(b,data); 411c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret <= 0) 412c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 413c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 414c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 415c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (out != NULL) 416c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 417c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org clear_socket_error(); 418c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=readsocket(b->num,out,outl); 419c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_clear_retry_flags(b); 420c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret <= 0) 421c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 422c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BIO_sock_should_retry(ret)) 423c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_retry_read(b); 424c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 425c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 426c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 427c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 428c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 429c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_write(BIO *b, const char *in, int inl) 430c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 431c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ret; 432c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_CONNECT *data; 433c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 434c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data=(BIO_CONNECT *)b->ptr; 435c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->state != BIO_CONN_S_OK) 436c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 437c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=conn_state(b,data); 438c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret <= 0) return(ret); 439c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 440c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 441c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org clear_socket_error(); 442c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=writesocket(b->num,in,inl); 443c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_clear_retry_flags(b); 444c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret <= 0) 445c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 446c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BIO_sock_should_retry(ret)) 447c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_retry_write(b); 448c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 449c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 450c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 451c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 452c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic long conn_ctrl(BIO *b, int cmd, long num, void *ptr) 453c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 454c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO *dbio; 455c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int *ip; 456c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const char **pptr; 457c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org long ret=1; 458c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_CONNECT *data; 459c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 460c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data=(BIO_CONNECT *)b->ptr; 461c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 462c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (cmd) 463c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 464c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_RESET: 465c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 466c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->state=BIO_CONN_S_BEFORE; 467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org conn_close_socket(b); 468c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->flags=0; 469c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 470c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_DO_STATE_MACHINE: 471c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* use this one to start the connection */ 472c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->state != BIO_CONN_S_OK) 473c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=(long)conn_state(b,data); 474c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 475c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=1; 476c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 477c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_GET_CONNECT: 478c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ptr != NULL) 479c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 480c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org pptr=(const char **)ptr; 481c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (num == 0) 482c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 483c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pptr=data->param_hostname; 484c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 485c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 486c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (num == 1) 487c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pptr=data->param_port; 489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (num == 2) 491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 492c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pptr= (char *)&(data->ip[0]); 493c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 494c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (num == 3) 495c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 496c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *((int *)ptr)=data->port; 497c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 498c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((!b->init) || (ptr == NULL)) 499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pptr="not initialized"; 500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=1; 501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_SET_CONNECT: 504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ptr != NULL) 505c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 506c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->init=1; 507c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (num == 0) 508c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 509c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->param_hostname != NULL) 510c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(data->param_hostname); 511c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->param_hostname=BUF_strdup(ptr); 512c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 513c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (num == 1) 514c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 515c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->param_port != NULL) 516c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(data->param_port); 517c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->param_port=BUF_strdup(ptr); 518c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 519c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (num == 2) 520c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 521c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org char buf[16]; 522c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char *p = ptr; 523c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 524c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_snprintf(buf,sizeof buf,"%d.%d.%d.%d", 525c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p[0],p[1],p[2],p[3]); 526c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->param_hostname != NULL) 527c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(data->param_hostname); 528c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->param_hostname=BUF_strdup(buf); 529c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org memcpy(&(data->ip[0]),ptr,4); 530c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 531c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if (num == 3) 532c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 533c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org char buf[DECIMAL_SIZE(int)+1]; 534c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 535c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_snprintf(buf,sizeof buf,"%d",*(int *)ptr); 536c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->param_port != NULL) 537c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(data->param_port); 538c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->param_port=BUF_strdup(buf); 539c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->port= *(int *)ptr; 540c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 541c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 542c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 543c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_SET_NBIO: 544c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->nbio=(int)num; 545c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 546c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_C_GET_FD: 547c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (b->init) 548c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 549c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ip=(int *)ptr; 550c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ip != NULL) 551c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *ip=b->num; 552c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=b->num; 553c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 554c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 555c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret= -1; 556c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 557c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_GET_CLOSE: 558c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=b->shutdown; 559c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 560c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_SET_CLOSE: 561c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org b->shutdown=(int)num; 562c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 563c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_PENDING: 564c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_WPENDING: 565c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 566c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 567c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_FLUSH: 568c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 569c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_DUP: 570c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 571c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dbio=(BIO *)ptr; 572c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->param_port) 573c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_conn_port(dbio,data->param_port); 574c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (data->param_hostname) 575c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_conn_hostname(dbio,data->param_hostname); 576c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_set_nbio(dbio,data->nbio); 577c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* FIXME: the cast of the function seems unlikely to be a good idea */ 578c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org (void)BIO_set_info_callback(dbio,(bio_info_cb *)data->info_callback); 579c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 580c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 581c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_SET_CALLBACK: 582c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 583c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0 /* FIXME: Should this be used? -- Richard Levitte */ 584c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 585c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret = -1; 586c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 587c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 588c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 589c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 590c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 591c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_GET_CALLBACK: 592c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 593c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int (**fptr)(const BIO *bio,int state,int xret); 594c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 595c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org fptr=(int (**)(const BIO *bio,int state,int xret))ptr; 596c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *fptr=data->info_callback; 597c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 598c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 599c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 600c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 601c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 602c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 603c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 604c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 605c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 606c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) 607c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 608c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org long ret=1; 609c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_CONNECT *data; 610c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 611c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data=(BIO_CONNECT *)b->ptr; 612c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 613c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (cmd) 614c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 615c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case BIO_CTRL_SET_CALLBACK: 616c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 617c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org data->info_callback=(int (*)(const struct bio_st *, int, int))fp; 618c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 619c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 620c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 621c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=0; 622c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 623c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 624c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 625c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 626c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 627c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int conn_puts(BIO *bp, const char *str) 628c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 629c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int n,ret; 630c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 631c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org n=strlen(str); 632c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=conn_write(bp,str,n); 633c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 634c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 635c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 636c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgBIO *BIO_new_connect(char *str) 637c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 638c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO *ret; 639c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 640c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=BIO_new(BIO_s_connect()); 641c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == NULL) return(NULL); 642c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BIO_set_conn_hostname(ret,str)) 643c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 644c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 645c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 646c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIO_free(ret); 647c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(NULL); 648c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 649c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 650c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 651c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 652c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 653