|
11 | 11 | * |
12 | 12 | * |
13 | 13 | * IDENTIFICATION |
14 | | - * $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.87 2008/12/03 20:04:26 mha Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.88 2008/12/14 19:39:37 mha Exp $ |
15 | 15 | * |
16 | 16 | * Since the server static private key ($DataDir/server.key) |
17 | 17 | * will normally be stored unencrypted so that the database |
@@ -394,45 +394,71 @@ secure_write(Port *port, void *ptr, size_t len) |
394 | 394 | #ifdefUSE_SSL |
395 | 395 |
|
396 | 396 | /* |
397 | | - * Private substitute BIO: this wraps the SSL library's standard socket BIO |
398 | | - * so that we can enable and disable interrupts just while calling recv(). |
399 | | - * We cannot have interrupts occurring while the bulk of openssl runs, |
400 | | - * because it uses malloc() and possibly other non-reentrant libc facilities. |
| 397 | + * Private substitute BIO: this does the sending and receiving using send() and |
| 398 | + * recv() instead. This is so that we can enable and disable interrupts |
| 399 | + * just while calling recv(). We cannot have interrupts occurring while |
| 400 | + * the bulk of openssl runs, because it uses malloc() and possibly other |
| 401 | + * non-reentrant libc facilities. We also need to call send() and recv() |
| 402 | + * directly so it gets passed through the socket/signals layer on Win32. |
| 403 | + * |
| 404 | + * They are closely modelled on the original socket implementations in OpenSSL. |
401 | 405 | * |
402 | | - * As of openssl 0.9.7, we can use the reasonably clean method of interposing |
403 | | - * a wrapper around the standard socket BIO's sock_read() method. This relies |
404 | | - * on the fact that sock_read() doesn't call anything non-reentrant, in fact |
405 | | - * not much of anything at all except recv(). If this ever changes we'd |
406 | | - * probably need to duplicate the code of sock_read() in order to push the |
407 | | - * interrupt enable/disable down yet another level. |
408 | 406 | */ |
409 | 407 |
|
410 | 408 | staticboolmy_bio_initialized= false; |
411 | 409 | staticBIO_METHODmy_bio_methods; |
412 | | -staticint(*std_sock_read) (BIO*h,char*buf,intsize); |
413 | 410 |
|
414 | 411 | staticint |
415 | 412 | my_sock_read(BIO*h,char*buf,intsize) |
416 | 413 | { |
417 | | -intres; |
| 414 | +intres=0; |
418 | 415 |
|
419 | 416 | prepare_for_client_read(); |
420 | 417 |
|
421 | | -res=std_sock_read(h,buf,size); |
| 418 | +if (buf!=NULL) |
| 419 | +{ |
| 420 | +res=recv(h->num,buf,size,0); |
| 421 | +BIO_clear_retry_flags(h); |
| 422 | +if (res <=0) |
| 423 | +{ |
| 424 | +/* If we were interrupted, tell caller to retry */ |
| 425 | +if (errno==EINTR) |
| 426 | +{ |
| 427 | +BIO_set_retry_read(h); |
| 428 | +} |
| 429 | +} |
| 430 | +} |
422 | 431 |
|
423 | 432 | client_read_ended(); |
424 | 433 |
|
425 | 434 | returnres; |
426 | 435 | } |
427 | 436 |
|
| 437 | +staticint |
| 438 | +my_sock_write(BIO*h,constchar*buf,intsize) |
| 439 | +{ |
| 440 | +intres=0; |
| 441 | + |
| 442 | +res=send(h->num,buf,size,0); |
| 443 | +if (res <=0) |
| 444 | +{ |
| 445 | +if (errno==EINTR) |
| 446 | +{ |
| 447 | +BIO_set_retry_write(h); |
| 448 | +} |
| 449 | +} |
| 450 | + |
| 451 | +returnres; |
| 452 | +} |
| 453 | + |
428 | 454 | staticBIO_METHOD* |
429 | 455 | my_BIO_s_socket(void) |
430 | 456 | { |
431 | 457 | if (!my_bio_initialized) |
432 | 458 | { |
433 | 459 | memcpy(&my_bio_methods,BIO_s_socket(),sizeof(BIO_METHOD)); |
434 | | -std_sock_read=my_bio_methods.bread; |
435 | 460 | my_bio_methods.bread=my_sock_read; |
| 461 | +my_bio_methods.bwrite=my_sock_write; |
436 | 462 | my_bio_initialized= true; |
437 | 463 | } |
438 | 464 | return&my_bio_methods; |
|