1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/bio/bss_conn.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,679 @@
1.4 +/* crypto/bio/bss_conn.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +/*
1.62 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.63 + */
1.64 +
1.65 +
1.66 +#include <stdio.h>
1.67 +#include <errno.h>
1.68 +#define USE_SOCKETS
1.69 +#include "cryptlib.h"
1.70 +#include <openssl/bio.h>
1.71 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.72 +#include "libcrypto_wsd_macros.h"
1.73 +#include "libcrypto_wsd.h"
1.74 +#endif
1.75 +
1.76 +#ifndef OPENSSL_NO_SOCK
1.77 +
1.78 +#ifdef OPENSSL_SYS_WIN16
1.79 +#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
1.80 +#else
1.81 +#define SOCKET_PROTOCOL IPPROTO_TCP
1.82 +#endif
1.83 +
1.84 +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
1.85 +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
1.86 +#undef FIONBIO
1.87 +#endif
1.88 +
1.89 +
1.90 +typedef struct bio_connect_st
1.91 + {
1.92 + int state;
1.93 +
1.94 + char *param_hostname;
1.95 + char *param_port;
1.96 + int nbio;
1.97 +
1.98 + unsigned char ip[4];
1.99 + unsigned short port;
1.100 +
1.101 + struct sockaddr_in them;
1.102 +
1.103 + /* int socket; this will be kept in bio->num so that it is
1.104 + * compatible with the bss_sock bio */
1.105 +
1.106 + /* called when the connection is initially made
1.107 + * callback(BIO,state,ret); The callback should return
1.108 + * 'ret'. state is for compatibility with the ssl info_callback */
1.109 + int (*info_callback)(const BIO *bio,int state,int ret);
1.110 + } BIO_CONNECT;
1.111 +
1.112 +static int conn_write(BIO *h, const char *buf, int num);
1.113 +static int conn_read(BIO *h, char *buf, int size);
1.114 +static int conn_puts(BIO *h, const char *str);
1.115 +static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
1.116 +static int conn_new(BIO *h);
1.117 +static int conn_free(BIO *data);
1.118 +static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
1.119 +
1.120 +static int conn_state(BIO *b, BIO_CONNECT *c);
1.121 +static void conn_close_socket(BIO *data);
1.122 +BIO_CONNECT *BIO_CONNECT_new(void );
1.123 +void BIO_CONNECT_free(BIO_CONNECT *a);
1.124 +
1.125 +#ifndef EMULATOR
1.126 +static BIO_METHOD methods_connectp=
1.127 + {
1.128 + BIO_TYPE_CONNECT,
1.129 + "socket connect",
1.130 + conn_write,
1.131 + conn_read,
1.132 + conn_puts,
1.133 + NULL, /* connect_gets, */
1.134 + conn_ctrl,
1.135 + conn_new,
1.136 + conn_free,
1.137 + conn_callback_ctrl,
1.138 + };
1.139 +#else
1.140 +
1.141 +GET_STATIC_VAR_FROM_TLS(methods_connectp,bss_conn,BIO_METHOD)
1.142 +#define methods_connectp (*GET_WSD_VAR_NAME(methods_connectp,bss_conn,s)())
1.143 +const BIO_METHOD temp_s_methods_connectp=
1.144 + {
1.145 + BIO_TYPE_CONNECT,
1.146 + "socket connect",
1.147 + conn_write,
1.148 + conn_read,
1.149 + conn_puts,
1.150 + NULL, /* connect_gets, */
1.151 + conn_ctrl,
1.152 + conn_new,
1.153 + conn_free,
1.154 + conn_callback_ctrl,
1.155 + };
1.156 +#endif
1.157 +
1.158 +static int conn_state(BIO *b, BIO_CONNECT *c)
1.159 + {
1.160 + int ret= -1,i;
1.161 + unsigned long l;
1.162 + char *p,*q;
1.163 + int (*cb)(const BIO *,int,int)=NULL;
1.164 +
1.165 + if (c->info_callback != NULL)
1.166 + cb=c->info_callback;
1.167 +
1.168 + for (;;)
1.169 + {
1.170 + switch (c->state)
1.171 + {
1.172 + case BIO_CONN_S_BEFORE:
1.173 + p=c->param_hostname;
1.174 + if (p == NULL)
1.175 + {
1.176 + BIOerr(BIO_F_CONN_STATE,BIO_R_NO_HOSTNAME_SPECIFIED);
1.177 + goto exit_loop;
1.178 + }
1.179 + for ( ; *p != '\0'; p++)
1.180 + {
1.181 + if ((*p == ':') || (*p == '/')) break;
1.182 + }
1.183 +
1.184 + i= *p;
1.185 + if ((i == ':') || (i == '/'))
1.186 + {
1.187 +
1.188 + *(p++)='\0';
1.189 + if (i == ':')
1.190 + {
1.191 + for (q=p; *q; q++)
1.192 + if (*q == '/')
1.193 + {
1.194 + *q='\0';
1.195 + break;
1.196 + }
1.197 + if (c->param_port != NULL)
1.198 + OPENSSL_free(c->param_port);
1.199 + c->param_port=BUF_strdup(p);
1.200 + }
1.201 + }
1.202 +
1.203 + if (c->param_port == NULL)
1.204 + {
1.205 + BIOerr(BIO_F_CONN_STATE,BIO_R_NO_PORT_SPECIFIED);
1.206 + ERR_add_error_data(2,"host=",c->param_hostname);
1.207 + goto exit_loop;
1.208 + }
1.209 + c->state=BIO_CONN_S_GET_IP;
1.210 + break;
1.211 +
1.212 + case BIO_CONN_S_GET_IP:
1.213 + if (BIO_get_host_ip(c->param_hostname,&(c->ip[0])) <= 0)
1.214 + goto exit_loop;
1.215 + c->state=BIO_CONN_S_GET_PORT;
1.216 + break;
1.217 +
1.218 + case BIO_CONN_S_GET_PORT:
1.219 + if (c->param_port == NULL)
1.220 + {
1.221 + /* abort(); */
1.222 + goto exit_loop;
1.223 + }
1.224 + else if (BIO_get_port(c->param_port,&c->port) <= 0)
1.225 + goto exit_loop;
1.226 + c->state=BIO_CONN_S_CREATE_SOCKET;
1.227 + break;
1.228 +
1.229 + case BIO_CONN_S_CREATE_SOCKET:
1.230 + /* now setup address */
1.231 + memset((char *)&c->them,0,sizeof(c->them));
1.232 + c->them.sin_family=AF_INET;
1.233 + c->them.sin_port=htons((unsigned short)c->port);
1.234 + l=(unsigned long)
1.235 + ((unsigned long)c->ip[0]<<24L)|
1.236 + ((unsigned long)c->ip[1]<<16L)|
1.237 + ((unsigned long)c->ip[2]<< 8L)|
1.238 + ((unsigned long)c->ip[3]);
1.239 + c->them.sin_addr.s_addr=htonl(l);
1.240 + c->state=BIO_CONN_S_CREATE_SOCKET;
1.241 +
1.242 + ret=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
1.243 + if (ret == INVALID_SOCKET)
1.244 + {
1.245 + SYSerr(SYS_F_SOCKET,get_last_socket_error());
1.246 + ERR_add_error_data(4,"host=",c->param_hostname,
1.247 + ":",c->param_port);
1.248 + BIOerr(BIO_F_CONN_STATE,BIO_R_UNABLE_TO_CREATE_SOCKET);
1.249 + goto exit_loop;
1.250 + }
1.251 + b->num=ret;
1.252 + c->state=BIO_CONN_S_NBIO;
1.253 + break;
1.254 +
1.255 + case BIO_CONN_S_NBIO:
1.256 + if (c->nbio)
1.257 + {
1.258 + if (!BIO_socket_nbio(b->num,1))
1.259 + {
1.260 + BIOerr(BIO_F_CONN_STATE,BIO_R_ERROR_SETTING_NBIO);
1.261 + ERR_add_error_data(4,"host=",
1.262 + c->param_hostname,
1.263 + ":",c->param_port);
1.264 + goto exit_loop;
1.265 + }
1.266 + }
1.267 + c->state=BIO_CONN_S_CONNECT;
1.268 +
1.269 +#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
1.270 + i=1;
1.271 + i=setsockopt(b->num,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
1.272 + if (i < 0)
1.273 + {
1.274 + SYSerr(SYS_F_SOCKET,get_last_socket_error());
1.275 + ERR_add_error_data(4,"host=",c->param_hostname,
1.276 + ":",c->param_port);
1.277 + BIOerr(BIO_F_CONN_STATE,BIO_R_KEEPALIVE);
1.278 + goto exit_loop;
1.279 + }
1.280 +#endif
1.281 + break;
1.282 +
1.283 + case BIO_CONN_S_CONNECT:
1.284 + BIO_clear_retry_flags(b);
1.285 + ret=connect(b->num,
1.286 + (struct sockaddr *)&c->them,
1.287 + sizeof(c->them));
1.288 + b->retry_reason=0;
1.289 + if (ret < 0)
1.290 + {
1.291 + if (BIO_sock_should_retry(ret))
1.292 + {
1.293 + BIO_set_retry_special(b);
1.294 + c->state=BIO_CONN_S_BLOCKED_CONNECT;
1.295 + b->retry_reason=BIO_RR_CONNECT;
1.296 + }
1.297 + else
1.298 + {
1.299 + SYSerr(SYS_F_CONNECT,get_last_socket_error());
1.300 + ERR_add_error_data(4,"host=",
1.301 + c->param_hostname,
1.302 + ":",c->param_port);
1.303 + BIOerr(BIO_F_CONN_STATE,BIO_R_CONNECT_ERROR);
1.304 + }
1.305 + goto exit_loop;
1.306 + }
1.307 + else
1.308 + c->state=BIO_CONN_S_OK;
1.309 + break;
1.310 +
1.311 + case BIO_CONN_S_BLOCKED_CONNECT:
1.312 + i=BIO_sock_error(b->num);
1.313 + if (i)
1.314 + {
1.315 + BIO_clear_retry_flags(b);
1.316 + SYSerr(SYS_F_CONNECT,i);
1.317 + ERR_add_error_data(4,"host=",
1.318 + c->param_hostname,
1.319 + ":",c->param_port);
1.320 + BIOerr(BIO_F_CONN_STATE,BIO_R_NBIO_CONNECT_ERROR);
1.321 + ret=0;
1.322 + goto exit_loop;
1.323 + }
1.324 + else
1.325 + c->state=BIO_CONN_S_OK;
1.326 + break;
1.327 +
1.328 + case BIO_CONN_S_OK:
1.329 + ret=1;
1.330 + goto exit_loop;
1.331 + default:
1.332 + /* abort(); */
1.333 + goto exit_loop;
1.334 + }
1.335 +
1.336 + if (cb != NULL)
1.337 + {
1.338 + if (!(ret=cb((BIO *)b,c->state,ret)))
1.339 + goto end;
1.340 + }
1.341 + }
1.342 +
1.343 + /* Loop does not exit */
1.344 +exit_loop:
1.345 + if (cb != NULL)
1.346 + ret=cb((BIO *)b,c->state,ret);
1.347 +end:
1.348 + return(ret);
1.349 + }
1.350 +
1.351 +EXPORT_C BIO_CONNECT *BIO_CONNECT_new(void)
1.352 + {
1.353 + BIO_CONNECT *ret;
1.354 +
1.355 + if ((ret=(BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL)
1.356 + return(NULL);
1.357 + ret->state=BIO_CONN_S_BEFORE;
1.358 + ret->param_hostname=NULL;
1.359 + ret->param_port=NULL;
1.360 + ret->info_callback=NULL;
1.361 + ret->nbio=0;
1.362 + ret->ip[0]=0;
1.363 + ret->ip[1]=0;
1.364 + ret->ip[2]=0;
1.365 + ret->ip[3]=0;
1.366 + ret->port=0;
1.367 + memset((char *)&ret->them,0,sizeof(ret->them));
1.368 + return(ret);
1.369 + }
1.370 +
1.371 +EXPORT_C void BIO_CONNECT_free(BIO_CONNECT *a)
1.372 + {
1.373 + if(a == NULL)
1.374 + return;
1.375 +
1.376 + if (a->param_hostname != NULL)
1.377 + OPENSSL_free(a->param_hostname);
1.378 + if (a->param_port != NULL)
1.379 + OPENSSL_free(a->param_port);
1.380 + OPENSSL_free(a);
1.381 + }
1.382 +
1.383 +EXPORT_C BIO_METHOD *BIO_s_connect(void)
1.384 + {
1.385 + return(&methods_connectp);
1.386 + }
1.387 +
1.388 +static int conn_new(BIO *bi)
1.389 + {
1.390 + bi->init=0;
1.391 + bi->num=INVALID_SOCKET;
1.392 + bi->flags=0;
1.393 + if ((bi->ptr=(char *)BIO_CONNECT_new()) == NULL)
1.394 + return(0);
1.395 + else
1.396 + return(1);
1.397 + }
1.398 +
1.399 +static void conn_close_socket(BIO *bio)
1.400 + {
1.401 + BIO_CONNECT *c;
1.402 +
1.403 + c=(BIO_CONNECT *)bio->ptr;
1.404 + if (bio->num != INVALID_SOCKET)
1.405 + {
1.406 + /* Only do a shutdown if things were established */
1.407 + if (c->state == BIO_CONN_S_OK)
1.408 + shutdown(bio->num,2);
1.409 + closesocket(bio->num);
1.410 + bio->num=INVALID_SOCKET;
1.411 + }
1.412 + }
1.413 +
1.414 +static int conn_free(BIO *a)
1.415 + {
1.416 + BIO_CONNECT *data;
1.417 +
1.418 + if (a == NULL) return(0);
1.419 + data=(BIO_CONNECT *)a->ptr;
1.420 +
1.421 + if (a->shutdown)
1.422 + {
1.423 + conn_close_socket(a);
1.424 + BIO_CONNECT_free(data);
1.425 + a->ptr=NULL;
1.426 + a->flags=0;
1.427 + a->init=0;
1.428 + }
1.429 + return(1);
1.430 + }
1.431 +
1.432 +static int conn_read(BIO *b, char *out, int outl)
1.433 + {
1.434 + int ret=0;
1.435 + BIO_CONNECT *data;
1.436 +
1.437 + data=(BIO_CONNECT *)b->ptr;
1.438 + if (data->state != BIO_CONN_S_OK)
1.439 + {
1.440 + ret=conn_state(b,data);
1.441 + if (ret <= 0)
1.442 + return(ret);
1.443 + }
1.444 +
1.445 + if (out != NULL)
1.446 + {
1.447 + clear_socket_error();
1.448 + ret=readsocket(b->num,out,outl);
1.449 + BIO_clear_retry_flags(b);
1.450 + if (ret <= 0)
1.451 + {
1.452 + if (BIO_sock_should_retry(ret))
1.453 + BIO_set_retry_read(b);
1.454 + }
1.455 + }
1.456 + return(ret);
1.457 + }
1.458 +
1.459 +static int conn_write(BIO *b, const char *in, int inl)
1.460 + {
1.461 + int ret;
1.462 + BIO_CONNECT *data;
1.463 +
1.464 + data=(BIO_CONNECT *)b->ptr;
1.465 + if (data->state != BIO_CONN_S_OK)
1.466 + {
1.467 + ret=conn_state(b,data);
1.468 + if (ret <= 0) return(ret);
1.469 + }
1.470 +
1.471 + clear_socket_error();
1.472 + ret=writesocket(b->num,in,inl);
1.473 + BIO_clear_retry_flags(b);
1.474 + if (ret <= 0)
1.475 + {
1.476 + if (BIO_sock_should_retry(ret))
1.477 + BIO_set_retry_write(b);
1.478 + }
1.479 + return(ret);
1.480 + }
1.481 +
1.482 +static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
1.483 + {
1.484 + BIO *dbio;
1.485 + int *ip;
1.486 + const char **pptr;
1.487 + long ret=1;
1.488 + BIO_CONNECT *data;
1.489 +
1.490 + data=(BIO_CONNECT *)b->ptr;
1.491 +
1.492 + switch (cmd)
1.493 + {
1.494 + case BIO_CTRL_RESET:
1.495 + ret=0;
1.496 + data->state=BIO_CONN_S_BEFORE;
1.497 + conn_close_socket(b);
1.498 + b->flags=0;
1.499 + break;
1.500 + case BIO_C_DO_STATE_MACHINE:
1.501 + /* use this one to start the connection */
1.502 + if (data->state != BIO_CONN_S_OK)
1.503 + ret=(long)conn_state(b,data);
1.504 + else
1.505 + ret=1;
1.506 + break;
1.507 + case BIO_C_GET_CONNECT:
1.508 + if (ptr != NULL)
1.509 + {
1.510 + pptr=(const char **)ptr;
1.511 + if (num == 0)
1.512 + {
1.513 + *pptr=data->param_hostname;
1.514 +
1.515 + }
1.516 + else if (num == 1)
1.517 + {
1.518 + *pptr=data->param_port;
1.519 + }
1.520 + else if (num == 2)
1.521 + {
1.522 + *pptr= (char *)&(data->ip[0]);
1.523 + }
1.524 + else if (num == 3)
1.525 + {
1.526 + *((int *)ptr)=data->port;
1.527 + }
1.528 + if ((!b->init) || (ptr == NULL))
1.529 + *pptr="not initialized";
1.530 + ret=1;
1.531 + }
1.532 + break;
1.533 + case BIO_C_SET_CONNECT:
1.534 + if (ptr != NULL)
1.535 + {
1.536 + b->init=1;
1.537 + if (num == 0)
1.538 + {
1.539 + if (data->param_hostname != NULL)
1.540 + OPENSSL_free(data->param_hostname);
1.541 + data->param_hostname=BUF_strdup(ptr);
1.542 + }
1.543 + else if (num == 1)
1.544 + {
1.545 + if (data->param_port != NULL)
1.546 + OPENSSL_free(data->param_port);
1.547 + data->param_port=BUF_strdup(ptr);
1.548 + }
1.549 + else if (num == 2)
1.550 + {
1.551 + char buf[16];
1.552 + unsigned char *p = ptr;
1.553 +
1.554 + BIO_snprintf(buf,sizeof buf,"%d.%d.%d.%d",
1.555 + p[0],p[1],p[2],p[3]);
1.556 + if (data->param_hostname != NULL)
1.557 + OPENSSL_free(data->param_hostname);
1.558 + data->param_hostname=BUF_strdup(buf);
1.559 + memcpy(&(data->ip[0]),ptr,4);
1.560 + }
1.561 + else if (num == 3)
1.562 + {
1.563 + char buf[DECIMAL_SIZE(int)+1];
1.564 +
1.565 + BIO_snprintf(buf,sizeof buf,"%d",*(int *)ptr);
1.566 + if (data->param_port != NULL)
1.567 + OPENSSL_free(data->param_port);
1.568 + data->param_port=BUF_strdup(buf);
1.569 + data->port= *(int *)ptr;
1.570 + }
1.571 + }
1.572 + break;
1.573 + case BIO_C_SET_NBIO:
1.574 + data->nbio=(int)num;
1.575 + break;
1.576 + case BIO_C_GET_FD:
1.577 + if (b->init)
1.578 + {
1.579 + ip=(int *)ptr;
1.580 + if (ip != NULL)
1.581 + *ip=b->num;
1.582 + ret=b->num;
1.583 + }
1.584 + else
1.585 + ret= -1;
1.586 + break;
1.587 + case BIO_CTRL_GET_CLOSE:
1.588 + ret=b->shutdown;
1.589 + break;
1.590 + case BIO_CTRL_SET_CLOSE:
1.591 + b->shutdown=(int)num;
1.592 + break;
1.593 + case BIO_CTRL_PENDING:
1.594 + case BIO_CTRL_WPENDING:
1.595 + ret=0;
1.596 + break;
1.597 + case BIO_CTRL_FLUSH:
1.598 + break;
1.599 + case BIO_CTRL_DUP:
1.600 + {
1.601 + dbio=(BIO *)ptr;
1.602 + if (data->param_port)
1.603 + BIO_set_conn_port(dbio,data->param_port);
1.604 + if (data->param_hostname)
1.605 + BIO_set_conn_hostname(dbio,data->param_hostname);
1.606 + BIO_set_nbio(dbio,data->nbio);
1.607 + /* FIXME: the cast of the function seems unlikely to be a good idea */
1.608 + (void)BIO_set_info_callback(dbio,(bio_info_cb *)data->info_callback);
1.609 + }
1.610 + break;
1.611 + case BIO_CTRL_SET_CALLBACK:
1.612 + {
1.613 +#if 0 /* FIXME: Should this be used? -- Richard Levitte */
1.614 + BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1.615 + ret = -1;
1.616 +#else
1.617 + ret=0;
1.618 +#endif
1.619 + }
1.620 + break;
1.621 + case BIO_CTRL_GET_CALLBACK:
1.622 + {
1.623 + int (**fptr)(const BIO *bio,int state,int xret);
1.624 +
1.625 + fptr=(int (**)(const BIO *bio,int state,int xret))ptr;
1.626 + *fptr=data->info_callback;
1.627 + }
1.628 + break;
1.629 + default:
1.630 + ret=0;
1.631 + break;
1.632 + }
1.633 + return(ret);
1.634 + }
1.635 +
1.636 +static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
1.637 + {
1.638 + long ret=1;
1.639 + BIO_CONNECT *data;
1.640 +
1.641 + data=(BIO_CONNECT *)b->ptr;
1.642 +
1.643 + switch (cmd)
1.644 + {
1.645 + case BIO_CTRL_SET_CALLBACK:
1.646 + {
1.647 + data->info_callback=(int (*)(const struct bio_st *, int, int))fp;
1.648 + }
1.649 + break;
1.650 + default:
1.651 + ret=0;
1.652 + break;
1.653 + }
1.654 + return(ret);
1.655 + }
1.656 +
1.657 +static int conn_puts(BIO *bp, const char *str)
1.658 + {
1.659 + int n,ret;
1.660 +
1.661 + n=strlen(str);
1.662 + ret=conn_write(bp,str,n);
1.663 + return(ret);
1.664 + }
1.665 +
1.666 +EXPORT_C BIO *BIO_new_connect(char *str)
1.667 + {
1.668 + BIO *ret;
1.669 +
1.670 + ret=BIO_new(BIO_s_connect());
1.671 + if (ret == NULL) return(NULL);
1.672 + if (BIO_set_conn_hostname(ret,str))
1.673 + return(ret);
1.674 + else
1.675 + {
1.676 + BIO_free(ret);
1.677 + return(NULL);
1.678 + }
1.679 + }
1.680 +
1.681 +#endif
1.682 +