diff options
author | Howard Chu <hyc@highlandsun.com> | 2010-05-07 15:05:34 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2010-05-07 15:05:34 +0200 |
commit | d64bd82bdcb169d0647a80f00068cedd761f8163 (patch) | |
tree | 222920db94e7d4ae7df6df1f9a9afd0b78159492 | |
parent | cb6647ce1cfba836203e91057752441302b9c46a (diff) | |
download | curl-d64bd82bdcb169d0647a80f00068cedd761f8163.tar.gz |
sendrecv: split the I/O handling into private handler
Howard Chu brought the bulk work of this patch that properly
moves out the sending and recving of data to the parts of the
code that are properly responsible for the various ways of doing
so.
Daniel Stenberg assisted with polishing a few bits and fixed some
minor flaws in the original patch.
Another upside of this patch is that we now abuse CURLcodes less
with the "magic" -1 return codes and instead use CURLE_AGAIN more
consistently.
-rw-r--r-- | lib/easy.c | 10 | ||||
-rw-r--r-- | lib/gtls.c | 33 | ||||
-rw-r--r-- | lib/gtls.h | 10 | ||||
-rw-r--r-- | lib/http.c | 8 | ||||
-rw-r--r-- | lib/krb4.h | 5 | ||||
-rw-r--r-- | lib/nss.c | 31 | ||||
-rw-r--r-- | lib/nssg.h | 16 | ||||
-rw-r--r-- | lib/pingpong.c | 3 | ||||
-rw-r--r-- | lib/polarssl.c | 33 | ||||
-rw-r--r-- | lib/polarssl.h | 10 | ||||
-rw-r--r-- | lib/qssl.c | 26 | ||||
-rw-r--r-- | lib/qssl.h | 16 | ||||
-rw-r--r-- | lib/security.c | 102 | ||||
-rw-r--r-- | lib/sendf.c | 179 | ||||
-rw-r--r-- | lib/sendf.h | 19 | ||||
-rw-r--r-- | lib/socks.c | 6 | ||||
-rw-r--r-- | lib/ssh.c | 46 | ||||
-rw-r--r-- | lib/ssh.h | 20 | ||||
-rw-r--r-- | lib/sslgen.c | 19 | ||||
-rw-r--r-- | lib/sslgen.h | 22 | ||||
-rw-r--r-- | lib/ssluse.c | 31 | ||||
-rw-r--r-- | lib/ssluse.h | 16 | ||||
-rw-r--r-- | lib/telnet.c | 19 | ||||
-rw-r--r-- | lib/transfer.c | 12 | ||||
-rw-r--r-- | lib/url.c | 3 | ||||
-rw-r--r-- | lib/urldata.h | 17 |
26 files changed, 288 insertions, 424 deletions
diff --git a/lib/easy.c b/lib/easy.c index 53f417fc3..637d99bb0 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -1108,7 +1108,6 @@ CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n) { curl_socket_t sfd; CURLcode ret; - int ret1; ssize_t n1; struct connectdata *c; struct SessionHandle *data = (struct SessionHandle *)curl; @@ -1118,13 +1117,10 @@ CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n) return ret; *n = 0; - ret1 = Curl_read(c, sfd, buffer, buflen, &n1); + ret = Curl_read(c, sfd, buffer, buflen, &n1); - if(ret1 == -1) - return CURLE_AGAIN; - - if(ret1 != CURLE_OK) - return (CURLcode)ret1; + if(ret != CURLE_OK) + return ret; *n = (size_t)n1; diff --git a/lib/gtls.c b/lib/gtls.c index 4f5edaf78..2cb1fae41 100644 --- a/lib/gtls.c +++ b/lib/gtls.c @@ -419,6 +419,9 @@ gtls_connect_step1(struct connectdata *conn, return CURLE_OK; } +static Curl_recv gtls_recv; +static Curl_send gtls_send; + static CURLcode gtls_connect_step3(struct connectdata *conn, int sockindex) @@ -630,6 +633,8 @@ gtls_connect_step3(struct connectdata *conn, infof(data, "\t MAC: %s\n", ptr); conn->ssl[sockindex].state = ssl_connection_complete; + conn->recv = gtls_recv; + conn->send = gtls_send; { /* we always unconditionally get the session id here, as even if we @@ -730,18 +735,17 @@ Curl_gtls_connect(struct connectdata *conn, return CURLE_OK; } -/* 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, - int *curlcode) +static ssize_t gtls_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) { ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len); if(rc < 0 ) { *curlcode = (rc == GNUTLS_E_AGAIN) - ? /* EWOULDBLOCK */ -1 + ? CURLE_AGAIN : CURLE_SEND_ERROR; rc = -1; @@ -843,18 +847,17 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) return retval; } -/* 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 */ - int *curlcode) +static ssize_t gtls_recv(struct connectdata *conn, /* connection data */ + int num, /* socketindex */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + CURLcode *curlcode) { ssize_t ret; ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize); if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { - *curlcode = -1; + *curlcode = CURLE_AGAIN; return -1; } @@ -866,7 +869,7 @@ ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */ /* handshake() writes error message on its own */ *curlcode = rc; else - *curlcode = -1; /* then return as if this was a wouldblock */ + *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */ return -1; } diff --git a/lib/gtls.h b/lib/gtls.h index da3489bc3..51e0af1f5 100644 --- a/lib/gtls.h +++ b/lib/gtls.h @@ -38,14 +38,6 @@ void Curl_gtls_close_all(struct SessionHandle *data); /* close a SSL connection */ void Curl_gtls_close(struct connectdata *conn, int sockindex); -/* 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, 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); @@ -63,8 +55,6 @@ int Curl_gtls_seed(struct SessionHandle *data); #define curlssl_set_engine(x,y) (x=x, y=y, CURLE_FAILED_INIT) #define curlssl_set_engine_default(x) (x=x, CURLE_FAILED_INIT) #define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL) -#define curlssl_send Curl_gtls_send -#define curlssl_recv Curl_gtls_recv #define curlssl_version Curl_gtls_version #define curlssl_check_cxn(x) (x=x, -1) #define curlssl_data_pending(x,y) (x=x, y=y, 0) diff --git a/lib/http.c b/lib/http.c index fc01ee889..d510e6a9e 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1283,7 +1283,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, struct SessionHandle *data=conn->data; struct SingleRequest *k = &data->req; CURLcode result; - int res; long timeout = data->set.timeout?data->set.timeout:PROXY_TIMEOUT; /* in milliseconds */ curl_socket_t tunnelsocket = conn->sock[sockindex]; @@ -1467,11 +1466,10 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, break; default: DEBUGASSERT(ptr+BUFSIZE-nread <= data->state.buffer+BUFSIZE+1); - res = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, &gotbytes); - if(res< 0) - /* EWOULDBLOCK */ + result = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, &gotbytes); + if(result==CURLE_AGAIN) continue; /* go loop yourself */ - else if(res) + else if(result) keepon = FALSE; else if(gotbytes <= 0) { keepon = FALSE; diff --git a/lib/krb4.h b/lib/krb4.h index 81998b5eb..264279378 100644 --- a/lib/krb4.h +++ b/lib/krb4.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, 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 @@ -51,14 +51,11 @@ int Curl_sec_fflush_fd(struct connectdata *conn, int fd); int Curl_sec_fprintf (struct connectdata *, FILE *, const char *, ...); int Curl_sec_getc (struct connectdata *conn, FILE *); int Curl_sec_putc (struct connectdata *conn, int, FILE *); -int Curl_sec_read (struct connectdata *conn, int, void *, int); int Curl_sec_read_msg (struct connectdata *conn, char *, int); int Curl_sec_vfprintf(struct connectdata *, FILE *, const char *, va_list); int Curl_sec_fprintf2(struct connectdata *conn, FILE *f, const char *fmt, ...); int Curl_sec_vfprintf2(struct connectdata *conn, FILE *, const char *, va_list); -ssize_t Curl_sec_send(struct connectdata *conn, int, const char *, int); -int Curl_sec_write(struct connectdata *conn, int, const char *, int); void Curl_sec_end (struct connectdata *); int Curl_sec_login (struct connectdata *); @@ -1010,6 +1010,9 @@ static bool handle_cc_error(PRInt32 err, struct SessionHandle *data) } } +static Curl_recv nss_recv; +static Curl_send nss_send; + CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) { PRInt32 err; @@ -1321,6 +1324,8 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) } connssl->state = ssl_connection_complete; + conn->recv = nss_recv; + conn->send = nss_send; display_conn_info(conn, connssl->handle); @@ -1373,12 +1378,11 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) return curlerr; } -/* 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 */ - int *curlcode) +static ssize_t nss_send(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + const void *mem, /* send this data */ + size_t len, /* amount to write */ + CURLcode *curlcode) { int rc; @@ -1387,7 +1391,7 @@ int Curl_nss_send(struct connectdata *conn, /* connection data */ if(rc < 0) { PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) - *curlcode = -1; /* EWOULDBLOCK */ + *curlcode = CURLE_AGAIN; else if(handle_cc_error(err, conn->data)) *curlcode = CURLE_SSL_CERTPROBLEM; else { @@ -1399,12 +1403,11 @@ int Curl_nss_send(struct connectdata *conn, /* connection data */ return rc; /* number of bytes */ } -/* 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 */ - int *curlcode) +static ssize_t nss_recv(struct connectdata * conn, /* connection data */ + int num, /* socketindex */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + CURLcode *curlcode) { ssize_t nread; @@ -1414,7 +1417,7 @@ ssize_t Curl_nss_recv(struct connectdata * conn, /* connection data */ PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) - *curlcode = -1; /* EWOULDBLOCK */ + *curlcode = CURLE_AGAIN; else if(handle_cc_error(err, conn->data)) *curlcode = CURLE_SSL_CERTPROBLEM; else { diff --git a/lib/nssg.h b/lib/nssg.h index 309c3d6d8..6eaa17858 100644 --- a/lib/nssg.h +++ b/lib/nssg.h @@ -42,20 +42,6 @@ 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, - 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 */ - int *curlcode); - size_t Curl_nss_version(char *buffer, size_t size); int Curl_nss_check_cxn(struct connectdata *cxn); int Curl_nss_seed(struct SessionHandle *data); @@ -74,8 +60,6 @@ int Curl_nss_seed(struct SessionHandle *data); #define curlssl_set_engine(x,y) (x=x, y=y, CURLE_FAILED_INIT) #define curlssl_set_engine_default(x) (x=x, CURLE_FAILED_INIT) #define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL) -#define curlssl_send Curl_nss_send -#define curlssl_recv Curl_nss_recv #define curlssl_version Curl_nss_version #define curlssl_check_cxn(x) Curl_nss_check_cxn(x) #define curlssl_data_pending(x,y) (x=x, y=y, 0) diff --git a/lib/pingpong.c b/lib/pingpong.c index c6b6f2fb8..6172833f8 100644 --- a/lib/pingpong.c +++ b/lib/pingpong.c @@ -340,8 +340,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, #if defined(HAVE_KRB4) || defined(HAVE_GSSAPI) conn->data_prot = prot; #endif - if(res < 0) - /* EWOULDBLOCK */ + if(res == CURLE_AGAIN) return CURLE_OK; /* return */ #ifdef CURL_DOES_CONVERSIONS diff --git a/lib/polarssl.c b/lib/polarssl.c index 95baa1320..0027e31e0 100644 --- a/lib/polarssl.c +++ b/lib/polarssl.c @@ -76,6 +76,9 @@ static void polarssl_debug(void *context, int level, char *line) #else #endif +static Curl_recv polarssl_recv; +static Curl_send polarssl_send; + /* * This function loads all the client/CA certificates and CRLs. Setup the TLS * layer and do all necessary magic. @@ -299,6 +302,8 @@ Curl_polarssl_connect(struct connectdata *conn, } conn->ssl[sockindex].state = ssl_connection_complete; + conn->recv = polarssl_recv; + conn->send = polarssl_send; /* Save the current session data for possible re-use */ { @@ -319,12 +324,11 @@ Curl_polarssl_connect(struct connectdata *conn, return CURLE_OK; } -/* for documentation see Curl_ssl_send() in sslgen.h */ -ssize_t Curl_polarssl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - int *curlcode) +static ssize_t polarssl_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) { int ret = -1; @@ -332,7 +336,8 @@ ssize_t Curl_polarssl_send(struct connectdata *conn, (unsigned char *)mem, len); if(ret < 0) { - *curlcode = (ret == POLARSSL_ERR_NET_TRY_AGAIN) ? -1 : CURLE_SEND_ERROR; + *curlcode = (ret == POLARSSL_ERR_NET_TRY_AGAIN) ? + CURLE_AGAIN : CURLE_SEND_ERROR; ret = -1; } @@ -355,12 +360,11 @@ void Curl_polarssl_close(struct connectdata *conn, int sockindex) ssl_free(&conn->ssl[sockindex].ssl); } -/* for documentation see Curl_ssl_recv() in sslgen.h */ -ssize_t Curl_polarssl_recv(struct connectdata *conn, - int num, - char *buf, - size_t buffersize, - int *curlcode) +static ssize_t polarssl_recv(struct connectdata *conn, + int num, + char *buf, + size_t buffersize, + CURLcode *curlcode) { int ret = -1; ssize_t len = -1; @@ -369,7 +373,8 @@ ssize_t Curl_polarssl_recv(struct connectdata *conn, ret = ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, buffersize); if(ret <= 0) { - *curlcode = (ret == POLARSSL_ERR_NET_TRY_AGAIN) ? -1 : CURLE_RECV_ERROR; + *curlcode = (ret == POLARSSL_ERR_NET_TRY_AGAIN) ? + CURLE_AGAIN : CURLE_RECV_ERROR; return -1; } diff --git a/lib/polarssl.h b/lib/polarssl.h index 7d406ef70..be905987e 100644 --- a/lib/polarssl.h +++ b/lib/polarssl.h @@ -34,14 +34,6 @@ void Curl_polarssl_close_all(struct SessionHandle *data); /* close a SSL connection */ void Curl_polarssl_close(struct connectdata *conn, int sockindex); -/* return number of sent (non-SSL) bytes */ -ssize_t Curl_polarssl_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, int *curlcode); -ssize_t Curl_polarssl_recv(struct connectdata *conn, /* connection data */ - int num, /* socketindex */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - int *curlcode); void Curl_polarssl_session_free(void *ptr); size_t Curl_polarssl_version(char *buffer, size_t size); int Curl_polarssl_shutdown(struct connectdata *conn, int sockindex); @@ -57,8 +49,6 @@ int Curl_polarssl_shutdown(struct connectdata *conn, int sockindex); #define curlssl_set_engine(x,y) (x=x, y=y, CURLE_FAILED_INIT) #define curlssl_set_engine_default(x) (x=x, CURLE_FAILED_INIT) #define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL) -#define curlssl_send Curl_polarssl_send -#define curlssl_recv Curl_polarssl_recv #define curlssl_version Curl_polarssl_version #define curlssl_check_cxn(x) (x=x, -1) #define curlssl_data_pending(x,y) (x=x, y=y, 0) diff --git a/lib/qssl.c b/lib/qssl.c index 5a08a2559..74f9b5766 100644 --- a/lib/qssl.c +++ b/lib/qssl.c @@ -242,6 +242,9 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex) } +static Curl_recv qsossl_recv; +static Curl_send qsossl_send; + CURLcode Curl_qsossl_connect(struct connectdata * conn, int sockindex) { @@ -263,8 +266,11 @@ CURLcode Curl_qsossl_connect(struct connectdata * conn, int sockindex) connssl->state = ssl_connection_none; } } - if (rc == CURLE_OK) + if (rc == CURLE_OK) { connssl->state = ssl_connection_complete; + conn->recv = qsossl_recv; + conn->send = qsossl_send; + } return rc; } @@ -374,9 +380,8 @@ int Curl_qsossl_shutdown(struct connectdata * conn, int sockindex) } -/* for documentation see Curl_ssl_send() in sslgen.h */ -ssize_t Curl_qsossl_send(struct connectdata * conn, int sockindex, - const void * mem, size_t len, int * curlcode) +static ssize_t qsossl_send(struct connectdata * conn, int sockindex, + const void * mem, size_t len, CURLcode * curlcode) { /* SSL_Write() is said to return 'int' while write() and send() returns @@ -392,14 +397,14 @@ ssize_t Curl_qsossl_send(struct connectdata * conn, int sockindex, /* The operation did not complete; the same SSL I/O function should be called again later. This is basicly an EWOULDBLOCK equivalent. */ - *curlcode = -1; /* EWOULDBLOCK */ + *curlcode = CURLE_AGAIN; return -1; case SSL_ERROR_IO: switch (errno) { case EWOULDBLOCK: case EINTR: - *curlcode = -1; /* EWOULDBLOCK */ + *curlcode = CURLE_AGAIN; return -1; } @@ -419,9 +424,8 @@ ssize_t Curl_qsossl_send(struct connectdata * conn, int sockindex, } -/* for documentation see Curl_ssl_recv() in sslgen.h */ -ssize_t Curl_qsossl_recv(struct connectdata * conn, int num, char * buf, - size_t buffersize, int * curlcode) +static ssize_t qsossl_recv(struct connectdata * conn, int num, char * buf, + size_t buffersize, CURLcode * curlcode) { char error_buffer[120]; /* OpenSSL documents that this must be at @@ -440,13 +444,13 @@ ssize_t Curl_qsossl_recv(struct connectdata * conn, int num, char * buf, case SSL_ERROR_BAD_STATE: /* there's data pending, re-invoke SSL_Read(). */ - *curlcode = -1; /* EWOULDBLOCK */ + *curlcode = CURLE_AGAIN; return -1; case SSL_ERROR_IO: switch (errno) { case EWOULDBLOCK: - *curlcode = -1; /* EWOULDBLOCK */ + *curlcode = CURLE_AGAIN; return -1; } diff --git a/lib/qssl.h b/lib/qssl.h index a0cf8cc29..45190e623 100644 --- a/lib/qssl.h +++ b/lib/qssl.h @@ -36,20 +36,6 @@ void Curl_qsossl_close(struct connectdata *conn, int sockindex); int Curl_qsossl_close_all(struct SessionHandle * data); int Curl_qsossl_shutdown(struct connectdata * conn, int sockindex); -/* for documentation see Curl_ssl_send() in sslgen.h */ -ssize_t Curl_qsossl_send(struct connectdata * conn, - int sockindex, - const void * mem, - size_t len, - int * curlcode); - -/* for documentation see Curl_ssl_recv() in sslgen.h */ -ssize_t Curl_qsossl_recv(struct connectdata * conn, /* connection data */ - int num, /* socketindex */ - char * buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - int * curlcode); - size_t Curl_qsossl_version(char * buffer, size_t size); int Curl_qsossl_check_cxn(struct connectdata * cxn); @@ -66,8 +52,6 @@ int Curl_qsossl_check_cxn(struct connectdata * cxn); #define curlssl_set_engine(x,y) CURLE_FAILED_INIT #define curlssl_set_engine_default(x) CURLE_FAILED_INIT #define curlssl_engines_list(x) NULL -#define curlssl_send Curl_qsossl_send -#define curlssl_recv Curl_qsossl_recv #define curlssl_version Curl_qsossl_version #define curlssl_check_cxn(x) Curl_qsossl_check_cxn(x) #define curlssl_data_pending(x,y) 0 diff --git a/lib/security.c b/lib/security.c index 03fc67966..03b1be251 100644 --- a/lib/security.c +++ b/lib/security.c @@ -10,7 +10,7 @@ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * - * Copyright (C) 2001 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2001 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. * * All rights reserved. * @@ -101,20 +101,6 @@ static const struct Curl_sec_client_mech * const mechs[] = { NULL }; -/* TODO: This function isn't actually used anywhere and should be removed */ -int -Curl_sec_getc(struct connectdata *conn, FILE *F) -{ - if(conn->sec_complete && conn->data_prot) { - char c; - if(Curl_sec_read(conn, fileno(F), &c, 1) <= 0) - return EOF; - return c; - } - else - return getc(F); -} - static int block_read(int fd, void *buf, size_t len) { @@ -189,35 +175,16 @@ buffer_read(struct krb4buffer *buf, void *data, size_t len) return len; } -static size_t -buffer_write(struct krb4buffer *buf, void *data, size_t len) -{ - if(buf->index + len > buf->size) { - void *tmp; - if(buf->data == NULL) - tmp = malloc(1024); - else - tmp = realloc(buf->data, buf->index + len); - if(tmp == NULL) - return -1; - buf->data = tmp; - buf->size = buf->index + len; - } - memcpy((char*)buf->data + buf->index, data, len); - buf->index += len; - return len; -} - -int -Curl_sec_read(struct connectdata *conn, int fd, void *buffer, int length) +static ssize_t sec_read(struct connectdata *conn, int num, + char *buffer, size_t length, CURLcode *err) { size_t len; int rx = 0; + curl_socket_t fd = conn->sock[num]; - if(conn->sec_complete == 0 || conn->data_prot == 0) - return read(fd, buffer, length); + *err = CURLE_OK; - if(conn->in_buffer.eof_flag){ + if(conn->in_buffer.eof_flag) { conn->in_buffer.eof_flag = 0; return 0; } @@ -284,29 +251,12 @@ sec_send(struct connectdata *conn, int fd, const char *from, int length) return length; } -int -Curl_sec_fflush_fd(struct connectdata *conn, int fd) -{ - if(conn->data_prot != prot_clear) { - if(conn->out_buffer.index > 0){ - Curl_sec_write(conn, fd, - conn->out_buffer.data, conn->out_buffer.index); - conn->out_buffer.index = 0; - } - sec_send(conn, fd, NULL, 0); - } - return 0; -} - -int -Curl_sec_write(struct connectdata *conn, int fd, const char *buffer, int length) +static ssize_t sec_write(struct connectdata *conn, int fd, + const char *buffer, int length) { int len = conn->buffer_size; int tx = 0; - if(conn->data_prot == prot_clear) - return write(fd, buffer, length); - len -= (conn->mech->overhead)(conn->app_data, conn->data_prot, len); if(len <= 0) len = length; @@ -321,27 +271,25 @@ Curl_sec_write(struct connectdata *conn, int fd, const char *buffer, int length) return tx; } -ssize_t -Curl_sec_send(struct connectdata *conn, int num, const char *buffer, int length) +int +Curl_sec_fflush_fd(struct connectdata *conn, int fd) { - curl_socket_t fd = conn->sock[num]; - return (ssize_t)Curl_sec_write(conn, fd, buffer, length); + if(conn->data_prot != prot_clear) { + if(conn->out_buffer.index > 0){ + sec_write(conn, fd, conn->out_buffer.data, conn->out_buffer.index); + conn->out_buffer.index = 0; + } + sec_send(conn, fd, NULL, 0); + } + return 0; } -int -Curl_sec_putc(struct connectdata *conn, int c, FILE *F) +static ssize_t _sec_send(struct connectdata *conn, int num, + const void *buffer, size_t length, CURLcode *err) { - char ch = (char)c; - if(conn->data_prot == prot_clear) - return putc(c, F); - - buffer_write(&conn->out_buffer, &ch, 1); - if(c == '\n' || conn->out_buffer.index >= 1024 /* XXX */) { - Curl_sec_write(conn, fileno(F), conn->out_buffer.data, - conn->out_buffer.index); - conn->out_buffer.index = 0; - } - return c; + curl_socket_t fd = conn->sock[num]; + *err = CURLE_OK; + return sec_write(conn, fd, buffer, length); } int @@ -517,6 +465,10 @@ Curl_sec_login(struct connectdata *conn) } conn->mech = *m; conn->sec_complete = 1; + if (conn->data_prot != prot_clear) { + conn->recv = sec_read; + conn->send = _sec_send; + } conn->command_prot = prot_safe; /* Set the requested protection level */ /* BLOCKING */ diff --git a/lib/sendf.c b/lib/sendf.c index ff4aee30b..ffd01c744 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -234,42 +234,11 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn, return res; } -static ssize_t send_plain(struct connectdata *conn, - int num, - const void *mem, - size_t len) -{ - curl_socket_t sockfd = conn->sock[num]; - ssize_t bytes_written = swrite(sockfd, mem, len); - - if(-1 == bytes_written) { - int err = SOCKERRNO; - - if( -#ifdef WSAEWOULDBLOCK - /* This is how Windows does it */ - (WSAEWOULDBLOCK == err) -#else - /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned - due to its inability to send off data without blocking. We therefor - treat both error codes the same here */ - (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) -#endif - ) - /* this is just a case of EWOULDBLOCK */ - bytes_written=0; - else - failf(conn->data, "Send failure: %s", - Curl_strerror(conn, err)); - } - return bytes_written; -} - /* * 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 + * If the write would block (CURLE_AGAIN), we return CURLE_OK and * (*written == 0). Otherwise we return regular CURLcode value. */ CURLcode Curl_write(struct connectdata *conn, @@ -279,29 +248,20 @@ CURLcode Curl_write(struct connectdata *conn, ssize_t *written) { ssize_t bytes_written; - int curlcode = CURLE_OK; + CURLcode 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, &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)) - bytes_written = Curl_sftp_send(conn, num, mem, len); - else if(conn->sec_complete) - bytes_written = Curl_sec_send(conn, num, mem, len); - else - bytes_written = send_plain(conn, num, mem, len); + bytes_written = conn->send(conn, num, mem, len, &curlcode); *written = bytes_written; if(-1 != bytes_written) /* we completely ignore the curlcode value when -1 is not returned */ return CURLE_OK; - /* handle EWOULDBLOCK or a send failure */ + /* handle CURLE_AGAIN or a send failure */ switch(curlcode) { - case /* EWOULDBLOCK */ -1: - *written = /* EWOULDBLOCK */ 0; + case CURLE_AGAIN: + *written = 0; return CURLE_OK; case CURLE_OK: @@ -314,6 +274,39 @@ CURLcode Curl_write(struct connectdata *conn, } } +ssize_t Curl_send_plain(struct connectdata *conn, int num, + const void *mem, size_t len, CURLcode *code) +{ + curl_socket_t sockfd = conn->sock[num]; + ssize_t bytes_written = swrite(sockfd, mem, len); + + *code = CURLE_OK; + if(-1 == bytes_written) { + int err = SOCKERRNO; + + if( +#ifdef WSAEWOULDBLOCK + /* This is how Windows does it */ + (WSAEWOULDBLOCK == err) +#else + /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned + due to its inability to send off data without blocking. We therefor + treat both error codes the same here */ + (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) +#endif + ) { + /* this is just a case of EWOULDBLOCK */ + bytes_written=0; + *code = CURLE_AGAIN; + } else { + failf(conn->data, "Send failure: %s", + Curl_strerror(conn, err)); + *code = CURLE_SEND_ERROR; + } + } + return bytes_written; +} + /* * Curl_write_plain() is an internal write function that sends data to the * server using plain sockets only. Otherwise meant to have the exact same @@ -329,14 +322,45 @@ CURLcode Curl_write_plain(struct connectdata *conn, CURLcode retcode; int num = (sockfd == conn->sock[SECONDARYSOCKET]); - bytes_written = send_plain(conn, num, mem, len); + bytes_written = Curl_send_plain(conn, num, mem, len, &retcode); *written = bytes_written; - retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR; return retcode; } +ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, + size_t len, CURLcode *code) +{ + curl_socket_t sockfd = conn->sock[num]; + ssize_t nread = sread(sockfd, buf, len); + + *code = CURLE_OK; + if(-1 == nread) { + int err = SOCKERRNO; + + if( +#ifdef WSAEWOULDBLOCK + /* This is how Windows does it */ + (WSAEWOULDBLOCK == err) +#else + /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned + due to its inability to send off data without blocking. We therefor + treat both error codes the same here */ + (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) +#endif + ) { + /* this is just a case of EWOULDBLOCK */ + *code = CURLE_AGAIN; + } else { + failf(conn->data, "Recv failure: %s", + Curl_strerror(conn, err)); + *code = CURLE_RECV_ERROR; + } + } + return nread; +} + static CURLcode pausewrite(struct SessionHandle *data, int type, /* what type of data */ const char *ptr, @@ -476,7 +500,7 @@ CURLcode Curl_client_write(struct connectdata *conn, return CURLE_OK; } -int Curl_read_plain(curl_socket_t sockfd, +CURLcode Curl_read_plain(curl_socket_t sockfd, char *buf, size_t bytesfromsocket, ssize_t *n) @@ -490,7 +514,7 @@ int Curl_read_plain(curl_socket_t sockfd, #else if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)) #endif - return -1; + return CURLE_AGAIN; else return CURLE_RECV_ERROR; } @@ -504,15 +528,15 @@ int Curl_read_plain(curl_socket_t sockfd, * Internal read-from-socket function. This is meant to deal with plain * sockets, SSL sockets and kerberos sockets. * - * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return - * a regular CURLcode value. + * Returns a regular CURLcode value. */ -int Curl_read(struct connectdata *conn, /* connection data */ +CURLcode Curl_read(struct connectdata *conn, /* connection data */ curl_socket_t sockfd, /* read from this socket */ char *buf, /* store read data here */ size_t sizerequested, /* max amount to read */ ssize_t *n) /* amount bytes read */ { + CURLcode curlcode = CURLE_RECV_ERROR; ssize_t nread = 0; size_t bytesfromsocket = 0; char *buffertofill = NULL; @@ -552,50 +576,17 @@ int Curl_read(struct connectdata *conn, /* connection data */ buffertofill = buf; } - if(conn->ssl[num].state == ssl_connection_complete) { - int curlcode = CURLE_RECV_ERROR; - nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket, &curlcode); + nread = conn->recv(conn, num, buffertofill, bytesfromsocket, &curlcode); + if(nread == -1) + return curlcode; - if(nread == -1) - return curlcode; - } - else if(Curl_ssh_enabled(conn, (PROT_SCP|PROT_SFTP))) { - if(conn->protocol & PROT_SCP) - nread = Curl_scp_recv(conn, num, buffertofill, bytesfromsocket); - else if(conn->protocol & PROT_SFTP) - nread = Curl_sftp_recv(conn, num, buffertofill, bytesfromsocket); -#ifdef LIBSSH2CHANNEL_EAGAIN - if(nread == LIBSSH2CHANNEL_EAGAIN) - /* EWOULDBLOCK */ - return -1; -#endif - if(nread < 0) - /* since it is negative and not EAGAIN, it was a protocol-layer error */ - return CURLE_RECV_ERROR; - } - else { - if(conn->sec_complete) - nread = Curl_sec_read(conn, sockfd, buffertofill, - bytesfromsocket); - /* TODO: Need to handle EAGAIN here somehow, similar to how it - * is done in Curl_read_plain, either right here or in Curl_sec_read - * itself. */ - else { - int ret = Curl_read_plain(sockfd, buffertofill, bytesfromsocket, - &nread); - if(ret) - return ret; - } + if(pipelining) { + memcpy(buf, conn->master_buffer, nread); + conn->buf_len = nread; + conn->read_pos = nread; } - if(nread >= 0) { - if(pipelining) { - memcpy(buf, conn->master_buffer, nread); - conn->buf_len = nread; - conn->read_pos = nread; - } - *n += nread; - } + *n += nread; return CURLE_OK; } diff --git a/lib/sendf.h b/lib/sendf.h index 5732a0ba8..8f0ea24d7 100644 --- a/lib/sendf.h +++ b/lib/sendf.h @@ -55,15 +55,20 @@ CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len); /* internal read-function, does plain socket only */ -int Curl_read_plain(curl_socket_t sockfd, - char *buf, - size_t bytesfromsocket, - ssize_t *n); +CURLcode Curl_read_plain(curl_socket_t sockfd, + char *buf, + size_t bytesfromsocket, + ssize_t *n); + +ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, + size_t len, CURLcode *code); +ssize_t Curl_send_plain(struct connectdata *conn, int num, + const void *mem, size_t len, CURLcode *code); /* internal read-function, does plain socket, SSL and krb4 */ -int Curl_read(struct connectdata *conn, curl_socket_t sockfd, - char *buf, size_t buffersize, - ssize_t *n); +CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd, + char *buf, size_t buffersize, + ssize_t *n); /* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */ CURLcode Curl_write(struct connectdata *conn, curl_socket_t sockfd, diff --git a/lib/socks.c b/lib/socks.c index 9787f864a..a10a99186 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -77,7 +77,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */ conntime = Curl_tvdiff(tvnow, conn->created); if(conntime > conn_timeout) { /* we already got the timeout */ - result = ~CURLE_OK; + result = CURLE_OPERATION_TIMEDOUT; break; } if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, @@ -86,7 +86,9 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */ break; } result = Curl_read_plain(sockfd, buf, buffersize, &nread); - if(result) + if(CURLE_AGAIN == result) + continue; + else if(result) break; if(buffersize == nread) { @@ -2464,6 +2464,9 @@ static CURLcode ssh_init(struct connectdata *conn) return CURLE_OK; } +static Curl_recv scp_recv, sftp_recv; +static Curl_send scp_send, sftp_send; + /* * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to * do protocol-specific actions at connect-time. @@ -2489,6 +2492,13 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) if(result) return result; + if(conn->protocol & PROT_SCP) { + conn->recv = scp_recv; + conn->send = scp_send; + } else { + conn->recv = sftp_recv; + conn->send = sftp_send; + } ssh = &conn->proto.sshc; #ifdef CURL_LIBSSH2_DEBUG @@ -2703,8 +2713,8 @@ static CURLcode scp_done(struct connectdata *conn, CURLcode status, } /* return number of received (decrypted) bytes */ -ssize_t Curl_scp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len) +static ssize_t scp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) { ssize_t nwrite; (void)sockindex; /* we only support SCP on the fixed known primary socket */ @@ -2715,8 +2725,10 @@ ssize_t Curl_scp_send(struct connectdata *conn, int sockindex, ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - if(nwrite == LIBSSH2_ERROR_EAGAIN) - return 0; + if(nwrite == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } return nwrite; } @@ -2725,8 +2737,8 @@ ssize_t Curl_scp_send(struct connectdata *conn, int sockindex, * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return * a regular CURLcode value. */ -ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len) +static ssize_t scp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) { ssize_t nread; (void)sockindex; /* we only support SCP on the fixed known primary socket */ @@ -2736,6 +2748,10 @@ ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex, libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len); ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + if (nread == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nread = -1; + } return nread; } @@ -2840,8 +2856,8 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status, } /* return number of sent bytes */ -ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len) +static ssize_t sftp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) { ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14 but is changed to ssize_t in 0.15. These days we don't @@ -2852,8 +2868,10 @@ ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex, ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - if(nwrite == LIBSSH2_ERROR_EAGAIN) - return 0; + if(nwrite == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } return nwrite; } @@ -2861,8 +2879,8 @@ ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex, /* * Return number of received (decrypted) bytes */ -ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len) +static ssize_t sftp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) { ssize_t nread; (void)sockindex; @@ -2871,6 +2889,10 @@ ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex, ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + if(nread == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nread = -1; + } return nread; } @@ -162,26 +162,6 @@ struct ssh_conn { extern const struct Curl_handler Curl_handler_scp; extern const struct Curl_handler Curl_handler_sftp; -ssize_t Curl_scp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len); -ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len); - -ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len); -ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len); - -#define Curl_ssh_enabled(conn,prot) (conn->protocol & prot) - -#else /* USE_LIBSSH2 */ - -#define Curl_ssh_enabled(x,y) 0 -#define Curl_scp_send(a,b,c,d) 0 -#define Curl_sftp_send(a,b,c,d) 0 -#define Curl_scp_recv(a,b,c,d) 0 -#define Curl_sftp_recv(a,b,c,d) 0 - #endif /* USE_LIBSSH2 */ #endif /* HEADER_CURL_SSH_H */ diff --git a/lib/sslgen.c b/lib/sslgen.c index 24b6dcbd6..bd8dc1722 100644 --- a/lib/sslgen.c +++ b/lib/sslgen.c @@ -410,25 +410,6 @@ struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data) return curlssl_engines_list(data); } -ssize_t Curl_ssl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - int *curlcode) -{ - return curlssl_send(conn, sockindex, mem, len, curlcode); -} - -ssize_t Curl_ssl_recv(struct connectdata *conn, - int sockindex, - char *mem, - size_t len, - int *curlcode) -{ - return curlssl_recv(conn, sockindex, mem, len, curlcode); -} - - /* * This sets up a session ID cache to the specified size. Make sure this code * is agnostic to what underlying SSL technology we use. diff --git a/lib/sslgen.h b/lib/sslgen.h index c56265e05..997e30d35 100644 --- a/lib/sslgen.h +++ b/lib/sslgen.h @@ -45,28 +45,6 @@ CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine); CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data); struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data); -/* 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 */ - 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); diff --git a/lib/ssluse.c b/lib/ssluse.c index d9cf38290..0e23c0842 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -2352,6 +2352,9 @@ ossl_connect_step3(struct connectdata *conn, return retcode; } +static Curl_recv ossl_recv; +static Curl_send ossl_send; + static CURLcode ossl_connect_common(struct connectdata *conn, int sockindex, @@ -2437,6 +2440,8 @@ ossl_connect_common(struct connectdata *conn, if(ssl_connect_done==connssl->connecting_state) { connssl->state = ssl_connection_complete; + conn->recv = ossl_recv; + conn->send = ossl_send; *done = TRUE; } else @@ -2482,12 +2487,11 @@ bool Curl_ossl_data_pending(const struct connectdata *conn, return FALSE; } -/* for documentation see Curl_ssl_send() in sslgen.h */ -ssize_t Curl_ossl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - int *curlcode) +static ssize_t ossl_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) { /* SSL_write() is said to return 'int' while write() and send() returns 'size_t' */ @@ -2510,7 +2514,7 @@ ssize_t Curl_ossl_send(struct connectdata *conn, /* The operation did not complete; the same TLS/SSL I/O function should be called again later. This is basicly an EWOULDBLOCK equivalent. */ - *curlcode = /* EWOULDBLOCK */ -1; + *curlcode = CURLE_AGAIN; return -1; case SSL_ERROR_SYSCALL: failf(conn->data, "SSL_write() returned SYSCALL, errno = %d", @@ -2534,12 +2538,11 @@ ssize_t Curl_ossl_send(struct connectdata *conn, return (ssize_t)rc; /* number of bytes */ } -/* for documentation see Curl_ssl_recv() in sslgen.h */ -ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */ - int num, /* socketindex */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - int *curlcode) +static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ + int num, /* socketindex */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + CURLcode *curlcode) { char error_buffer[120]; /* OpenSSL documents that this must be at least 120 bytes long. */ @@ -2560,7 +2563,7 @@ ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */ case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: /* there's data pending, re-invoke SSL_read() */ - *curlcode = -1; /* EWOULDBLOCK */ + *curlcode = CURLE_AGAIN; return -1; default: /* openssl/ssl.h says "look at error stack/return value/errno" */ diff --git a/lib/ssluse.h b/lib/ssluse.h index 00357afc5..2ac0ad2ec 100644 --- a/lib/ssluse.h +++ b/lib/ssluse.h @@ -56,20 +56,6 @@ struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data); int Curl_ossl_init(void); void Curl_ossl_cleanup(void); -/* for documentation see Curl_ssl_send() in sslgen.h */ -ssize_t Curl_ossl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - int *curlcode); - -/* for documentation see Curl_ssl_recv() in sslgen.h */ -ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */ - int num, /* socketindex */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - int *curlcode); - size_t Curl_ossl_version(char *buffer, size_t size); int Curl_ossl_check_cxn(struct connectdata *cxn); int Curl_ossl_seed(struct SessionHandle *data); @@ -90,8 +76,6 @@ bool Curl_ossl_data_pending(const struct connectdata *conn, #define curlssl_set_engine(x,y) Curl_ossl_set_engine(x,y) #define curlssl_set_engine_default(x) Curl_ossl_set_engine_default(x) #define curlssl_engines_list(x) Curl_ossl_engines_list(x) -#define curlssl_send Curl_ossl_send -#define curlssl_recv Curl_ossl_recv #define curlssl_version Curl_ossl_version #define curlssl_check_cxn Curl_ossl_check_cxn #define curlssl_data_pending(x,y) Curl_ossl_data_pending(x,y) diff --git a/lib/telnet.c b/lib/telnet.c index e7f05eb91..b94415db5 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -1209,7 +1209,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) struct pollfd pfd[2]; int poll_cnt; #endif - int ret; ssize_t nread; struct timeval now; bool keepon = TRUE; @@ -1383,14 +1382,13 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) } if(events.lNetworkEvents & FD_READ) { /* read data from network */ - ret = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); - /* returned sub-zero, this would've blocked. Loop again */ - if(ret < 0) + code = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); + /* read would've blocked. Loop again */ + if(code == CURLE_AGAIN) break; /* returned not-zero, this an error */ - else if(ret) { + else if(code) { keepon = FALSE; - code = (CURLcode)ret; break; } /* returned zero but actually received 0 or less here, @@ -1472,14 +1470,13 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) default: /* read! */ if(pfd[0].revents & POLLIN) { /* read data from network */ - ret = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); - /* returned sub-zero, this would've blocked. Loop again */ - if(ret < 0) + code = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); + /* read would've blocked. Loop again */ + if(code == CURLE_AGAIN) break; /* returned not-zero, this an error */ - else if(ret) { + else if(code) { keepon = FALSE; - code = (CURLcode)ret; break; } /* returned zero but actually received 0 or less here, diff --git a/lib/transfer.c b/lib/transfer.c index 92a59d038..c9234a79d 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -376,12 +376,11 @@ static CURLcode readwrite_data(struct SessionHandle *data, *done = FALSE; /* This is where we loop until we have read everything there is to - read or we get a EWOULDBLOCK */ + read or we get a CURLE_AGAIN */ do { size_t buffersize = data->set.buffer_size? data->set.buffer_size : BUFSIZE; size_t bytestoread = buffersize; - int readrc; if(k->size != -1 && !k->header) { /* make sure we don't read "too much" if we can help it since we @@ -394,15 +393,12 @@ static CURLcode readwrite_data(struct SessionHandle *data, if(bytestoread) { /* receive data from the network! */ - readrc = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread); + result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread); - /* subzero, this would've blocked */ - if(0 > readrc) + /* read would've blocked */ + if(CURLE_AGAIN == result) break; /* get out of loop */ - /* get the CURLcode from the int */ - result = (CURLcode)readrc; - if(result>0) return result; } @@ -4760,6 +4760,9 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } + conn->recv = Curl_recv_plain; + conn->send = Curl_send_plain; + /*********************************************************************** * file: is a special case in that it doesn't need a network connection ***********************************************************************/ diff --git a/lib/urldata.h b/lib/urldata.h index 7e3afee7c..efc56d7b0 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -650,6 +650,20 @@ struct Curl_handler { long protocol; /* PROT_* flags concerning the protocol set */ }; +/* return the count of bytes sent, or -1 on error */ +typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + const void *buf, /* data to write */ + size_t len, /* max amount to write */ + CURLcode *err); /* error to return */ + +/* return the count of bytes read, or -1 on error */ +typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + char *buf, /* store data here */ + size_t len, /* max amount to read */ + CURLcode *err); /* error to return */ + /* * The connectdata struct contains all fields and variables that should be * unique for an entire connection. @@ -746,6 +760,9 @@ struct connectdata { curl_socket_t sock[2]; /* two sockets, the second is used for the data transfer when doing FTP */ + Curl_recv *recv; + Curl_send *send; + struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */ struct ssl_config_data ssl_config; |