summaryrefslogtreecommitdiff
path: root/lib/socks_gssapi.c
diff options
context:
space:
mode:
authorStefan Eissing <stefan@eissing.org>2023-01-30 16:03:00 +0100
committerDaniel Stenberg <daniel@haxx.se>2023-01-31 11:23:59 +0100
commit5651a36d1ae46db61a31771a8d4d6dcf2a510856 (patch)
treee4a92cb9ca01ee60bce0d5af481c37a918d92378 /lib/socks_gssapi.c
parenta3bcfab4b577dde2ddac0f25bbe872037dd81d23 (diff)
downloadcurl-5651a36d1ae46db61a31771a8d4d6dcf2a510856.tar.gz
cf-socket: improvements in socket I/O handling
- Curl_write_plain/Curl_read_plain have been eliminated. Last code use now uses Curl_conn_send/recv so that requests use conn->send/revc callbacks which defaults to cfilters use. - Curl_recv_plain/Curl_send_plain have been internalized in cf-socket.c. - USE_RECV_BEFORE_SEND_WORKAROUND (active on Windows) has been moved into cf-socket.c. The pre_recv buffer is held at the socket filter context. `postponed_data` structures have been removed from `connectdata`. - the hanger in HTTP/2 request handling was a result of read buffering on all sends and the multi handling is not prepared for this. The following happens: - multi preforms on a HTTP/2 easy handle - h2 reads and processes data - this leads to a send of h2 data - which receives and buffers before the send - h2 returns - multi selects on the socket, but no data arrives (its in the buffer already) the workaround now receives data in a loop as long as there is something in the buffer. The real fix would be for multi to change, so that `data_pending` is evaluated before deciding to wait on the socket. io_buffer, optional, in cf-socket.c, http/2 sets state.drain if lower filter have pending data. This io_buffer is only available/used when the -DUSE_RECV_BEFORE_SEND_WORKAROUND is active, e.g. on Windows configurations. It also maintains the original checks on protocol handler being HTTP and conn->send/recv not being replaced. The HTTP/2 (nghttp2) cfilter now sets data->state.drain when it finds out that the "lower" filter chain has still pending data at the end of its IO operation. This prevents the processing from becoming stalled. Closes #10280
Diffstat (limited to 'lib/socks_gssapi.c')
-rw-r--r--lib/socks_gssapi.c44
1 files changed, 23 insertions, 21 deletions
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
index 381a724ac..2ede8c7c2 100644
--- a/lib/socks_gssapi.c
+++ b/lib/socks_gssapi.c
@@ -30,6 +30,7 @@
#include "curl_gssapi.h"
#include "urldata.h"
#include "sendf.h"
+#include "cfilters.h"
#include "connect.h"
#include "timeval.h"
#include "socks.h"
@@ -101,14 +102,14 @@ static int check_gss_err(struct Curl_easy *data,
return 0;
}
-CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
- struct connectdata *conn = data->conn;
- curl_socket_t sock = conn->sock[sockindex];
+ struct connectdata *conn = cf->conn;
+ curl_socket_t sock = conn->sock[cf->sockindex];
CURLcode code;
ssize_t actualread;
- ssize_t written;
+ ssize_t nwritten;
int result;
OM_uint32 gss_major_status, gss_minor_status, gss_status;
OM_uint32 gss_ret_flags;
@@ -203,8 +204,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
us_length = htons((short)gss_send_token.length);
memcpy(socksreq + 2, &us_length, sizeof(short));
- code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
- if(code || (4 != written)) {
+ nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, &code);
+ if(code || (4 != nwritten)) {
failf(data, "Failed to send GSS-API authentication request.");
gss_release_name(&gss_status, &server);
gss_release_buffer(&gss_status, &gss_recv_token);
@@ -213,10 +214,10 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
return CURLE_COULDNT_CONNECT;
}
- code = Curl_write_plain(data, sock, (char *)gss_send_token.value,
- gss_send_token.length, &written);
-
- if(code || ((ssize_t)gss_send_token.length != written)) {
+ nwritten = Curl_conn_cf_send(cf->next, data,
+ (char *)gss_send_token.value,
+ gss_send_token.length, &code);
+ if(code || ((ssize_t)gss_send_token.length != nwritten)) {
failf(data, "Failed to send GSS-API authentication token.");
gss_release_name(&gss_status, &server);
gss_release_buffer(&gss_status, &gss_recv_token);
@@ -242,7 +243,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
* +----+------+-----+----------------+
*/
- result = Curl_blockread_all(data, sock, (char *)socksreq, 4, &actualread);
+ result = Curl_blockread_all(cf, data, (char *)socksreq, 4, &actualread);
if(result || (actualread != 4)) {
failf(data, "Failed to receive GSS-API authentication response.");
gss_release_name(&gss_status, &server);
@@ -281,7 +282,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
return CURLE_OUT_OF_MEMORY;
}
- result = Curl_blockread_all(data, sock, (char *)gss_recv_token.value,
+ result = Curl_blockread_all(cf, data, (char *)gss_recv_token.value,
gss_recv_token.length, &actualread);
if(result || (actualread != us_length)) {
@@ -410,8 +411,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
memcpy(socksreq + 2, &us_length, sizeof(short));
}
- code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
- if(code || (4 != written)) {
+ nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 4, &code);
+ if(code || (4 != nwritten)) {
failf(data, "Failed to send GSS-API encryption request.");
gss_release_buffer(&gss_status, &gss_w_token);
gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -420,17 +421,18 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
if(data->set.socks5_gssapi_nec) {
memcpy(socksreq, &gss_enc, 1);
- code = Curl_write_plain(data, sock, socksreq, 1, &written);
- if(code || ( 1 != written)) {
+ nwritten = Curl_conn_cf_send(cf->next, data, (char *)socksreq, 1, &code);
+ if(code || ( 1 != nwritten)) {
failf(data, "Failed to send GSS-API encryption type.");
gss_delete_sec_context(&gss_status, &gss_context, NULL);
return CURLE_COULDNT_CONNECT;
}
}
else {
- code = Curl_write_plain(data, sock, (char *)gss_w_token.value,
- gss_w_token.length, &written);
- if(code || ((ssize_t)gss_w_token.length != written)) {
+ nwritten = Curl_conn_cf_send(cf->next, data,
+ (char *)gss_w_token.value,
+ gss_w_token.length, &code);
+ if(code || ((ssize_t)gss_w_token.length != nwritten)) {
failf(data, "Failed to send GSS-API encryption type.");
gss_release_buffer(&gss_status, &gss_w_token);
gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -439,7 +441,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
gss_release_buffer(&gss_status, &gss_w_token);
}
- result = Curl_blockread_all(data, sock, (char *)socksreq, 4, &actualread);
+ result = Curl_blockread_all(cf, data, (char *)socksreq, 4, &actualread);
if(result || (actualread != 4)) {
failf(data, "Failed to receive GSS-API encryption response.");
gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -470,7 +472,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
gss_delete_sec_context(&gss_status, &gss_context, NULL);
return CURLE_OUT_OF_MEMORY;
}
- result = Curl_blockread_all(data, sock, (char *)gss_recv_token.value,
+ result = Curl_blockread_all(cf, data, (char *)gss_recv_token.value,
gss_recv_token.length, &actualread);
if(result || (actualread != us_length)) {