--- clean/gnutls-1.0.23/libextra/gnutls_openssl.c 2004-08-04 22:36:03.000000000 +0100 +++ gnutls-1.0.23/libextra/gnutls_openssl.c 2005-01-02 19:50:49.000000000 +0000 @@ -31,7 +31,6 @@ static int last_error = 0; - /* Library initialisation functions */ int SSL_library_init(void) @@ -219,12 +218,17 @@ ssl->rfd = (gnutls_transport_ptr)-1; ssl->wfd = (gnutls_transport_ptr)-1; + + ssl->ssl_peek_buffer = NULL; + ssl->ssl_peek_buffer_size = ssl->ssl_peek_avail = 0; return ssl; } void SSL_free(SSL *ssl) { + if (ssl->ssl_peek_buffer) + free(ssl->ssl_peek_buffer); gnutls_certificate_free_credentials(ssl->gnutls_cred); gnutls_deinit(ssl->gnutls_state); free(ssl); @@ -245,6 +249,7 @@ int SSL_set_fd(SSL *ssl, int fd) { gnutls_transport_set_ptr (ssl->gnutls_state, (gnutls_transport_ptr)fd); + ssl->rfd = ssl->wfd = fd; return 1; } @@ -268,6 +273,16 @@ return 1; } +int SSL_get_rfd(SSL *ssl) +{ + return ssl->rfd; +} + +int SSL_get_wfd(SSL *ssl) +{ + return ssl->wfd; +} + void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) { gnutls_transport_set_ptr2 (ssl->gnutls_state, rbio->fd, wbio->fd); @@ -280,6 +295,9 @@ int SSL_pending(SSL *ssl) { + if (ssl->ssl_peek_avail) + return ssl->ssl_peek_avail; + return gnutls_record_check_pending(ssl->gnutls_state); } @@ -430,10 +448,49 @@ return 1; } +int SSL_peek(SSL *ssl, void *buf, int len) +{ + if (len > ssl->ssl_peek_buffer_size) { + ssl->ssl_peek_buffer = realloc (ssl->ssl_peek_buffer, len); + ssl->ssl_peek_buffer_size = len; + } + + if (ssl->ssl_peek_avail == 0) { + + int ret; + + ret = gnutls_record_recv(ssl->gnutls_state, ssl->ssl_peek_buffer, len); + ssl->last_error = ret; + + if (ret > 0) + ssl->ssl_peek_avail += ret; + } + + if (len > ssl->ssl_peek_avail) + len = ssl->ssl_peek_avail; + + memcpy (buf, ssl->ssl_peek_buffer, len); + + return len; +} + int SSL_read(SSL *ssl, void *buf, int len) { int ret; + if (ssl->ssl_peek_avail) { + int n = (ssl->ssl_peek_avail > len) ? len : ssl->ssl_peek_avail; + + memcpy (buf, ssl->ssl_peek_buffer, n); + + if (ssl->ssl_peek_avail > n) + memmove (ssl->ssl_peek_buffer, ssl->ssl_peek_buffer + n, ssl->ssl_peek_avail - n); + + ssl->ssl_peek_avail -= n; + + return n; + } + ret = gnutls_record_recv(ssl->gnutls_state, buf, len); ssl->last_error = ret; --- clean/gnutls-1.0.23/includes/gnutls/openssl.h 2004-08-04 22:36:02.000000000 +0100 +++ gnutls-1.0.23/includes/gnutls/openssl.h 2005-01-02 19:48:35.000000000 +0000 @@ -139,6 +139,10 @@ gnutls_transport_ptr rfd; gnutls_transport_ptr wfd; + + char *ssl_peek_buffer; + size_t ssl_peek_buffer_size; + size_t ssl_peek_avail; } SSL; typedef struct