Skip to content

Commit

Permalink
refactorize interface of Curl_ssl_recv/Curl_ssl_send
Browse files Browse the repository at this point in the history
  • Loading branch information
kdudka committed Apr 4, 2010
1 parent 7425db3 commit ff87111
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 97 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
Kamil Dudka (4 Apr 2010)
- Eliminated a race condition in Curl_resolv_timeout().

- Refactorized interface of Curl_ssl_recv()/Curl_ssl_send().

Daniel Stenberg (1 Apr 2010)
- Matt Wixson found and fixed a bug in the SCP/SFTP area where the code
treated a 0 return code from libssh2 to be the same as EAGAIN while in
Expand Down
33 changes: 17 additions & 16 deletions lib/gtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
Expand Down Expand Up @@ -638,18 +638,21 @@ Curl_gtls_connect(struct connectdata *conn,
}


/* return number of sent (non-SSL) bytes */
/* for documentation see Curl_ssl_send() in sslgen.h */
ssize_t Curl_gtls_send(struct connectdata *conn,
int sockindex,
const void *mem,
size_t len)
size_t len,
int *curlcode)
{
ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);

if(rc < 0 ) {
if(rc == GNUTLS_E_AGAIN)
return 0; /* EWOULDBLOCK equivalent */
rc = -1; /* generic error code for send failure */
*curlcode = (rc == GNUTLS_E_AGAIN)
? /* EWOULDBLOCK */ -1
: CURLE_SEND_ERROR;

rc = -1;
}

return rc;
Expand Down Expand Up @@ -748,22 +751,18 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
return retval;
}

/*
* If the read would block we return -1 and set 'wouldblock' to TRUE.
* Otherwise we return the amount of data read. Other errors should return -1
* and set 'wouldblock' to FALSE.
*/
/* for documentation see Curl_ssl_recv() in sslgen.h */
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
bool *wouldblock)
int *curlcode)
{
ssize_t ret;

ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
*wouldblock = TRUE;
*curlcode = -1;
return -1;
}

Expand All @@ -773,20 +772,22 @@ ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
CURLcode rc = handshake(conn, conn->ssl[num].session, num, FALSE);
if(rc)
/* handshake() writes error message on its own */
return rc;
*wouldblock = TRUE; /* then return as if this was a wouldblock */
*curlcode = rc;
else
*curlcode = -1; /* then return as if this was a wouldblock */
return -1;
}

*wouldblock = FALSE;
if(!ret) {
failf(conn->data, "Peer closed the TLS connection");
*curlcode = CURLE_RECV_ERROR;
return -1;
}

if(ret < 0) {
failf(conn->data, "GnuTLS recv error (%d): %s",
(int)ret, gnutls_strerror((int)ret));
*curlcode = CURLE_RECV_ERROR;
return -1;
}

Expand Down
16 changes: 8 additions & 8 deletions lib/gtls.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
Expand Down Expand Up @@ -35,14 +35,14 @@ void Curl_gtls_close_all(struct SessionHandle *data);
/* close a SSL connection */
void Curl_gtls_close(struct connectdata *conn, int sockindex);

/* return number of sent (non-SSL) bytes */
/* for documentation see Curl_ssl_send() in sslgen.h */
ssize_t Curl_gtls_send(struct connectdata *conn, int sockindex,
const void *mem, size_t len);
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
bool *wouldblock);
const void *mem, size_t len, int *curlcode);

/* for documentation see Curl_ssl_recv() in sslgen.h */
ssize_t Curl_gtls_recv(struct connectdata *conn, int num, char *buf,
size_t buffersize, int *curlcode);

void Curl_gtls_session_free(void *ptr);
size_t Curl_gtls_version(char *buffer, size_t size);
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
Expand Down
31 changes: 17 additions & 14 deletions lib/nss.c
Original file line number Diff line number Diff line change
Expand Up @@ -1340,47 +1340,50 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
return curlerr;
}

/* return number of sent (non-SSL) bytes */
/* for documentation see Curl_ssl_send() in sslgen.h */
int Curl_nss_send(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
const void *mem, /* send this data */
size_t len) /* amount to write */
size_t len, /* amount to write */
int *curlcode)
{
int rc;

rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0, -1);

if(rc < 0) {
failf(conn->data, "SSL write: error %d", PR_GetError());
PRInt32 err = PR_GetError();
if(err == PR_WOULD_BLOCK_ERROR)
*curlcode = -1; /* EWOULDBLOCK */
else {
failf(conn->data, "SSL write: error %d", err);
*curlcode = CURLE_SEND_ERROR;
}
return -1;
}
return rc; /* number of bytes */
}

/*
* If the read would block we return -1 and set 'wouldblock' to TRUE.
* Otherwise we return the amount of data read. Other errors should return -1
* and set 'wouldblock' to FALSE.
*/
/* for documentation see Curl_ssl_recv() in sslgen.h */
ssize_t Curl_nss_recv(struct connectdata * conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
bool * wouldblock)
int *curlcode)
{
ssize_t nread;

nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1);
*wouldblock = FALSE;
if(nread < 0) {
/* failed SSL read */
PRInt32 err = PR_GetError();

if(err == PR_WOULD_BLOCK_ERROR) {
*wouldblock = TRUE;
return -1; /* basically EWOULDBLOCK */
if(err == PR_WOULD_BLOCK_ERROR)
*curlcode = -1; /* EWOULDBLOCK */
else {
failf(conn->data, "SSL read: errno %d", err);
*curlcode = CURLE_RECV_ERROR;
}
failf(conn->data, "SSL read: errno %d", err);
return -1;
}
return nread;
Expand Down
10 changes: 7 additions & 3 deletions lib/nssg.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
Expand Down Expand Up @@ -42,15 +42,19 @@ int Curl_nss_close_all(struct SessionHandle *data);
int Curl_nss_init(void);
void Curl_nss_cleanup(void);

/* for documentation see Curl_ssl_send() in sslgen.h */
int Curl_nss_send(struct connectdata *conn,
int sockindex,
const void *mem,
size_t len);
size_t len,
int *curlcode);

/* for documentation see Curl_ssl_recv() in sslgen.h */
ssize_t Curl_nss_recv(struct connectdata *conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
bool *wouldblock);
int *curlcode);

size_t Curl_nss_version(char *buffer, size_t size);
int Curl_nss_check_cxn(struct connectdata *cxn);
Expand Down
34 changes: 25 additions & 9 deletions lib/sendf.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ static ssize_t send_plain(struct connectdata *conn,
/*
* Curl_write() is an internal write function that sends data to the
* server. Works with plain sockets, SCP, SSL or kerberos.
*
* If the write would block (EWOULDBLOCK), we return CURLE_OK and
* (*written == 0). Otherwise we return regular CURLcode value.
*/
CURLcode Curl_write(struct connectdata *conn,
curl_socket_t sockfd,
Expand All @@ -276,11 +279,11 @@ CURLcode Curl_write(struct connectdata *conn,
ssize_t *written)
{
ssize_t bytes_written;
CURLcode retcode;
int curlcode = CURLE_OK;
int num = (sockfd == conn->sock[SECONDARYSOCKET]);

if(conn->ssl[num].state == ssl_connection_complete)
bytes_written = Curl_ssl_send(conn, num, mem, len);
bytes_written = Curl_ssl_send(conn, num, mem, len, &curlcode);
else if(Curl_ssh_enabled(conn, PROT_SCP))
bytes_written = Curl_scp_send(conn, num, mem, len);
else if(Curl_ssh_enabled(conn, PROT_SFTP))
Expand All @@ -291,9 +294,24 @@ CURLcode Curl_write(struct connectdata *conn,
bytes_written = send_plain(conn, num, mem, len);

*written = bytes_written;
retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
if(-1 != bytes_written)
/* we completely ignore the curlcode value when -1 is not returned */
return CURLE_OK;

return retcode;
/* handle EWOULDBLOCK or a send failure */
switch(curlcode) {
case /* EWOULDBLOCK */ -1:
*written = /* EWOULDBLOCK */ 0;
return CURLE_OK;

case CURLE_OK:
/* general send failure */
return CURLE_SEND_ERROR;

default:
/* we got a specific curlcode, forward it */
return (CURLcode)curlcode;
}
}

/*
Expand Down Expand Up @@ -535,13 +553,11 @@ int Curl_read(struct connectdata *conn, /* connection data */
}

if(conn->ssl[num].state == ssl_connection_complete) {
nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket);
int curlcode;
nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket, &curlcode);

if(nread == -1)
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
else if(nread == -2)
/* -2 from Curl_ssl_recv() means a true error, not EWOULDBLOCK */
return CURLE_RECV_ERROR;
return curlcode;
}
else if(Curl_ssh_enabled(conn, (PROT_SCP|PROT_SFTP))) {
if(conn->protocol & PROT_SCP)
Expand Down
36 changes: 10 additions & 26 deletions lib/sslgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
Expand Down Expand Up @@ -408,38 +408,22 @@ struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
return curlssl_engines_list(data);
}

/* return number of sent (non-SSL) bytes; -1 on error */
ssize_t Curl_ssl_send(struct connectdata *conn,
int sockindex,
const void *mem,
size_t len)
size_t len,
int *curlcode)
{
return curlssl_send(conn, sockindex, mem, len);
return curlssl_send(conn, sockindex, mem, len, curlcode);
}

/* return number of received (decrypted) bytes */

/*
* If the read would block (EWOULDBLOCK) we return -1. If an error occurs during
* the read, we return -2. Otherwise we return the count of bytes transfered.
*/
ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
char *mem, /* store read data here */
size_t len) /* max amount to read */
ssize_t Curl_ssl_recv(struct connectdata *conn,
int sockindex,
char *mem,
size_t len,
int *curlcode)
{
ssize_t nread;
bool block = FALSE;

nread = curlssl_recv(conn, sockindex, mem, len, &block);
if(nread == -1) {
if(!block)
return -2; /* this is a true error, not EWOULDBLOCK */
else
return -1; /* EWOULDBLOCK */
}

return nread;
return curlssl_recv(conn, sockindex, mem, len, curlcode);
}


Expand Down
27 changes: 21 additions & 6 deletions lib/sslgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2008, 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
Expand Down Expand Up @@ -44,14 +44,29 @@ CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
/* Sets engine as default for all SSL operations */
CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data);
ssize_t Curl_ssl_send(struct connectdata *conn,
int sockindex,
const void *mem,
size_t len);

/* If the write would block (EWOULDBLOCK) or fail, we we return -1.
* The error or -1 (for EWOULDBLOCK) is then stored in *curlcode.
* Otherwise we return the count of (non-SSL) bytes transfered.
*/
ssize_t Curl_ssl_send(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
const void *mem, /* data to write */
size_t len, /* max amount to write */
int *curlcode); /* error to return,
-1 means EWOULDBLOCK */

/* If the read would block (EWOULDBLOCK) or fail, we we return -1.
* The error or -1 (for EWOULDBLOCK) is then stored in *curlcode.
* Otherwise we return the count of (non-SSL) bytes transfered.
*/
ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
char *mem, /* store read data here */
size_t len); /* max amount to read */
size_t len, /* max amount to read */
int *curlcode); /* error to return,
-1 means EWOULDBLOCK */

/* init the SSL session ID cache */
CURLcode Curl_ssl_initsessions(struct SessionHandle *, long);
size_t Curl_ssl_version(char *buffer, size_t size);
Expand Down
Loading

0 comments on commit ff87111

Please sign in to comment.