/* 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(struct Curl_easy *data, curl_socket_t fd, void *to, size_t len)
+socket_read(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(data, fd, to_p, len, &nread);
+ result = Curl_read_plain(fd, to_p, len, &nread);
if(!result) {
len -= nread;
to_p += nread;
return CURLE_OK;
}
-static CURLcode read_data(struct Curl_easy *data, curl_socket_t fd,
+static CURLcode read_data(struct connectdata *conn,
+ curl_socket_t fd,
struct krb5buffer *buf)
{
- struct connectdata *conn = data->conn;
int len;
CURLcode result;
int nread;
- result = socket_read(data, fd, &len, sizeof(len));
+ result = socket_read(fd, &len, sizeof(len));
if(result)
return result;
if(!len || !buf->data)
return CURLE_OUT_OF_MEMORY;
- result = socket_read(data, fd, buf->data, len);
+ result = socket_read(fd, buf->data, len);
if(result)
return result;
nread = conn->mech->decode(conn->app_data, buf->data, len,
/* Handle clear text response. */
if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
- return Curl_recv_plain(data, sockindex, buffer, len, err);
+ return sread(fd, buffer, len);
if(conn->in_buffer.eof_flag) {
conn->in_buffer.eof_flag = 0;
buffer += bytes_read;
while(len > 0) {
- if(read_data(data, fd, &conn->in_buffer))
+ if(read_data(conn, fd, &conn->in_buffer))
return -1;
if(conn->in_buffer.size == 0) {
if(bytes_read > 0)
}
}
-/* 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)
{
/*
* 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().
- *
- * 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.
+ * proto as Curl_write()
*/
CURLcode Curl_write_plain(struct Curl_easy *data,
curl_socket_t sockfd,
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);
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)
{
return chop_write(data, type, ptr, len);
}
-/*
- * 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 */
+CURLcode Curl_read_plain(curl_socket_t sockfd,
+ char *buf,
+ size_t bytesfromsocket,
+ ssize_t *n)
{
- 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;
-
- num = (sockfd == conn->sock[SECONDARYSOCKET]);
+ ssize_t nread = sread(sockfd, buf, bytesfromsocket);
- *n = Curl_recv_plain(data, num, buf, sizerequested, &result);
+ 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;
+ }
- return result;
+ *n = nread;
+ return CURLE_OK;
}
/*
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex);
/* internal read-function, does plain socket only */
-CURLcode Curl_read_plain(struct Curl_easy *data,
- curl_socket_t sockfd,
+CURLcode Curl_read_plain(curl_socket_t sockfd,
char *buf,
- size_t sizerequested,
+ size_t bytesfromsocket,
ssize_t *n);
ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
result = ~CURLE_OK;
break;
}
- result = Curl_read_plain(data, sockfd, buf, buffersize, &nread);
+ result = Curl_read_plain(sockfd, buf, buffersize, &nread);
if(CURLE_AGAIN == result)
continue;
if(result)
/* FALLTHROUGH */
case CONNECT_SOCKS_READ:
/* Receive response */
- result = Curl_read_plain(data, sockfd, (char *)sx->outp,
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "SOCKS4: Failed receiving connect request ack: %s",
sx->outp = socksreq; /* store it here */
/* FALLTHROUGH */
case CONNECT_SOCKS_READ:
- result = Curl_read_plain(data, sockfd, (char *)sx->outp,
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive initial SOCKS5 response.");
sxstate(sx, data, CONNECT_AUTH_READ);
/* FALLTHROUGH */
case CONNECT_AUTH_READ:
- result = Curl_read_plain(data, sockfd, (char *)sx->outp,
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
sxstate(sx, data, CONNECT_REQ_READ);
/* FALLTHROUGH */
case CONNECT_REQ_READ:
- result = Curl_read_plain(data, sockfd, (char *)sx->outp,
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to receive SOCKS5 connect request ack.");
#endif
/* FALLTHROUGH */
case CONNECT_REQ_READ_MORE:
- result = Curl_read_plain(data, sockfd, (char *)sx->outp,
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to receive SOCKS5 connect request ack.");
for(;;) {
if(doread) {
/* read encrypted handshake data from socket */
- result = Curl_read_plain(data, conn->sock[sockindex],
+ result = Curl_read_plain(conn->sock[sockindex],
(char *) (backend->encdata_buffer +
backend->encdata_offset),
backend->encdata_length -
backend->encdata_offset, backend->encdata_length));
/* read encrypted data from socket */
- *err = Curl_read_plain(data, conn->sock[sockindex],
+ *err = Curl_read_plain(conn->sock[sockindex],
(char *)(backend->encdata_buffer +
backend->encdata_offset),
size, &nread);