diff options
Diffstat (limited to 'src/lib/libcrypto/bio/b_sock.c')
| -rw-r--r-- | src/lib/libcrypto/bio/b_sock.c | 386 |
1 files changed, 247 insertions, 139 deletions
diff --git a/src/lib/libcrypto/bio/b_sock.c b/src/lib/libcrypto/bio/b_sock.c index a45909527c..dcaef68ea7 100644 --- a/src/lib/libcrypto/bio/b_sock.c +++ b/src/lib/libcrypto/bio/b_sock.c | |||
| @@ -56,32 +56,30 @@ | |||
| 56 | * [including the GNU Public Licence.] | 56 | * [including the GNU Public Licence.] |
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | #ifndef NO_SOCK | 59 | #ifndef OPENSSL_NO_SOCK |
| 60 | 60 | ||
| 61 | #include <stdio.h> | 61 | #include <stdio.h> |
| 62 | #include <stdlib.h> | 62 | #include <stdlib.h> |
| 63 | #include <errno.h> | 63 | #include <errno.h> |
| 64 | #define USE_SOCKETS | 64 | #define USE_SOCKETS |
| 65 | #include "cryptlib.h" | 65 | #include "cryptlib.h" |
| 66 | #include "bio.h" | 66 | #include <openssl/bio.h> |
| 67 | 67 | ||
| 68 | /* BIOerr(BIO_F_WSASTARTUP,BIO_R_WSASTARTUP ); */ | 68 | #ifdef OPENSSL_SYS_WIN16 |
| 69 | |||
| 70 | #ifdef WIN16 | ||
| 71 | #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ | 69 | #define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ |
| 72 | #else | 70 | #else |
| 73 | #define SOCKET_PROTOCOL IPPROTO_TCP | 71 | #define SOCKET_PROTOCOL IPPROTO_TCP |
| 74 | #endif | 72 | #endif |
| 75 | 73 | ||
| 76 | #ifdef SO_MAXCONN | 74 | #ifdef SO_MAXCONN |
| 77 | #define MAX_LISTEN SOMAXCONN | ||
| 78 | #elif defined(SO_MAXCONN) | ||
| 79 | #define MAX_LISTEN SO_MAXCONN | 75 | #define MAX_LISTEN SO_MAXCONN |
| 76 | #elif defined(SOMAXCONN) | ||
| 77 | #define MAX_LISTEN SOMAXCONN | ||
| 80 | #else | 78 | #else |
| 81 | #define MAX_LISTEN 32 | 79 | #define MAX_LISTEN 32 |
| 82 | #endif | 80 | #endif |
| 83 | 81 | ||
| 84 | #ifdef WINDOWS | 82 | #ifdef OPENSSL_SYS_WINDOWS |
| 85 | static int wsa_init_done=0; | 83 | static int wsa_init_done=0; |
| 86 | #endif | 84 | #endif |
| 87 | 85 | ||
| @@ -96,59 +94,67 @@ static struct ghbn_cache_st | |||
| 96 | unsigned long order; | 94 | unsigned long order; |
| 97 | } ghbn_cache[GHBN_NUM]; | 95 | } ghbn_cache[GHBN_NUM]; |
| 98 | 96 | ||
| 99 | #ifndef NOPROTO | 97 | static int get_ip(const char *str,unsigned char *ip); |
| 100 | static int get_ip(char *str,unsigned char *ip); | 98 | #if 0 |
| 101 | static void ghbn_free(struct hostent *a); | 99 | static void ghbn_free(struct hostent *a); |
| 102 | static struct hostent *ghbn_dup(struct hostent *a); | 100 | static struct hostent *ghbn_dup(struct hostent *a); |
| 103 | #else | ||
| 104 | static int get_ip(); | ||
| 105 | static void ghbn_free(); | ||
| 106 | static struct hostent *ghbn_dup(); | ||
| 107 | #endif | 101 | #endif |
| 108 | 102 | int BIO_get_host_ip(const char *str, unsigned char *ip) | |
| 109 | int BIO_get_host_ip(str,ip) | ||
| 110 | char *str; | ||
| 111 | unsigned char *ip; | ||
| 112 | { | 103 | { |
| 113 | int i; | 104 | int i; |
| 105 | int err = 1; | ||
| 106 | int locked = 0; | ||
| 114 | struct hostent *he; | 107 | struct hostent *he; |
| 115 | 108 | ||
| 116 | i=get_ip(str,ip); | 109 | i=get_ip(str,ip); |
| 117 | if (i > 0) return(1); | ||
| 118 | if (i < 0) | 110 | if (i < 0) |
| 119 | { | 111 | { |
| 120 | BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS); | 112 | BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_INVALID_IP_ADDRESS); |
| 121 | ERR_add_error_data(2,"host=",str); | 113 | goto err; |
| 122 | return(0); | ||
| 123 | } | 114 | } |
| 124 | else | ||
| 125 | { /* do a gethostbyname */ | ||
| 126 | if (!BIO_sock_init()) return(0); | ||
| 127 | 115 | ||
| 128 | he=BIO_gethostbyname(str); | 116 | /* At this point, we have something that is most probably correct |
| 129 | if (he == NULL) | 117 | in some way, so let's init the socket. */ |
| 130 | { | 118 | if (BIO_sock_init() != 1) |
| 131 | BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP); | 119 | return 0; /* don't generate another error code here */ |
| 132 | ERR_add_error_data(2,"host=",str); | ||
| 133 | return(0); | ||
| 134 | } | ||
| 135 | 120 | ||
| 136 | /* cast to short because of win16 winsock definition */ | 121 | /* If the string actually contained an IP address, we need not do |
| 137 | if ((short)he->h_addrtype != AF_INET) | 122 | anything more */ |
| 138 | { | 123 | if (i > 0) return(1); |
| 139 | BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); | 124 | |
| 140 | ERR_add_error_data(2,"host=",str); | 125 | /* do a gethostbyname */ |
| 141 | return(0); | 126 | CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); |
| 142 | } | 127 | locked = 1; |
| 143 | for (i=0; i<4; i++) | 128 | he=BIO_gethostbyname(str); |
| 144 | ip[i]=he->h_addr_list[0][i]; | 129 | if (he == NULL) |
| 130 | { | ||
| 131 | BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_BAD_HOSTNAME_LOOKUP); | ||
| 132 | goto err; | ||
| 145 | } | 133 | } |
| 146 | return(1); | 134 | |
| 135 | /* cast to short because of win16 winsock definition */ | ||
| 136 | if ((short)he->h_addrtype != AF_INET) | ||
| 137 | { | ||
| 138 | BIOerr(BIO_F_BIO_GET_HOST_IP,BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); | ||
| 139 | goto err; | ||
| 140 | } | ||
| 141 | for (i=0; i<4; i++) | ||
| 142 | ip[i]=he->h_addr_list[0][i]; | ||
| 143 | err = 0; | ||
| 144 | |||
| 145 | err: | ||
| 146 | if (locked) | ||
| 147 | CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); | ||
| 148 | if (err) | ||
| 149 | { | ||
| 150 | ERR_add_error_data(2,"host=",str); | ||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | else | ||
| 154 | return 1; | ||
| 147 | } | 155 | } |
| 148 | 156 | ||
| 149 | int BIO_get_port(str,port_ptr) | 157 | int BIO_get_port(const char *str, unsigned short *port_ptr) |
| 150 | char *str; | ||
| 151 | short *port_ptr; | ||
| 152 | { | 158 | { |
| 153 | int i; | 159 | int i; |
| 154 | struct servent *s; | 160 | struct servent *s; |
| @@ -163,8 +169,19 @@ short *port_ptr; | |||
| 163 | *port_ptr=(unsigned short)i; | 169 | *port_ptr=(unsigned short)i; |
| 164 | else | 170 | else |
| 165 | { | 171 | { |
| 166 | s=getservbyname(str,"tcp"); | 172 | CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); |
| 167 | if (s == NULL) | 173 | /* Note: under VMS with SOCKETSHR, it seems like the first |
| 174 | * parameter is 'char *', instead of 'const char *' | ||
| 175 | */ | ||
| 176 | s=getservbyname( | ||
| 177 | #ifndef CONST_STRICT | ||
| 178 | (char *) | ||
| 179 | #endif | ||
| 180 | str,"tcp"); | ||
| 181 | if(s != NULL) | ||
| 182 | *port_ptr=ntohs((unsigned short)s->s_port); | ||
| 183 | CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); | ||
| 184 | if(s == NULL) | ||
| 168 | { | 185 | { |
| 169 | if (strcmp(str,"http") == 0) | 186 | if (strcmp(str,"http") == 0) |
| 170 | *port_ptr=80; | 187 | *port_ptr=80; |
| @@ -190,31 +207,30 @@ short *port_ptr; | |||
| 190 | ERR_add_error_data(3,"service='",str,"'"); | 207 | ERR_add_error_data(3,"service='",str,"'"); |
| 191 | return(0); | 208 | return(0); |
| 192 | } | 209 | } |
| 193 | return(1); | ||
| 194 | } | 210 | } |
| 195 | *port_ptr=htons((unsigned short)s->s_port); | ||
| 196 | } | 211 | } |
| 197 | return(1); | 212 | return(1); |
| 198 | } | 213 | } |
| 199 | 214 | ||
| 200 | int BIO_sock_error(sock) | 215 | int BIO_sock_error(int sock) |
| 201 | int sock; | ||
| 202 | { | 216 | { |
| 203 | int j,i,size; | 217 | int j,i; |
| 218 | int size; | ||
| 204 | 219 | ||
| 205 | size=sizeof(int); | 220 | size=sizeof(int); |
| 206 | 221 | /* Note: under Windows the third parameter is of type (char *) | |
| 207 | i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(char *)&j,&size); | 222 | * whereas under other systems it is (void *) if you don't have |
| 223 | * a cast it will choke the compiler: if you do have a cast then | ||
| 224 | * you can either go for (char *) or (void *). | ||
| 225 | */ | ||
| 226 | i=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void *)&j,(void *)&size); | ||
| 208 | if (i < 0) | 227 | if (i < 0) |
| 209 | return(1); | 228 | return(1); |
| 210 | else | 229 | else |
| 211 | return(j); | 230 | return(j); |
| 212 | } | 231 | } |
| 213 | 232 | ||
| 214 | long BIO_ghbn_ctrl(cmd,iarg,parg) | 233 | long BIO_ghbn_ctrl(int cmd, int iarg, char *parg) |
| 215 | int cmd; | ||
| 216 | int iarg; | ||
| 217 | char *parg; | ||
| 218 | { | 234 | { |
| 219 | int i; | 235 | int i; |
| 220 | char **p; | 236 | char **p; |
| @@ -223,13 +239,13 @@ char *parg; | |||
| 223 | { | 239 | { |
| 224 | case BIO_GHBN_CTRL_HITS: | 240 | case BIO_GHBN_CTRL_HITS: |
| 225 | return(BIO_ghbn_hits); | 241 | return(BIO_ghbn_hits); |
| 226 | break; | 242 | /* break; */ |
| 227 | case BIO_GHBN_CTRL_MISSES: | 243 | case BIO_GHBN_CTRL_MISSES: |
| 228 | return(BIO_ghbn_miss); | 244 | return(BIO_ghbn_miss); |
| 229 | break; | 245 | /* break; */ |
| 230 | case BIO_GHBN_CTRL_CACHE_SIZE: | 246 | case BIO_GHBN_CTRL_CACHE_SIZE: |
| 231 | return(GHBN_NUM); | 247 | return(GHBN_NUM); |
| 232 | break; | 248 | /* break; */ |
| 233 | case BIO_GHBN_CTRL_GET_ENTRY: | 249 | case BIO_GHBN_CTRL_GET_ENTRY: |
| 234 | if ((iarg >= 0) && (iarg <GHBN_NUM) && | 250 | if ((iarg >= 0) && (iarg <GHBN_NUM) && |
| 235 | (ghbn_cache[iarg].order > 0)) | 251 | (ghbn_cache[iarg].order > 0)) |
| @@ -241,7 +257,7 @@ char *parg; | |||
| 241 | return(1); | 257 | return(1); |
| 242 | } | 258 | } |
| 243 | return(0); | 259 | return(0); |
| 244 | break; | 260 | /* break; */ |
| 245 | case BIO_GHBN_CTRL_FLUSH: | 261 | case BIO_GHBN_CTRL_FLUSH: |
| 246 | for (i=0; i<GHBN_NUM; i++) | 262 | for (i=0; i<GHBN_NUM; i++) |
| 247 | ghbn_cache[i].order=0; | 263 | ghbn_cache[i].order=0; |
| @@ -252,85 +268,105 @@ char *parg; | |||
| 252 | return(1); | 268 | return(1); |
| 253 | } | 269 | } |
| 254 | 270 | ||
| 255 | static struct hostent *ghbn_dup(a) | 271 | #if 0 |
| 256 | struct hostent *a; | 272 | static struct hostent *ghbn_dup(struct hostent *a) |
| 257 | { | 273 | { |
| 258 | struct hostent *ret; | 274 | struct hostent *ret; |
| 259 | int i,j; | 275 | int i,j; |
| 260 | 276 | ||
| 261 | ret=(struct hostent *)malloc(sizeof(struct hostent)); | 277 | MemCheck_off(); |
| 278 | ret=(struct hostent *)OPENSSL_malloc(sizeof(struct hostent)); | ||
| 262 | if (ret == NULL) return(NULL); | 279 | if (ret == NULL) return(NULL); |
| 263 | memset(ret,0,sizeof(struct hostent)); | 280 | memset(ret,0,sizeof(struct hostent)); |
| 264 | 281 | ||
| 265 | for (i=0; a->h_aliases[i] != NULL; i++) | 282 | for (i=0; a->h_aliases[i] != NULL; i++) |
| 266 | ; | 283 | ; |
| 267 | i++; | 284 | i++; |
| 268 | ret->h_aliases=(char **)malloc(sizeof(char *)*i); | 285 | ret->h_aliases = (char **)OPENSSL_malloc(i*sizeof(char *)); |
| 269 | memset(ret->h_aliases,0,sizeof(char *)*i); | 286 | if (ret->h_aliases == NULL) |
| 270 | if (ret == NULL) goto err; | 287 | goto err; |
| 288 | memset(ret->h_aliases, 0, i*sizeof(char *)); | ||
| 271 | 289 | ||
| 272 | for (i=0; a->h_addr_list[i] != NULL; i++) | 290 | for (i=0; a->h_addr_list[i] != NULL; i++) |
| 273 | ; | 291 | ; |
| 274 | i++; | 292 | i++; |
| 275 | ret->h_addr_list=(char **)malloc(sizeof(char *)*i); | 293 | ret->h_addr_list=(char **)OPENSSL_malloc(i*sizeof(char *)); |
| 276 | memset(ret->h_addr_list,0,sizeof(char *)*i); | 294 | if (ret->h_addr_list == NULL) |
| 277 | if (ret->h_addr_list == NULL) goto err; | 295 | goto err; |
| 296 | memset(ret->h_addr_list, 0, i*sizeof(char *)); | ||
| 278 | 297 | ||
| 279 | j=strlen(a->h_name)+1; | 298 | j=strlen(a->h_name)+1; |
| 280 | if ((ret->h_name=malloc(j)) == NULL) goto err; | 299 | if ((ret->h_name=OPENSSL_malloc(j)) == NULL) goto err; |
| 281 | memcpy((char *)ret->h_name,a->h_name,j); | 300 | memcpy((char *)ret->h_name,a->h_name,j); |
| 282 | for (i=0; a->h_aliases[i] != NULL; i++) | 301 | for (i=0; a->h_aliases[i] != NULL; i++) |
| 283 | { | 302 | { |
| 284 | j=strlen(a->h_aliases[i])+1; | 303 | j=strlen(a->h_aliases[i])+1; |
| 285 | if ((ret->h_aliases[i]=malloc(j)) == NULL) goto err; | 304 | if ((ret->h_aliases[i]=OPENSSL_malloc(j)) == NULL) goto err; |
| 286 | memcpy(ret->h_aliases[i],a->h_aliases[i],j); | 305 | memcpy(ret->h_aliases[i],a->h_aliases[i],j); |
| 287 | } | 306 | } |
| 288 | ret->h_length=a->h_length; | 307 | ret->h_length=a->h_length; |
| 289 | ret->h_addrtype=a->h_addrtype; | 308 | ret->h_addrtype=a->h_addrtype; |
| 290 | for (i=0; a->h_addr_list[i] != NULL; i++) | 309 | for (i=0; a->h_addr_list[i] != NULL; i++) |
| 291 | { | 310 | { |
| 292 | if ((ret->h_addr_list[i]=malloc(a->h_length)) == NULL) | 311 | if ((ret->h_addr_list[i]=OPENSSL_malloc(a->h_length)) == NULL) |
| 293 | goto err; | 312 | goto err; |
| 294 | memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length); | 313 | memcpy(ret->h_addr_list[i],a->h_addr_list[i],a->h_length); |
| 295 | } | 314 | } |
| 296 | return(ret); | 315 | if (0) |
| 316 | { | ||
| 297 | err: | 317 | err: |
| 298 | if (ret != NULL) | 318 | if (ret != NULL) |
| 299 | ghbn_free(ret); | 319 | ghbn_free(ret); |
| 300 | return(NULL); | 320 | ret=NULL; |
| 321 | } | ||
| 322 | MemCheck_on(); | ||
| 323 | return(ret); | ||
| 301 | } | 324 | } |
| 302 | 325 | ||
| 303 | static void ghbn_free(a) | 326 | static void ghbn_free(struct hostent *a) |
| 304 | struct hostent *a; | ||
| 305 | { | 327 | { |
| 306 | int i; | 328 | int i; |
| 307 | 329 | ||
| 330 | if(a == NULL) | ||
| 331 | return; | ||
| 332 | |||
| 308 | if (a->h_aliases != NULL) | 333 | if (a->h_aliases != NULL) |
| 309 | { | 334 | { |
| 310 | for (i=0; a->h_aliases[i] != NULL; i++) | 335 | for (i=0; a->h_aliases[i] != NULL; i++) |
| 311 | free(a->h_aliases[i]); | 336 | OPENSSL_free(a->h_aliases[i]); |
| 312 | free(a->h_aliases); | 337 | OPENSSL_free(a->h_aliases); |
| 313 | } | 338 | } |
| 314 | if (a->h_addr_list != NULL) | 339 | if (a->h_addr_list != NULL) |
| 315 | { | 340 | { |
| 316 | for (i=0; a->h_addr_list[i] != NULL; i++) | 341 | for (i=0; a->h_addr_list[i] != NULL; i++) |
| 317 | free(a->h_addr_list[i]); | 342 | OPENSSL_free(a->h_addr_list[i]); |
| 318 | free(a->h_addr_list); | 343 | OPENSSL_free(a->h_addr_list); |
| 319 | } | 344 | } |
| 320 | if (a->h_name != NULL) free((char *)a->h_name); | 345 | if (a->h_name != NULL) OPENSSL_free(a->h_name); |
| 321 | free(a); | 346 | OPENSSL_free(a); |
| 322 | } | 347 | } |
| 323 | 348 | ||
| 324 | struct hostent *BIO_gethostbyname(name) | 349 | #endif |
| 325 | char *name; | 350 | |
| 351 | struct hostent *BIO_gethostbyname(const char *name) | ||
| 326 | { | 352 | { |
| 353 | #if 1 | ||
| 354 | /* Caching gethostbyname() results forever is wrong, | ||
| 355 | * so we have to let the true gethostbyname() worry about this */ | ||
| 356 | return gethostbyname(name); | ||
| 357 | #else | ||
| 327 | struct hostent *ret; | 358 | struct hostent *ret; |
| 328 | int i,lowi=0,j; | 359 | int i,lowi=0,j; |
| 329 | unsigned long low= (unsigned long)-1; | 360 | unsigned long low= (unsigned long)-1; |
| 330 | 361 | ||
| 331 | /* return(gethostbyname(name)); */ | ||
| 332 | 362 | ||
| 333 | CRYPTO_w_lock(CRYPTO_LOCK_BIO_GETHOSTBYNAME); | 363 | # if 0 |
| 364 | /* It doesn't make sense to use locking here: The function interface | ||
| 365 | * is not thread-safe, because threads can never be sure when | ||
| 366 | * some other thread destroys the data they were given a pointer to. | ||
| 367 | */ | ||
| 368 | CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); | ||
| 369 | # endif | ||
| 334 | j=strlen(name); | 370 | j=strlen(name); |
| 335 | if (j < 128) | 371 | if (j < 128) |
| 336 | { | 372 | { |
| @@ -354,17 +390,39 @@ char *name; | |||
| 354 | if (i == GHBN_NUM) /* no hit*/ | 390 | if (i == GHBN_NUM) /* no hit*/ |
| 355 | { | 391 | { |
| 356 | BIO_ghbn_miss++; | 392 | BIO_ghbn_miss++; |
| 357 | ret=gethostbyname(name); | 393 | /* Note: under VMS with SOCKETSHR, it seems like the first |
| 358 | 394 | * parameter is 'char *', instead of 'const char *' | |
| 359 | if (ret == NULL) return(NULL); | 395 | */ |
| 360 | if (j > 128) return(ret); /* too big to cache */ | 396 | ret=gethostbyname( |
| 397 | # ifndef CONST_STRICT | ||
| 398 | (char *) | ||
| 399 | # endif | ||
| 400 | name); | ||
| 401 | |||
| 402 | if (ret == NULL) | ||
| 403 | goto end; | ||
| 404 | if (j > 128) /* too big to cache */ | ||
| 405 | { | ||
| 406 | # if 0 | ||
| 407 | /* If we were trying to make this function thread-safe (which | ||
| 408 | * is bound to fail), we'd have to give up in this case | ||
| 409 | * (or allocate more memory). */ | ||
| 410 | ret = NULL; | ||
| 411 | # endif | ||
| 412 | goto end; | ||
| 413 | } | ||
| 361 | 414 | ||
| 362 | /* else add to cache */ | 415 | /* else add to cache */ |
| 363 | if (ghbn_cache[lowi].ent != NULL) | 416 | if (ghbn_cache[lowi].ent != NULL) |
| 364 | ghbn_free(ghbn_cache[lowi].ent); | 417 | ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */ |
| 418 | ghbn_cache[lowi].name[0] = '\0'; | ||
| 365 | 419 | ||
| 420 | if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL) | ||
| 421 | { | ||
| 422 | BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE); | ||
| 423 | goto end; | ||
| 424 | } | ||
| 366 | strncpy(ghbn_cache[lowi].name,name,128); | 425 | strncpy(ghbn_cache[lowi].name,name,128); |
| 367 | ghbn_cache[lowi].ent=ghbn_dup(ret); | ||
| 368 | ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits; | 426 | ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits; |
| 369 | } | 427 | } |
| 370 | else | 428 | else |
| @@ -373,13 +431,18 @@ char *name; | |||
| 373 | ret= ghbn_cache[i].ent; | 431 | ret= ghbn_cache[i].ent; |
| 374 | ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits; | 432 | ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits; |
| 375 | } | 433 | } |
| 376 | CRYPTO_w_unlock(CRYPTO_LOCK_BIO_GETHOSTBYNAME); | 434 | end: |
| 435 | # if 0 | ||
| 436 | CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); | ||
| 437 | # endif | ||
| 377 | return(ret); | 438 | return(ret); |
| 439 | #endif | ||
| 378 | } | 440 | } |
| 379 | 441 | ||
| 380 | int BIO_sock_init() | 442 | |
| 443 | int BIO_sock_init(void) | ||
| 381 | { | 444 | { |
| 382 | #ifdef WINDOWS | 445 | #ifdef OPENSSL_SYS_WINDOWS |
| 383 | static struct WSAData wsa_state; | 446 | static struct WSAData wsa_state; |
| 384 | 447 | ||
| 385 | if (!wsa_init_done) | 448 | if (!wsa_init_done) |
| @@ -399,13 +462,13 @@ int BIO_sock_init() | |||
| 399 | return(-1); | 462 | return(-1); |
| 400 | } | 463 | } |
| 401 | } | 464 | } |
| 402 | #endif /* WINDOWS */ | 465 | #endif /* OPENSSL_SYS_WINDOWS */ |
| 403 | return(1); | 466 | return(1); |
| 404 | } | 467 | } |
| 405 | 468 | ||
| 406 | void BIO_sock_cleanup() | 469 | void BIO_sock_cleanup(void) |
| 407 | { | 470 | { |
| 408 | #ifdef WINDOWS | 471 | #ifdef OPENSSL_SYS_WINDOWS |
| 409 | if (wsa_init_done) | 472 | if (wsa_init_done) |
| 410 | { | 473 | { |
| 411 | wsa_init_done=0; | 474 | wsa_init_done=0; |
| @@ -415,10 +478,9 @@ void BIO_sock_cleanup() | |||
| 415 | #endif | 478 | #endif |
| 416 | } | 479 | } |
| 417 | 480 | ||
| 418 | int BIO_socket_ioctl(fd,type,arg) | 481 | #if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000 |
| 419 | int fd; | 482 | |
| 420 | long type; | 483 | int BIO_socket_ioctl(int fd, long type, unsigned long *arg) |
| 421 | unsigned long *arg; | ||
| 422 | { | 484 | { |
| 423 | int i; | 485 | int i; |
| 424 | 486 | ||
| @@ -427,12 +489,11 @@ unsigned long *arg; | |||
| 427 | SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error()); | 489 | SYSerr(SYS_F_IOCTLSOCKET,get_last_socket_error()); |
| 428 | return(i); | 490 | return(i); |
| 429 | } | 491 | } |
| 492 | #endif /* __VMS_VER */ | ||
| 430 | 493 | ||
| 431 | /* The reason I have implemented this instead of using sscanf is because | 494 | /* The reason I have implemented this instead of using sscanf is because |
| 432 | * Visual C 1.52c gives an unresolved external when linking a DLL :-( */ | 495 | * Visual C 1.52c gives an unresolved external when linking a DLL :-( */ |
| 433 | static int get_ip(str,ip) | 496 | static int get_ip(const char *str, unsigned char ip[4]) |
| 434 | char *str; | ||
| 435 | unsigned char ip[4]; | ||
| 436 | { | 497 | { |
| 437 | unsigned int tmp[4]; | 498 | unsigned int tmp[4]; |
| 438 | int num=0,c,ok=0; | 499 | int num=0,c,ok=0; |
| @@ -446,16 +507,16 @@ unsigned char ip[4]; | |||
| 446 | { | 507 | { |
| 447 | ok=1; | 508 | ok=1; |
| 448 | tmp[num]=tmp[num]*10+c-'0'; | 509 | tmp[num]=tmp[num]*10+c-'0'; |
| 449 | if (tmp[num] > 255) return(-1); | 510 | if (tmp[num] > 255) return(0); |
| 450 | } | 511 | } |
| 451 | else if (c == '.') | 512 | else if (c == '.') |
| 452 | { | 513 | { |
| 453 | if (!ok) return(-1); | 514 | if (!ok) return(-1); |
| 454 | if (num == 3) break; | 515 | if (num == 3) return(0); |
| 455 | num++; | 516 | num++; |
| 456 | ok=0; | 517 | ok=0; |
| 457 | } | 518 | } |
| 458 | else if ((num == 3) && ok) | 519 | else if (c == '\0' && (num == 3) && ok) |
| 459 | break; | 520 | break; |
| 460 | else | 521 | else |
| 461 | return(0); | 522 | return(0); |
| @@ -467,18 +528,19 @@ unsigned char ip[4]; | |||
| 467 | return(1); | 528 | return(1); |
| 468 | } | 529 | } |
| 469 | 530 | ||
| 470 | int BIO_get_accept_socket(host) | 531 | int BIO_get_accept_socket(char *host, int bind_mode) |
| 471 | char *host; | ||
| 472 | { | 532 | { |
| 473 | int ret=0; | 533 | int ret=0; |
| 474 | struct sockaddr_in server; | 534 | struct sockaddr_in server,client; |
| 475 | int s= -1; | 535 | int s=INVALID_SOCKET,cs; |
| 476 | unsigned char ip[4]; | 536 | unsigned char ip[4]; |
| 477 | short port; | 537 | unsigned short port; |
| 478 | char *str,*h,*p,*e; | 538 | char *str=NULL,*e; |
| 539 | const char *h,*p; | ||
| 479 | unsigned long l; | 540 | unsigned long l; |
| 541 | int err_num; | ||
| 480 | 542 | ||
| 481 | if (!BIO_sock_init()) return(INVALID_SOCKET); | 543 | if (BIO_sock_init() != 1) return(INVALID_SOCKET); |
| 482 | 544 | ||
| 483 | if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET); | 545 | if ((str=BUF_strdup(host)) == NULL) return(INVALID_SOCKET); |
| 484 | 546 | ||
| @@ -504,25 +566,26 @@ char *host; | |||
| 504 | h="*"; | 566 | h="*"; |
| 505 | } | 567 | } |
| 506 | 568 | ||
| 507 | if (!BIO_get_port(p,&port)) return(INVALID_SOCKET); | 569 | if (!BIO_get_port(p,&port)) goto err; |
| 508 | 570 | ||
| 509 | memset((char *)&server,0,sizeof(server)); | 571 | memset((char *)&server,0,sizeof(server)); |
| 510 | server.sin_family=AF_INET; | 572 | server.sin_family=AF_INET; |
| 511 | server.sin_port=htons((unsigned short)port); | 573 | server.sin_port=htons(port); |
| 512 | 574 | ||
| 513 | if (strcmp(h,"*") == 0) | 575 | if (strcmp(h,"*") == 0) |
| 514 | server.sin_addr.s_addr=INADDR_ANY; | 576 | server.sin_addr.s_addr=INADDR_ANY; |
| 515 | else | 577 | else |
| 516 | { | 578 | { |
| 517 | if (!BIO_get_host_ip(h,&(ip[0]))) return(INVALID_SOCKET); | 579 | if (!BIO_get_host_ip(h,&(ip[0]))) goto err; |
| 518 | l=(unsigned long) | 580 | l=(unsigned long) |
| 519 | ((unsigned long)ip[0]<<24L)| | 581 | ((unsigned long)ip[0]<<24L)| |
| 520 | ((unsigned long)ip[0]<<16L)| | 582 | ((unsigned long)ip[1]<<16L)| |
| 521 | ((unsigned long)ip[0]<< 8L)| | 583 | ((unsigned long)ip[2]<< 8L)| |
| 522 | ((unsigned long)ip[0]); | 584 | ((unsigned long)ip[3]); |
| 523 | server.sin_addr.s_addr=htonl(l); | 585 | server.sin_addr.s_addr=htonl(l); |
| 524 | } | 586 | } |
| 525 | 587 | ||
| 588 | again: | ||
| 526 | s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); | 589 | s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); |
| 527 | if (s == INVALID_SOCKET) | 590 | if (s == INVALID_SOCKET) |
| 528 | { | 591 | { |
| @@ -531,9 +594,45 @@ char *host; | |||
| 531 | BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET); | 594 | BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_CREATE_SOCKET); |
| 532 | goto err; | 595 | goto err; |
| 533 | } | 596 | } |
| 597 | |||
| 598 | #ifdef SO_REUSEADDR | ||
| 599 | if (bind_mode == BIO_BIND_REUSEADDR) | ||
| 600 | { | ||
| 601 | int i=1; | ||
| 602 | |||
| 603 | ret=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&i,sizeof(i)); | ||
| 604 | bind_mode=BIO_BIND_NORMAL; | ||
| 605 | } | ||
| 606 | #endif | ||
| 534 | if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) | 607 | if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) |
| 535 | { | 608 | { |
| 536 | SYSerr(SYS_F_BIND,get_last_socket_error()); | 609 | #ifdef SO_REUSEADDR |
| 610 | err_num=get_last_socket_error(); | ||
| 611 | if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && | ||
| 612 | (err_num == EADDRINUSE)) | ||
| 613 | { | ||
| 614 | memcpy((char *)&client,(char *)&server,sizeof(server)); | ||
| 615 | if (strcmp(h,"*") == 0) | ||
| 616 | client.sin_addr.s_addr=htonl(0x7F000001); | ||
| 617 | cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); | ||
| 618 | if (cs != INVALID_SOCKET) | ||
| 619 | { | ||
| 620 | int ii; | ||
| 621 | ii=connect(cs,(struct sockaddr *)&client, | ||
| 622 | sizeof(client)); | ||
| 623 | closesocket(cs); | ||
| 624 | if (ii == INVALID_SOCKET) | ||
| 625 | { | ||
| 626 | bind_mode=BIO_BIND_REUSEADDR; | ||
| 627 | closesocket(s); | ||
| 628 | goto again; | ||
| 629 | } | ||
| 630 | /* else error */ | ||
| 631 | } | ||
| 632 | /* else error */ | ||
| 633 | } | ||
| 634 | #endif | ||
| 635 | SYSerr(SYS_F_BIND,err_num); | ||
| 537 | ERR_add_error_data(3,"port='",host,"'"); | 636 | ERR_add_error_data(3,"port='",host,"'"); |
| 538 | BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET); | 637 | BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,BIO_R_UNABLE_TO_BIND_SOCKET); |
| 539 | goto err; | 638 | goto err; |
| @@ -547,35 +646,35 @@ char *host; | |||
| 547 | } | 646 | } |
| 548 | ret=1; | 647 | ret=1; |
| 549 | err: | 648 | err: |
| 550 | if (str != NULL) Free(str); | 649 | if (str != NULL) OPENSSL_free(str); |
| 551 | if ((ret == 0) && (s != INVALID_SOCKET)) | 650 | if ((ret == 0) && (s != INVALID_SOCKET)) |
| 552 | { | 651 | { |
| 553 | #ifdef WINDOWS | ||
| 554 | closesocket(s); | 652 | closesocket(s); |
| 555 | #else | ||
| 556 | close(s); | ||
| 557 | #endif | ||
| 558 | s= INVALID_SOCKET; | 653 | s= INVALID_SOCKET; |
| 559 | } | 654 | } |
| 560 | return(s); | 655 | return(s); |
| 561 | } | 656 | } |
| 562 | 657 | ||
| 563 | int BIO_accept(sock,addr) | 658 | int BIO_accept(int sock, char **addr) |
| 564 | int sock; | ||
| 565 | char **addr; | ||
| 566 | { | 659 | { |
| 567 | int ret=INVALID_SOCKET; | 660 | int ret=INVALID_SOCKET; |
| 568 | static struct sockaddr_in from; | 661 | static struct sockaddr_in from; |
| 569 | unsigned long l; | 662 | unsigned long l; |
| 570 | short port; | 663 | unsigned short port; |
| 571 | int len; | 664 | int len; |
| 572 | char *p; | 665 | char *p; |
| 573 | 666 | ||
| 574 | memset((char *)&from,0,sizeof(from)); | 667 | memset((char *)&from,0,sizeof(from)); |
| 575 | len=sizeof(from); | 668 | len=sizeof(from); |
| 576 | ret=accept(sock,(struct sockaddr *)&from,&len); | 669 | /* Note: under VMS with SOCKETSHR the fourth parameter is currently |
| 670 | * of type (int *) whereas under other systems it is (void *) if | ||
| 671 | * you don't have a cast it will choke the compiler: if you do | ||
| 672 | * have a cast then you can either go for (int *) or (void *). | ||
| 673 | */ | ||
| 674 | ret=accept(sock,(struct sockaddr *)&from,(void *)&len); | ||
| 577 | if (ret == INVALID_SOCKET) | 675 | if (ret == INVALID_SOCKET) |
| 578 | { | 676 | { |
| 677 | if(BIO_sock_should_retry(ret)) return -2; | ||
| 579 | SYSerr(SYS_F_ACCEPT,get_last_socket_error()); | 678 | SYSerr(SYS_F_ACCEPT,get_last_socket_error()); |
| 580 | BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR); | 679 | BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR); |
| 581 | goto end; | 680 | goto end; |
| @@ -587,7 +686,7 @@ char **addr; | |||
| 587 | port=ntohs(from.sin_port); | 686 | port=ntohs(from.sin_port); |
| 588 | if (*addr == NULL) | 687 | if (*addr == NULL) |
| 589 | { | 688 | { |
| 590 | if ((p=Malloc(24)) == NULL) | 689 | if ((p=OPENSSL_malloc(24)) == NULL) |
| 591 | { | 690 | { |
| 592 | BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE); | 691 | BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE); |
| 593 | goto end; | 692 | goto end; |
| @@ -604,9 +703,7 @@ end: | |||
| 604 | return(ret); | 703 | return(ret); |
| 605 | } | 704 | } |
| 606 | 705 | ||
| 607 | int BIO_set_tcp_ndelay(s,on) | 706 | int BIO_set_tcp_ndelay(int s, int on) |
| 608 | int s; | ||
| 609 | int on; | ||
| 610 | { | 707 | { |
| 611 | int ret=0; | 708 | int ret=0; |
| 612 | #if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP)) | 709 | #if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP)) |
| @@ -626,3 +723,14 @@ int on; | |||
| 626 | } | 723 | } |
| 627 | #endif | 724 | #endif |
| 628 | 725 | ||
| 726 | int BIO_socket_nbio(int s, int mode) | ||
| 727 | { | ||
| 728 | int ret= -1; | ||
| 729 | unsigned long l; | ||
| 730 | |||
| 731 | l=mode; | ||
| 732 | #ifdef FIONBIO | ||
| 733 | ret=BIO_socket_ioctl(s,FIONBIO,&l); | ||
| 734 | #endif | ||
| 735 | return(ret == 0); | ||
| 736 | } | ||
