summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/krb5.c16
-rw-r--r--lib/sendf.c62
-rw-r--r--lib/sendf.h5
-rw-r--r--lib/socks.c12
-rw-r--r--lib/vtls/schannel.c4
5 files changed, 59 insertions, 40 deletions
diff --git a/lib/krb5.c b/lib/krb5.c
index 07d21903d..b22dcdb11 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -454,14 +454,14 @@ static int ftp_send_command(struct Curl_easy *data, const char *message, ...)
/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
saying whether an error occurred or CURLE_OK if |len| was read. */
static CURLcode
-socket_read(curl_socket_t fd, void *to, size_t len)
+socket_read(struct Curl_easy *data, curl_socket_t fd, void *to, size_t len)
{
char *to_p = to;
CURLcode result;
ssize_t nread = 0;
while(len > 0) {
- result = Curl_read_plain(fd, to_p, len, &nread);
+ result = Curl_read_plain(data, fd, to_p, len, &nread);
if(!result) {
len -= nread;
to_p += nread;
@@ -502,15 +502,15 @@ socket_write(struct Curl_easy *data, curl_socket_t fd, const void *to,
return CURLE_OK;
}
-static CURLcode read_data(struct connectdata *conn,
- curl_socket_t fd,
+static CURLcode read_data(struct Curl_easy *data, curl_socket_t fd,
struct krb5buffer *buf)
{
+ struct connectdata *conn = data->conn;
int len;
CURLcode result;
int nread;
- result = socket_read(fd, &len, sizeof(len));
+ result = socket_read(data, fd, &len, sizeof(len));
if(result)
return result;
@@ -525,7 +525,7 @@ static CURLcode read_data(struct connectdata *conn,
if(!len || !buf->data)
return CURLE_OUT_OF_MEMORY;
- result = socket_read(fd, buf->data, len);
+ result = socket_read(data, fd, buf->data, len);
if(result)
return result;
nread = conn->mech->decode(conn->app_data, buf->data, len,
@@ -560,7 +560,7 @@ static ssize_t sec_recv(struct Curl_easy *data, int sockindex,
/* Handle clear text response. */
if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
- return sread(fd, buffer, len);
+ return Curl_recv_plain(data, sockindex, buffer, len, err);
if(conn->in_buffer.eof_flag) {
conn->in_buffer.eof_flag = 0;
@@ -573,7 +573,7 @@ static ssize_t sec_recv(struct Curl_easy *data, int sockindex,
buffer += bytes_read;
while(len > 0) {
- if(read_data(conn, fd, &conn->in_buffer))
+ if(read_data(data, fd, &conn->in_buffer))
return -1;
if(conn->in_buffer.size == 0) {
if(bytes_read > 0)
diff --git a/lib/sendf.c b/lib/sendf.c
index 52bd47c5c..5c331b76e 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -338,6 +338,7 @@ CURLcode Curl_write(struct Curl_easy *data,
}
}
+/* Curl_send_plain sends raw data without a size restriction on 'len'. */
ssize_t Curl_send_plain(struct Curl_easy *data, int num,
const void *mem, size_t len, CURLcode *code)
{
@@ -403,7 +404,11 @@ ssize_t Curl_send_plain(struct Curl_easy *data, int num,
/*
* 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
- * proto as Curl_write()
+ * proto as Curl_write().
+ *
+ * This function wraps Curl_send_plain(). The only difference should be the
+ * prototype. 'sockfd' must be one of the connection's two main sockets and
+ * the value of 'len' must not be changed.
*/
CURLcode Curl_write_plain(struct Curl_easy *data,
curl_socket_t sockfd,
@@ -415,6 +420,12 @@ CURLcode Curl_write_plain(struct Curl_easy *data,
struct connectdata *conn = data->conn;
int num;
DEBUGASSERT(conn);
+ DEBUGASSERT(sockfd == conn->sock[FIRSTSOCKET] ||
+ sockfd == conn->sock[SECONDARYSOCKET]);
+ if(sockfd != conn->sock[FIRSTSOCKET] &&
+ sockfd != conn->sock[SECONDARYSOCKET])
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
num = (sockfd == conn->sock[SECONDARYSOCKET]);
*written = Curl_send_plain(data, num, mem, len, &result);
@@ -422,6 +433,7 @@ CURLcode Curl_write_plain(struct Curl_easy *data,
return result;
}
+/* Curl_recv_plain receives raw data without a size restriction on 'len'. */
ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
size_t len, CURLcode *code)
{
@@ -663,30 +675,36 @@ CURLcode Curl_client_write(struct Curl_easy *data,
return chop_write(data, type, ptr, len);
}
-CURLcode Curl_read_plain(curl_socket_t sockfd,
- char *buf,
- size_t bytesfromsocket,
- ssize_t *n)
+/*
+ * Curl_read_plain() is an internal read function that reads data from the
+ * server using plain sockets only. Otherwise meant to have the exact same
+ * proto as Curl_read().
+ *
+ * This function wraps Curl_recv_plain(). The only difference should be the
+ * prototype. 'sockfd' must be one of the connection's two main sockets and
+ * the value of 'sizerequested' must not be changed.
+ */
+CURLcode Curl_read_plain(struct Curl_easy *data, /* transfer */
+ 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 */
{
- ssize_t nread = sread(sockfd, buf, bytesfromsocket);
+ CURLcode result;
+ struct connectdata *conn = data->conn;
+ int num;
+ DEBUGASSERT(conn);
+ DEBUGASSERT(sockfd == conn->sock[FIRSTSOCKET] ||
+ sockfd == conn->sock[SECONDARYSOCKET]);
+ if(sockfd != conn->sock[FIRSTSOCKET] &&
+ sockfd != conn->sock[SECONDARYSOCKET])
+ return CURLE_BAD_FUNCTION_ARGUMENT;
- if(-1 == nread) {
- const int err = SOCKERRNO;
- const bool return_error =
-#ifdef USE_WINSOCK
- WSAEWOULDBLOCK == err
-#else
- EWOULDBLOCK == err || EAGAIN == err || EINTR == err
-#endif
- ;
- *n = 0; /* no data returned */
- if(return_error)
- return CURLE_AGAIN;
- return CURLE_RECV_ERROR;
- }
+ num = (sockfd == conn->sock[SECONDARYSOCKET]);
- *n = nread;
- return CURLE_OK;
+ *n = Curl_recv_plain(data, num, buf, sizerequested, &result);
+
+ return result;
}
/*
diff --git a/lib/sendf.h b/lib/sendf.h
index 7c4c1280a..8af5c4608 100644
--- a/lib/sendf.h
+++ b/lib/sendf.h
@@ -61,9 +61,10 @@ CURLcode Curl_client_write(struct Curl_easy *data, int type, char *ptr,
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex);
/* internal read-function, does plain socket only */
-CURLcode Curl_read_plain(curl_socket_t sockfd,
+CURLcode Curl_read_plain(struct Curl_easy *data,
+ curl_socket_t sockfd,
char *buf,
- size_t bytesfromsocket,
+ size_t sizerequested,
ssize_t *n);
ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
diff --git a/lib/socks.c b/lib/socks.c
index 40cd13e0a..e1f6dbbb2 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -112,7 +112,7 @@ int Curl_blockread_all(struct Curl_easy *data, /* transfer */
result = ~CURLE_OK;
break;
}
- result = Curl_read_plain(sockfd, buf, buffersize, &nread);
+ result = Curl_read_plain(data, sockfd, buf, buffersize, &nread);
if(CURLE_AGAIN == result)
continue;
if(result)
@@ -396,7 +396,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf,
/* FALLTHROUGH */
case CONNECT_SOCKS_READ:
/* Receive response */
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "SOCKS4: Failed receiving connect request ack: %s",
@@ -599,7 +599,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
sx->outp = socksreq; /* store it here */
/* FALLTHROUGH */
case CONNECT_SOCKS_READ:
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive initial SOCKS5 response.");
@@ -729,7 +729,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
sxstate(sx, data, CONNECT_AUTH_READ);
/* FALLTHROUGH */
case CONNECT_AUTH_READ:
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
@@ -931,7 +931,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
sxstate(sx, data, CONNECT_REQ_READ);
/* FALLTHROUGH */
case CONNECT_REQ_READ:
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to receive SOCKS5 connect request ack.");
@@ -1030,7 +1030,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
#endif
/* FALLTHROUGH */
case CONNECT_REQ_READ_MORE:
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to receive SOCKS5 connect request ack.");
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 6b5f3b592..6b35efdce 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -1413,7 +1413,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
for(;;) {
if(doread) {
/* read encrypted handshake data from socket */
- result = Curl_read_plain(conn->sock[sockindex],
+ result = Curl_read_plain(data, conn->sock[sockindex],
(char *) (backend->encdata_buffer +
backend->encdata_offset),
backend->encdata_length -
@@ -2190,7 +2190,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
backend->encdata_offset, backend->encdata_length));
/* read encrypted data from socket */
- *err = Curl_read_plain(conn->sock[sockindex],
+ *err = Curl_read_plain(data, conn->sock[sockindex],
(char *)(backend->encdata_buffer +
backend->encdata_offset),
size, &nread);