mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 16:18:48 -05:00
lib: pass in 'struct Curl_easy *' to most functions
... in most cases instead of 'struct connectdata *' but in some cases in addition to. - We mostly operate on transfers and not connections. - We need the transfer handle to log, store data and more. Everything in libcurl is driven by a transfer (the CURL * in the public API). - This work clarifies and separates the transfers from the connections better. - We should avoid "conn->data". Since individual connections can be used by many transfers when multiplexing, making sure that conn->data points to the current and correct transfer at all times is difficult and has been notoriously error-prone over the years. The goal is to ultimately remove the conn->data pointer for this reason. Closes #6425
This commit is contained in:
parent
0d26ab9ed3
commit
215db086e0
@ -671,7 +671,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
res->last_status = ARES_ENOTFOUND;
|
||||
#ifdef ENABLE_IPV6
|
||||
if(family == PF_UNSPEC) {
|
||||
if(Curl_ipv6works(conn)) {
|
||||
if(Curl_ipv6works(data)) {
|
||||
res->num_pending = 2;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -749,7 +749,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
if((pf != PF_INET) && !Curl_ipv6works(conn))
|
||||
if((pf != PF_INET) && !Curl_ipv6works(data))
|
||||
/* The stack seems to be a non-IPv6 one */
|
||||
pf = PF_INET;
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
@ -67,7 +67,7 @@ size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
|
||||
|
||||
(void)ctx;
|
||||
|
||||
result = Curl_read(conn, conn->sockfd, (char *)buf, buflen, &nread);
|
||||
result = Curl_read(data, conn->sockfd, (char *)buf, buflen, &nread);
|
||||
if(result == CURLE_AGAIN) {
|
||||
/* would block, register interest */
|
||||
if(data->hyp.read_waker)
|
||||
@ -94,7 +94,7 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx,
|
||||
CURLcode result;
|
||||
ssize_t nwrote;
|
||||
|
||||
result = Curl_write(conn, conn->sockfd, (void *)buf, buflen, &nwrote);
|
||||
result = Curl_write(data, conn->sockfd, (void *)buf, buflen, &nwrote);
|
||||
if(result == CURLE_AGAIN) {
|
||||
/* would block, register interest */
|
||||
if(data->hyp.write_waker)
|
||||
@ -380,7 +380,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
||||
/* Curl_http_auth_act() checks what authentication methods that are
|
||||
* available and decides which one (if any) to use. It will set 'newurl'
|
||||
* if an auth method was picked. */
|
||||
result = Curl_http_auth_act(conn);
|
||||
result = Curl_http_auth_act(data);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@ -628,9 +628,9 @@ static CURLcode cookies(struct Curl_easy *data,
|
||||
* request is to be performed. This creates and sends a properly constructed
|
||||
* HTTP request.
|
||||
*/
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct hyptransfer *h = &data->hyp;
|
||||
hyper_io *io = NULL;
|
||||
hyper_clientconn_options *options = NULL;
|
||||
@ -670,7 +670,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(!pq)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
result = Curl_http_output_auth(conn, method, httpreq,
|
||||
result = Curl_http_output_auth(data, conn, method, httpreq,
|
||||
(pq ? pq : data->state.up.path), FALSE);
|
||||
free(pq);
|
||||
if(result)
|
||||
@ -681,11 +681,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_http_range(data, conn, httpreq);
|
||||
result = Curl_http_range(data, httpreq);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_http_useragent(data, conn);
|
||||
result = Curl_http_useragent(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -799,7 +799,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
Curl_hyper_header(data, headers, data->state.aptr.uagent))
|
||||
goto error;
|
||||
|
||||
p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n";
|
||||
p_accept = Curl_checkheaders(data, "Accept")?NULL:"Accept: */*\r\n";
|
||||
if(p_accept && Curl_hyper_header(data, headers, p_accept))
|
||||
goto error;
|
||||
|
||||
@ -808,14 +808,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy &&
|
||||
!Curl_checkProxyheaders(conn, "Proxy-Connection")) {
|
||||
!Curl_checkProxyheaders(data, conn, "Proxy-Connection")) {
|
||||
if(Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive"))
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
Curl_safefree(data->state.aptr.ref);
|
||||
if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
|
||||
if(data->change.referer && !Curl_checkheaders(data, "Referer")) {
|
||||
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
|
||||
if(!data->state.aptr.ref)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -827,11 +827,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_add_timecondition(conn, headers);
|
||||
result = Curl_add_timecondition(data, headers);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_add_custom_headers(conn, FALSE, headers);
|
||||
result = Curl_add_custom_headers(data, FALSE, headers);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2021, 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
|
||||
@ -318,7 +318,8 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
struct conncache *connc,
|
||||
void *param,
|
||||
int (*func)(struct connectdata *conn, void *param))
|
||||
int (*func)(struct Curl_easy *data,
|
||||
struct connectdata *conn, void *param))
|
||||
{
|
||||
struct Curl_hash_iterator iter;
|
||||
struct Curl_llist_element *curr;
|
||||
@ -344,7 +345,7 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
struct connectdata *conn = curr->ptr;
|
||||
curr = curr->next;
|
||||
|
||||
if(1 == func(conn, param)) {
|
||||
if(1 == func(data, conn, param)) {
|
||||
CONNCACHE_UNLOCK(data);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2015 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@ -101,7 +101,8 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
struct conncache *connc,
|
||||
void *param,
|
||||
int (*func)(struct connectdata *conn,
|
||||
int (*func)(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
void *param));
|
||||
|
||||
struct connectdata *
|
||||
|
174
lib/connect.c
174
lib/connect.c
@ -160,7 +160,8 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
singleipconnect(struct connectdata *conn,
|
||||
singleipconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai, /* start connecting to this */
|
||||
int tempindex); /* 0 or 1 among the temp ones */
|
||||
|
||||
@ -236,11 +237,10 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
return timeout_ms;
|
||||
}
|
||||
|
||||
static CURLcode bindlocal(struct connectdata *conn,
|
||||
static CURLcode bindlocal(struct Curl_easy *data,
|
||||
curl_socket_t sockfd, int af, unsigned int scope)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
struct connectdata *conn = data->conn;
|
||||
struct Curl_sockaddr_storage sa;
|
||||
struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */
|
||||
curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */
|
||||
@ -573,7 +573,8 @@ static struct Curl_addrinfo *ainext(struct connectdata *conn,
|
||||
|
||||
/* Used within the multi interface. Try next IP address, returns error if no
|
||||
more address exists or error */
|
||||
static CURLcode trynextip(struct connectdata *conn,
|
||||
static CURLcode trynextip(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
int tempindex)
|
||||
{
|
||||
@ -591,7 +592,7 @@ static CURLcode trynextip(struct connectdata *conn,
|
||||
|
||||
while(ai) {
|
||||
if(ai) {
|
||||
result = singleipconnect(conn, ai, tempindex);
|
||||
result = singleipconnect(data, conn, ai, tempindex);
|
||||
if(result == CURLE_COULDNT_CONNECT) {
|
||||
ai = ainext(conn, tempindex, TRUE);
|
||||
continue;
|
||||
@ -602,21 +603,21 @@ static CURLcode trynextip(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(fd_to_close != CURL_SOCKET_BAD)
|
||||
Curl_closesocket(conn, fd_to_close);
|
||||
Curl_closesocket(data, conn, fd_to_close);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Copies connection info into the session handle to make it available
|
||||
when the session handle is no longer associated with a connection. */
|
||||
void Curl_persistconninfo(struct connectdata *conn)
|
||||
/* Copies connection info into the transfer handle to make it available when
|
||||
the transfer handle is no longer associated with the connection. */
|
||||
void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
|
||||
memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
|
||||
conn->data->info.conn_scheme = conn->handler->scheme;
|
||||
conn->data->info.conn_protocol = conn->handler->protocol;
|
||||
conn->data->info.conn_primary_port = conn->primary_port;
|
||||
conn->data->info.conn_local_port = conn->local_port;
|
||||
memcpy(data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
|
||||
memcpy(data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
|
||||
data->info.conn_scheme = conn->handler->scheme;
|
||||
data->info.conn_protocol = conn->handler->protocol;
|
||||
data->info.conn_primary_port = conn->primary_port;
|
||||
data->info.conn_local_port = conn->local_port;
|
||||
}
|
||||
|
||||
/* retrieves ip address and port from a sockaddr structure.
|
||||
@ -678,7 +679,8 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
|
||||
|
||||
/* retrieves the start/end point information of a socket of an established
|
||||
connection */
|
||||
void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd)
|
||||
void Curl_conninfo_remote(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t sockfd)
|
||||
{
|
||||
#ifdef HAVE_GETPEERNAME
|
||||
char buffer[STRERROR_LEN];
|
||||
@ -688,18 +690,19 @@ void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd)
|
||||
memset(&ssrem, 0, sizeof(ssrem));
|
||||
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(conn->data, "getpeername() failed with errno %d: %s",
|
||||
failf(data, "getpeername() failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
|
||||
conn->primary_ip, &conn->primary_port)) {
|
||||
failf(conn->data, "ssrem inet_ntop() failed with errno %d: %s",
|
||||
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||
#else
|
||||
(void)data;
|
||||
(void)conn;
|
||||
(void)sockfd;
|
||||
#endif
|
||||
@ -707,7 +710,8 @@ void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd)
|
||||
|
||||
/* retrieves the start/end point information of a socket of an established
|
||||
connection */
|
||||
void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd)
|
||||
void Curl_conninfo_local(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
#ifdef HAVE_GETSOCKNAME
|
||||
char buffer[STRERROR_LEN];
|
||||
@ -717,17 +721,18 @@ void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd)
|
||||
memset(&ssloc, 0, sizeof(ssloc));
|
||||
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(conn->data, "getsockname() failed with errno %d: %s",
|
||||
failf(data, "getsockname() failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
|
||||
conn->local_ip, &conn->local_port)) {
|
||||
failf(conn->data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
(void)data;
|
||||
(void)conn;
|
||||
(void)sockfd;
|
||||
#endif
|
||||
@ -735,17 +740,18 @@ void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd)
|
||||
|
||||
/* retrieves the start/end point information of a socket of an established
|
||||
connection */
|
||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
||||
void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
if(conn->transport == TRNSPRT_TCP) {
|
||||
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
|
||||
Curl_conninfo_remote(conn, sockfd);
|
||||
Curl_conninfo_local(conn, sockfd);
|
||||
Curl_conninfo_remote(data, conn, sockfd);
|
||||
Curl_conninfo_local(data, conn, sockfd);
|
||||
}
|
||||
} /* end of TCP-only section */
|
||||
|
||||
/* persist connection info in session handle */
|
||||
Curl_persistconninfo(conn);
|
||||
Curl_persistconninfo(data, conn);
|
||||
}
|
||||
|
||||
/* After a TCP connection to the proxy has been verified, this function does
|
||||
@ -755,12 +761,13 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
||||
Note: this function's sub-functions call failf()
|
||||
|
||||
*/
|
||||
static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
|
||||
static CURLcode connect_SOCKS(struct Curl_easy *data, int sockindex,
|
||||
bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
CURLproxycode pxresult = CURLPX_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
if(conn->bits.socksproxy) {
|
||||
/* for the secondary socket (FTP), use the "connect to host"
|
||||
* but ignore the "connect to port" (use the secondary port)
|
||||
@ -791,17 +798,17 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
|
||||
break;
|
||||
|
||||
default:
|
||||
failf(conn->data, "unknown proxytype option given");
|
||||
failf(data, "unknown proxytype option given");
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
} /* switch proxytype */
|
||||
if(pxresult) {
|
||||
result = CURLE_PROXY;
|
||||
conn->data->info.pxcode = pxresult;
|
||||
data->info.pxcode = pxresult;
|
||||
}
|
||||
}
|
||||
else
|
||||
#else
|
||||
(void)conn;
|
||||
(void)data;
|
||||
(void)sockindex;
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
*done = TRUE; /* no SOCKS proxy, so consider us connected */
|
||||
@ -813,7 +820,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
|
||||
* post_SOCKS() is called after a successful connect to the peer, which
|
||||
* *could* be a SOCKS proxy
|
||||
*/
|
||||
static void post_SOCKS(struct connectdata *conn,
|
||||
static void post_SOCKS(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
bool *connected)
|
||||
{
|
||||
@ -821,21 +829,21 @@ static void post_SOCKS(struct connectdata *conn,
|
||||
|
||||
*connected = TRUE;
|
||||
if(sockindex == FIRSTSOCKET)
|
||||
Curl_pgrsTime(conn->data, TIMER_CONNECT); /* connect done */
|
||||
Curl_updateconninfo(conn, conn->sock[sockindex]);
|
||||
Curl_verboseconnect(conn);
|
||||
conn->data->info.numconnects++; /* to track the number of connections made */
|
||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
||||
Curl_updateconninfo(data, conn, conn->sock[sockindex]);
|
||||
Curl_verboseconnect(data, conn);
|
||||
data->info.numconnects++; /* to track the number of connections made */
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_is_connected() checks if the socket has connected.
|
||||
*/
|
||||
|
||||
CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
CURLcode Curl_is_connected(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
bool *connected)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
timediff_t allow;
|
||||
int error = 0;
|
||||
@ -866,9 +874,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
if(SOCKS_STATE(conn->cnnct.state)) {
|
||||
/* still doing SOCKS */
|
||||
result = connect_SOCKS(conn, sockindex, connected);
|
||||
result = connect_SOCKS(data, sockindex, connected);
|
||||
if(!result && *connected)
|
||||
post_SOCKS(conn, sockindex, connected);
|
||||
post_SOCKS(data, conn, sockindex, connected);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -885,7 +893,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
conn->sock[sockindex] = conn->tempsock[i];
|
||||
conn->ip_addr = conn->tempaddr[i];
|
||||
conn->tempsock[i] = CURL_SOCKET_BAD;
|
||||
post_SOCKS(conn, sockindex, connected);
|
||||
post_SOCKS(data, conn, sockindex, connected);
|
||||
connkeep(conn, "HTTP/3 default");
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -920,7 +928,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
(Curl_timediff(now, conn->connecttime) >=
|
||||
data->set.happy_eyeballs_timeout)) {
|
||||
conn->bits.parallel_connect = TRUE; /* starting now */
|
||||
trynextip(conn, sockindex, 1);
|
||||
trynextip(data, conn, sockindex, 1);
|
||||
}
|
||||
}
|
||||
else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) {
|
||||
@ -937,17 +945,17 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
/* close the other socket, if open */
|
||||
if(conn->tempsock[other] != CURL_SOCKET_BAD) {
|
||||
Curl_closesocket(conn, conn->tempsock[other]);
|
||||
Curl_closesocket(data, conn, conn->tempsock[other]);
|
||||
conn->tempsock[other] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
/* see if we need to kick off any SOCKS proxy magic once we
|
||||
connected */
|
||||
result = connect_SOCKS(conn, sockindex, connected);
|
||||
result = connect_SOCKS(data, sockindex, connected);
|
||||
if(result || !*connected)
|
||||
return result;
|
||||
|
||||
post_SOCKS(conn, sockindex, connected);
|
||||
post_SOCKS(data, conn, sockindex, connected);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -978,7 +986,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ?
|
||||
allow : allow / 2;
|
||||
ainext(conn, i, TRUE);
|
||||
status = trynextip(conn, sockindex, i);
|
||||
status = trynextip(data, conn, sockindex, i);
|
||||
if((status != CURLE_COULDNT_CONNECT) ||
|
||||
conn->tempsock[other] == CURL_SOCKET_BAD)
|
||||
/* the last attempt failed and no other sockets remain open */
|
||||
@ -996,7 +1004,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
/* if the first address family runs out of addresses to try before the
|
||||
happy eyeball timeout, go ahead and try the next family now */
|
||||
result = trynextip(conn, sockindex, 1);
|
||||
result = trynextip(data, conn, sockindex, 1);
|
||||
if(!result)
|
||||
return result;
|
||||
|
||||
@ -1033,16 +1041,15 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd)
|
||||
{
|
||||
#if defined(TCP_NODELAY)
|
||||
curl_socklen_t onoff = (curl_socklen_t) 1;
|
||||
int level = IPPROTO_TCP;
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
struct Curl_easy *data = conn->data;
|
||||
char buffer[STRERROR_LEN];
|
||||
#else
|
||||
(void) conn;
|
||||
(void) data;
|
||||
#endif
|
||||
|
||||
if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
|
||||
@ -1050,7 +1057,7 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
infof(data, "Could not set TCP_NODELAY: %s\n",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
#else
|
||||
(void)conn;
|
||||
(void)data;
|
||||
(void)sockfd;
|
||||
#endif
|
||||
}
|
||||
@ -1060,10 +1067,9 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
sending data to a dead peer (instead of relying on the 4th argument to send
|
||||
being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
|
||||
systems? */
|
||||
static void nosigpipe(struct connectdata *conn,
|
||||
static void nosigpipe(struct Curl_easy *data,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
int onoff = 1;
|
||||
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
|
||||
sizeof(onoff)) < 0) {
|
||||
@ -1129,7 +1135,8 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
||||
* singleipconnect() connects to the given IP only, and it may return without
|
||||
* having connected.
|
||||
*/
|
||||
static CURLcode singleipconnect(struct connectdata *conn,
|
||||
static CURLcode singleipconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int tempindex)
|
||||
{
|
||||
@ -1137,7 +1144,6 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
int rc = -1;
|
||||
int error = 0;
|
||||
bool isconnected = FALSE;
|
||||
struct Curl_easy *data = conn->data;
|
||||
curl_socket_t sockfd;
|
||||
CURLcode result;
|
||||
char ipaddress[MAX_IPADR_LEN];
|
||||
@ -1150,7 +1156,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
curl_socket_t *sockp = &conn->tempsock[tempindex];
|
||||
*sockp = CURL_SOCKET_BAD;
|
||||
|
||||
result = Curl_socket(conn, ai, &addr, &sockfd);
|
||||
result = Curl_socket(data, ai, &addr, &sockfd);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -1160,7 +1166,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
/* malformed address or bug in inet_ntop, try next address */
|
||||
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
Curl_closesocket(conn, sockfd);
|
||||
Curl_closesocket(data, conn, sockfd);
|
||||
return CURLE_OK;
|
||||
}
|
||||
infof(data, " Trying %s:%ld...\n", ipaddress, port);
|
||||
@ -1172,9 +1178,9 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
|
||||
#endif
|
||||
if(is_tcp && data->set.tcp_nodelay)
|
||||
tcpnodelay(conn, sockfd);
|
||||
tcpnodelay(data, sockfd);
|
||||
|
||||
nosigpipe(conn, sockfd);
|
||||
nosigpipe(data, sockfd);
|
||||
|
||||
Curl_sndbufset(sockfd);
|
||||
|
||||
@ -1192,7 +1198,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
|
||||
isconnected = TRUE;
|
||||
else if(error) {
|
||||
Curl_closesocket(conn, sockfd); /* close the socket and bail out */
|
||||
Curl_closesocket(data, conn, sockfd); /* close the socket and bail out */
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
}
|
||||
@ -1203,10 +1209,10 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
|| addr.family == AF_INET6
|
||||
#endif
|
||||
) {
|
||||
result = bindlocal(conn, sockfd, addr.family,
|
||||
result = bindlocal(data, sockfd, addr.family,
|
||||
Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr));
|
||||
if(result) {
|
||||
Curl_closesocket(conn, sockfd); /* close socket and bail out */
|
||||
Curl_closesocket(data, conn, sockfd); /* close socket and bail out */
|
||||
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||
/* The address family is not supported on this interface.
|
||||
We can continue trying addresses */
|
||||
@ -1309,7 +1315,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
data->state.os_errno = error;
|
||||
|
||||
/* connect failed */
|
||||
Curl_closesocket(conn, sockfd);
|
||||
Curl_closesocket(data, conn, sockfd);
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
@ -1326,10 +1332,10 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
* pointer with the connected socket.
|
||||
*/
|
||||
|
||||
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
CURLcode Curl_connecthost(struct Curl_easy *data,
|
||||
struct connectdata *conn, /* context */
|
||||
const struct Curl_dns_entry *remotehost)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result = CURLE_COULDNT_CONNECT;
|
||||
int i;
|
||||
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
@ -1367,7 +1373,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
/* get through the list in family order in case of quick failures */
|
||||
for(i = 0; (i < 2) && result; i++) {
|
||||
while(conn->tempaddr[i]) {
|
||||
result = singleipconnect(conn, conn->tempaddr[i], i);
|
||||
result = singleipconnect(data, conn, conn->tempaddr[i], i);
|
||||
if(!result)
|
||||
break;
|
||||
ainext(conn, i, TRUE);
|
||||
@ -1376,7 +1382,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
Curl_expire(conn->data, data->set.happy_eyeballs_timeout,
|
||||
Curl_expire(data, data->set.happy_eyeballs_timeout,
|
||||
EXPIRE_HAPPY_EYEBALLS);
|
||||
|
||||
return CURLE_OK;
|
||||
@ -1387,9 +1393,11 @@ struct connfind {
|
||||
struct connectdata *found;
|
||||
};
|
||||
|
||||
static int conn_is_conn(struct connectdata *conn, void *param)
|
||||
static int conn_is_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn, void *param)
|
||||
{
|
||||
struct connfind *f = (struct connfind *)param;
|
||||
(void)data;
|
||||
if(conn->connection_id == f->id_tofind) {
|
||||
f->found = conn;
|
||||
return 1;
|
||||
@ -1471,8 +1479,8 @@ bool Curl_connalive(struct connectdata *conn)
|
||||
*
|
||||
* 'conn' can be NULL, beware!
|
||||
*/
|
||||
int Curl_closesocket(struct connectdata *conn,
|
||||
curl_socket_t sock)
|
||||
int Curl_closesocket(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t sock)
|
||||
{
|
||||
if(conn && conn->fclosesocket) {
|
||||
if((sock == conn->sock[SECONDARYSOCKET]) && conn->bits.sock_accepted)
|
||||
@ -1482,17 +1490,17 @@ int Curl_closesocket(struct connectdata *conn,
|
||||
conn->bits.sock_accepted = FALSE;
|
||||
else {
|
||||
int rc;
|
||||
Curl_multi_closed(conn->data, sock);
|
||||
Curl_set_in_callback(conn->data, true);
|
||||
Curl_multi_closed(data, sock);
|
||||
Curl_set_in_callback(data, true);
|
||||
rc = conn->fclosesocket(conn->closesocket_client, sock);
|
||||
Curl_set_in_callback(conn->data, false);
|
||||
Curl_set_in_callback(data, false);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if(conn)
|
||||
/* tell the multi-socket code about this */
|
||||
Curl_multi_closed(conn->data, sock);
|
||||
Curl_multi_closed(data, sock);
|
||||
|
||||
sclose(sock);
|
||||
|
||||
@ -1508,12 +1516,12 @@ int Curl_closesocket(struct connectdata *conn,
|
||||
* If the open socket callback is set, used that!
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_socket(struct connectdata *conn,
|
||||
CURLcode Curl_socket(struct Curl_easy *data,
|
||||
const struct Curl_addrinfo *ai,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct Curl_sockaddr_ex dummy;
|
||||
|
||||
if(!addr)
|
||||
@ -1601,16 +1609,20 @@ void Curl_conncontrol(struct connectdata *conn,
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* close if a connection, or a stream that isn't multiplexed */
|
||||
bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
|
||||
((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
|
||||
/* close if a connection, or a stream that isn't multiplexed. */
|
||||
/* This function will be called both before and after this connection is
|
||||
associated with a transfer. */
|
||||
bool closeit;
|
||||
DEBUGASSERT(conn);
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void)reason; /* useful for debugging */
|
||||
#endif
|
||||
closeit = (ctrl == CONNCTRL_CONNECTION) ||
|
||||
((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
|
||||
if((ctrl == CONNCTRL_STREAM) &&
|
||||
(conn->handler->flags & PROTOPT_STREAM))
|
||||
DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
|
||||
;
|
||||
else if((bit)closeit != conn->bits.close) {
|
||||
DEBUGF(infof(conn->data, "Marked for [%s]: %s\n",
|
||||
closeit?"closure":"keep alive", reason));
|
||||
conn->bits.close = closeit; /* the only place in the source code that
|
||||
should assign this bit */
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -27,11 +27,13 @@
|
||||
#include "sockaddr.h"
|
||||
#include "timeval.h"
|
||||
|
||||
CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
CURLcode Curl_is_connected(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
bool *connected);
|
||||
|
||||
CURLcode Curl_connecthost(struct connectdata *conn,
|
||||
CURLcode Curl_connecthost(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_dns_entry *host);
|
||||
|
||||
/* generic function that returns how much time there's left to run, according
|
||||
@ -74,11 +76,15 @@ void Curl_sndbufset(curl_socket_t sockfd);
|
||||
#define Curl_sndbufset(y) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
||||
void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd);
|
||||
void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd);
|
||||
void Curl_persistconninfo(struct connectdata *conn);
|
||||
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
|
||||
void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t sockfd);
|
||||
void Curl_conninfo_remote(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t sockfd);
|
||||
void Curl_conninfo_local(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t sockfd);
|
||||
void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn);
|
||||
int Curl_closesocket(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t sock);
|
||||
|
||||
/*
|
||||
* The Curl_sockaddr_ex structure is basically libcurl's external API
|
||||
@ -106,7 +112,7 @@ struct Curl_sockaddr_ex {
|
||||
* socket callback is set, used that!
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_socket(struct connectdata *conn,
|
||||
CURLcode Curl_socket(struct Curl_easy *data,
|
||||
const struct Curl_addrinfo *ai,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -904,7 +904,7 @@ static CURLcode client_unencode_write(struct connectdata *conn,
|
||||
if(!nbytes || k->ignorebody)
|
||||
return CURLE_OK;
|
||||
|
||||
return Curl_client_write(conn, CLIENTWRITE_BODY, (char *) buf, nbytes);
|
||||
return Curl_client_write(data, CLIENTWRITE_BODY, (char *) buf, nbytes);
|
||||
}
|
||||
|
||||
static void client_close_writer(struct connectdata *conn,
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2021, 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
|
||||
@ -131,6 +131,10 @@ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
display_gss_error(minor, GSS_C_MECH_CODE, buf, len);
|
||||
|
||||
infof(data, "%s%s\n", prefix, buf);
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
(void)data;
|
||||
(void)prefix;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@ -48,11 +48,13 @@
|
||||
|
||||
#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */
|
||||
|
||||
static CURLcode rtmp_setup_connection(struct connectdata *conn);
|
||||
static CURLcode rtmp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead);
|
||||
static CURLcode rtmp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static CURLcode rtmp_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode rtmp_done(struct Curl_easy *data, CURLcode, bool premature);
|
||||
static CURLcode rtmp_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode rtmp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
|
||||
static Curl_recv rtmp_recv;
|
||||
static Curl_send rtmp_send;
|
||||
@ -193,7 +195,8 @@ const struct Curl_handler Curl_handler_rtmpts = {
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
static CURLcode rtmp_setup_connection(struct connectdata *conn)
|
||||
static CURLcode rtmp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
RTMP *r = RTMP_Alloc();
|
||||
if(!r)
|
||||
@ -201,7 +204,7 @@ static CURLcode rtmp_setup_connection(struct connectdata *conn)
|
||||
|
||||
RTMP_Init(r);
|
||||
RTMP_SetBufferMS(r, DEF_BUFTIME);
|
||||
if(!RTMP_SetupURL(r, conn->data->change.url)) {
|
||||
if(!RTMP_SetupURL(r, data->change.url)) {
|
||||
RTMP_Free(r);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
@ -209,8 +212,9 @@ static CURLcode rtmp_setup_connection(struct connectdata *conn)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
SET_RCVTIMEO(tv, 10);
|
||||
|
||||
@ -243,9 +247,9 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode rtmp_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
|
||||
if(!RTMP_ConnectStream(r, 0))
|
||||
@ -261,20 +265,22 @@ static CURLcode rtmp_do(struct connectdata *conn, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode rtmp_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
(void)conn; /* unused */
|
||||
(void)data; /* unused */
|
||||
(void)status; /* unused */
|
||||
(void)premature; /* unused */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode rtmp_disconnect(struct connectdata *conn,
|
||||
static CURLcode rtmp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
(void)data;
|
||||
(void)dead_connection;
|
||||
if(r) {
|
||||
conn->proto.rtmp = NULL;
|
||||
@ -284,9 +290,10 @@ static CURLcode rtmp_disconnect(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
static ssize_t rtmp_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
size_t len, CURLcode *err)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
ssize_t nread;
|
||||
|
||||
@ -295,8 +302,8 @@ static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
nread = RTMP_Read(r, buf, curlx_uztosi(len));
|
||||
if(nread < 0) {
|
||||
if(r->m_read.status == RTMP_READ_COMPLETE ||
|
||||
r->m_read.status == RTMP_READ_EOF) {
|
||||
conn->data->req.size = conn->data->req.bytecount;
|
||||
r->m_read.status == RTMP_READ_EOF) {
|
||||
data->req.size = data->req.bytecount;
|
||||
nread = 0;
|
||||
}
|
||||
else
|
||||
@ -305,9 +312,10 @@ static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
return nread;
|
||||
}
|
||||
|
||||
static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t rtmp_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t len, CURLcode *err)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
RTMP *r = conn->proto.rtmp;
|
||||
ssize_t num;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2021, 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
|
||||
@ -398,7 +398,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
resp = NULL;
|
||||
}
|
||||
|
||||
result = sasl->params->sendauth(conn, mech, resp);
|
||||
result = sasl->params->sendauth(data, conn, mech, resp);
|
||||
if(!result) {
|
||||
*progress = SASL_INPROGRESS;
|
||||
state(sasl, conn, resp ? state2 : state1);
|
||||
@ -621,12 +621,12 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
switch(result) {
|
||||
case CURLE_BAD_CONTENT_ENCODING:
|
||||
/* Cancel dialog */
|
||||
result = sasl->params->sendcont(conn, "*");
|
||||
result = sasl->params->sendcont(data, conn, "*");
|
||||
newstate = SASL_CANCEL;
|
||||
break;
|
||||
case CURLE_OK:
|
||||
if(resp)
|
||||
result = sasl->params->sendcont(conn, resp);
|
||||
result = sasl->params->sendcont(data, conn, resp);
|
||||
break;
|
||||
default:
|
||||
newstate = SASL_STOP; /* Stop on error */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2021, 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
|
||||
@ -88,10 +88,12 @@ struct SASLproto {
|
||||
int contcode; /* Code to receive when continuation is expected */
|
||||
int finalcode; /* Code to receive upon authentication success */
|
||||
size_t maxirlen; /* Maximum initial response length */
|
||||
CURLcode (*sendauth)(struct connectdata *conn,
|
||||
CURLcode (*sendauth)(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const char *mech, const char *ir);
|
||||
/* Send authentication command */
|
||||
CURLcode (*sendcont)(struct connectdata *conn, const char *contauth);
|
||||
CURLcode (*sendcont)(struct Curl_easy *data,
|
||||
struct connectdata *conn, const char *contauth);
|
||||
/* Send authentication continuation */
|
||||
void (*getmessage)(char *buffer, char **outptr);
|
||||
/* Get SASL response message */
|
||||
|
19
lib/dict.c
19
lib/dict.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -67,7 +67,7 @@
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static CURLcode dict_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode dict_do(struct Curl_easy *data, bool *done);
|
||||
|
||||
/*
|
||||
* DICT protocol handler.
|
||||
@ -129,10 +129,9 @@ static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
|
||||
}
|
||||
|
||||
/* sendf() sends formatted data to the server */
|
||||
static CURLcode sendf(curl_socket_t sockfd, struct connectdata *conn,
|
||||
static CURLcode sendf(curl_socket_t sockfd, struct Curl_easy *data,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
ssize_t bytes_written;
|
||||
size_t write_len;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -151,7 +150,7 @@ static CURLcode sendf(curl_socket_t sockfd, struct connectdata *conn,
|
||||
|
||||
for(;;) {
|
||||
/* Write the buffer to the socket */
|
||||
result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
|
||||
result = Curl_write(data, sockfd, sptr, write_len, &bytes_written);
|
||||
|
||||
if(result)
|
||||
break;
|
||||
@ -173,7 +172,7 @@ static CURLcode sendf(curl_socket_t sockfd, struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode dict_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
char *word;
|
||||
char *eword;
|
||||
@ -183,7 +182,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
char *nthdef = NULL; /* This is not part of the protocol, but required
|
||||
by RFC 2229 */
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
|
||||
char *path = data->state.up.path;
|
||||
@ -230,7 +229,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
if(!eword)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = sendf(sockfd, conn,
|
||||
result = sendf(sockfd, data,
|
||||
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
|
||||
"MATCH "
|
||||
"%s " /* database */
|
||||
@ -278,7 +277,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
if(!eword)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = sendf(sockfd, conn,
|
||||
result = sendf(sockfd, data,
|
||||
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
|
||||
"DEFINE "
|
||||
"%s " /* database */
|
||||
@ -306,7 +305,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
if(ppath[i] == ':')
|
||||
ppath[i] = ' ';
|
||||
}
|
||||
result = sendf(sockfd, conn,
|
||||
result = sendf(sockfd, data,
|
||||
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
|
||||
"%s\r\n"
|
||||
"QUIT\r\n", ppath);
|
||||
|
24
lib/easy.c
24
lib/easy.c
@ -1072,7 +1072,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
/* even if one function returns error, this loops through and frees
|
||||
all buffers */
|
||||
if(!result)
|
||||
result = Curl_client_write(conn, writebuf[i].type,
|
||||
result = Curl_client_write(data, writebuf[i].type,
|
||||
Curl_dyn_ptr(&writebuf[i].b),
|
||||
Curl_dyn_len(&writebuf[i].b));
|
||||
Curl_dyn_free(&writebuf[i].b);
|
||||
@ -1156,8 +1156,13 @@ CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!data->conn)
|
||||
/* on first invoke, the transfer has been detached from the connection and
|
||||
needs to be reattached */
|
||||
Curl_attach_connnection(data, c);
|
||||
|
||||
*n = 0;
|
||||
result = Curl_read(c, sfd, buffer, buflen, &n1);
|
||||
result = Curl_read(data, sfd, buffer, buflen, &n1);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@ -1186,8 +1191,13 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!data->conn)
|
||||
/* on first invoke, the transfer has been detached from the connection and
|
||||
needs to be reattached */
|
||||
Curl_attach_connnection(data, c);
|
||||
|
||||
*n = 0;
|
||||
result = Curl_write(c, sfd, buffer, buflen, &n1);
|
||||
result = Curl_write(data, sfd, buffer, buflen, &n1);
|
||||
|
||||
if(n1 == -1)
|
||||
return CURLE_SEND_ERROR;
|
||||
@ -1206,16 +1216,16 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
|
||||
*
|
||||
* Returns always 0.
|
||||
*/
|
||||
static int conn_upkeep(struct connectdata *conn,
|
||||
static int conn_upkeep(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
void *param)
|
||||
{
|
||||
/* Param is unused. */
|
||||
(void)param;
|
||||
|
||||
if(conn->handler->connection_check) {
|
||||
if(conn->handler->connection_check)
|
||||
/* Do a protocol-specific keepalive check on the connection. */
|
||||
conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE);
|
||||
}
|
||||
conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE);
|
||||
|
||||
return 0; /* continue iteration */
|
||||
}
|
||||
|
69
lib/file.c
69
lib/file.c
@ -81,13 +81,15 @@
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static CURLcode file_do(struct connectdata *, bool *done);
|
||||
static CURLcode file_done(struct connectdata *conn,
|
||||
static CURLcode file_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode file_done(struct Curl_easy *data,
|
||||
CURLcode status, bool premature);
|
||||
static CURLcode file_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode file_disconnect(struct connectdata *conn,
|
||||
static CURLcode file_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode file_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection);
|
||||
static CURLcode file_setup_connection(struct connectdata *conn);
|
||||
static CURLcode file_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* FILE scheme handler.
|
||||
@ -116,11 +118,13 @@ const struct Curl_handler Curl_handler_file = {
|
||||
};
|
||||
|
||||
|
||||
static CURLcode file_setup_connection(struct connectdata *conn)
|
||||
static CURLcode file_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
(void)conn;
|
||||
/* allocate the FILE specific struct */
|
||||
conn->data->req.p.file = calloc(1, sizeof(struct FILEPROTO));
|
||||
if(!conn->data->req.p.file)
|
||||
data->req.p.file = calloc(1, sizeof(struct FILEPROTO));
|
||||
if(!data->req.p.file)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return CURLE_OK;
|
||||
@ -131,9 +135,8 @@ static CURLcode file_setup_connection(struct connectdata *conn)
|
||||
* do protocol-specific actions at connect-time. We emulate a
|
||||
* connect-then-transfer protocol and "connect" to the file here
|
||||
*/
|
||||
static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode file_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *real_path;
|
||||
struct FILEPROTO *file = data->req.p.file;
|
||||
int fd;
|
||||
@ -198,7 +201,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
file->fd = fd;
|
||||
if(!data->set.upload && (fd == -1)) {
|
||||
failf(data, "Couldn't open file %s", data->state.up.path);
|
||||
file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
|
||||
file_done(data, CURLE_FILE_COULDNT_READ_FILE, FALSE);
|
||||
return CURLE_FILE_COULDNT_READ_FILE;
|
||||
}
|
||||
*done = TRUE;
|
||||
@ -206,10 +209,10 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode file_done(struct connectdata *conn,
|
||||
CURLcode status, bool premature)
|
||||
static CURLcode file_done(struct Curl_easy *data,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct FILEPROTO *file = conn->data->req.p.file;
|
||||
struct FILEPROTO *file = data->req.p.file;
|
||||
(void)status; /* not used */
|
||||
(void)premature; /* not used */
|
||||
|
||||
@ -224,11 +227,13 @@ static CURLcode file_done(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode file_disconnect(struct connectdata *conn,
|
||||
static CURLcode file_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
(void)dead_connection; /* not used */
|
||||
return file_done(conn, 0, 0);
|
||||
(void)conn;
|
||||
return file_done(data, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef DOS_FILESYSTEM
|
||||
@ -237,14 +242,13 @@ static CURLcode file_disconnect(struct connectdata *conn,
|
||||
#define DIRSEP '/'
|
||||
#endif
|
||||
|
||||
static CURLcode file_upload(struct connectdata *conn)
|
||||
static CURLcode file_upload(struct Curl_easy *data)
|
||||
{
|
||||
struct FILEPROTO *file = conn->data->req.p.file;
|
||||
struct FILEPROTO *file = data->req.p.file;
|
||||
const char *dir = strchr(file->path, DIRSEP);
|
||||
int fd;
|
||||
int mode;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *buf = data->state.buffer;
|
||||
curl_off_t bytecount = 0;
|
||||
struct_stat file_stat;
|
||||
@ -254,7 +258,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
* Since FILE: doesn't do the full init, we need to provide some extra
|
||||
* assignments here.
|
||||
*/
|
||||
conn->data->req.upload_fromhere = buf;
|
||||
data->req.upload_fromhere = buf;
|
||||
|
||||
if(!dir)
|
||||
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
|
||||
@ -273,7 +277,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
else
|
||||
mode = MODE_DEFAULT|O_TRUNC;
|
||||
|
||||
fd = open(file->path, mode, conn->data->set.new_file_perms);
|
||||
fd = open(file->path, mode, data->set.new_file_perms);
|
||||
if(fd < 0) {
|
||||
failf(data, "Can't open %s for writing", file->path);
|
||||
return CURLE_WRITE_ERROR;
|
||||
@ -297,7 +301,8 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
size_t nread;
|
||||
size_t nwrite;
|
||||
size_t readcount;
|
||||
result = Curl_fillreadbuffer(conn, data->set.buffer_size, &readcount);
|
||||
result = Curl_fillreadbuffer(data->conn, data->set.buffer_size,
|
||||
&readcount);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@ -333,12 +338,12 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
|
||||
Curl_pgrsSetUploadCounter(data, bytecount);
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
if(Curl_pgrsUpdate(data->conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else
|
||||
result = Curl_speedcheck(data, Curl_now());
|
||||
}
|
||||
if(!result && Curl_pgrsUpdate(conn))
|
||||
if(!result && Curl_pgrsUpdate(data->conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
close(fd);
|
||||
@ -354,7 +359,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
* opposed to sockets) we instead perform the whole do-operation in this
|
||||
* function.
|
||||
*/
|
||||
static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode file_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
/* This implementation ignores the host name in conformance with
|
||||
RFC 1738. Only local files (reachable via the standard file system)
|
||||
@ -368,7 +373,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
curl_off_t expected_size = -1;
|
||||
bool size_known;
|
||||
bool fstated = FALSE;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
char *buf = data->state.buffer;
|
||||
curl_off_t bytecount = 0;
|
||||
int fd;
|
||||
@ -379,9 +384,9 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
Curl_pgrsStartNow(data);
|
||||
|
||||
if(data->set.upload)
|
||||
return file_upload(conn);
|
||||
return file_upload(data);
|
||||
|
||||
file = conn->data->req.p.file;
|
||||
file = data->req.p.file;
|
||||
|
||||
/* get the fd from the connection phase */
|
||||
fd = file->fd;
|
||||
@ -411,12 +416,12 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
msnprintf(header, sizeof(header),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n",
|
||||
expected_size);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER,
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER,
|
||||
(char *)"Accept-ranges: bytes\r\n", 0);
|
||||
if(result)
|
||||
return result;
|
||||
@ -437,7 +442,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
tm->tm_min,
|
||||
tm->tm_sec,
|
||||
data->set.opt_no_body ? "": "\r\n");
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0);
|
||||
if(result)
|
||||
return result;
|
||||
/* set the file size to make it available post transfer */
|
||||
@ -516,7 +521,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
if(size_known)
|
||||
expected_size -= nread;
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -31,7 +31,7 @@ extern const struct Curl_handler Curl_handler_ftp;
|
||||
extern const struct Curl_handler Curl_handler_ftps;
|
||||
#endif
|
||||
|
||||
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
|
||||
CURLcode Curl_GetFTPResponse(struct Curl_easy *data, ssize_t *nread,
|
||||
int *ftpcode);
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -268,10 +268,11 @@ static int ftp_pl_get_permission(const char *str)
|
||||
return permissions;
|
||||
}
|
||||
|
||||
static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
|
||||
static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data,
|
||||
struct fileinfo *infop)
|
||||
{
|
||||
curl_fnmatch_callback compare;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct WildcardData *wc = &conn->data->wildcard;
|
||||
struct ftp_wc *ftpwc = wc->protdata;
|
||||
struct Curl_llist *llist = &wc->filelist;
|
||||
@ -327,8 +328,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
void *connptr)
|
||||
{
|
||||
size_t bufflen = size*nmemb;
|
||||
struct connectdata *conn = (struct connectdata *)connptr;
|
||||
struct ftp_wc *ftpwc = conn->data->wildcard.protdata;
|
||||
struct Curl_easy *data = (struct Curl_easy *)connptr;
|
||||
struct ftp_wc *ftpwc = data->wildcard.protdata;
|
||||
struct ftp_parselist_data *parser = ftpwc->parser;
|
||||
struct fileinfo *infop;
|
||||
struct curl_fileinfo *finfo;
|
||||
@ -728,7 +729,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
result = ftp_pl_insert_finfo(conn, infop);
|
||||
result = ftp_pl_insert_finfo(data, infop);
|
||||
if(result) {
|
||||
parser->error = result;
|
||||
goto fail;
|
||||
@ -740,7 +741,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
result = ftp_pl_insert_finfo(conn, infop);
|
||||
result = ftp_pl_insert_finfo(data, infop);
|
||||
if(result) {
|
||||
parser->error = result;
|
||||
goto fail;
|
||||
@ -835,7 +836,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
else if(c == '\n') {
|
||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||
parser->offsets.symlink_target = parser->item_offset;
|
||||
result = ftp_pl_insert_finfo(conn, infop);
|
||||
result = ftp_pl_insert_finfo(data, infop);
|
||||
if(result) {
|
||||
parser->error = result;
|
||||
goto fail;
|
||||
@ -847,7 +848,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
if(c == '\n') {
|
||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||
parser->offsets.symlink_target = parser->item_offset;
|
||||
result = ftp_pl_insert_finfo(conn, infop);
|
||||
result = ftp_pl_insert_finfo(data, infop);
|
||||
if(result) {
|
||||
parser->error = result;
|
||||
goto fail;
|
||||
@ -967,7 +968,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
finfo->b_data[finfo->b_used - 1] = 0;
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
result = ftp_pl_insert_finfo(conn, infop);
|
||||
result = ftp_pl_insert_finfo(data, infop);
|
||||
if(result) {
|
||||
parser->error = result;
|
||||
goto fail;
|
||||
@ -979,7 +980,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
case PL_WINNT_FILENAME_WINEOL:
|
||||
if(c == '\n') {
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
result = ftp_pl_insert_finfo(conn, infop);
|
||||
result = ftp_pl_insert_finfo(data, infop);
|
||||
if(result) {
|
||||
parser->error = result;
|
||||
goto fail;
|
||||
|
25
lib/gopher.c
25
lib/gopher.c
@ -46,10 +46,10 @@
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static CURLcode gopher_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode gopher_do(struct Curl_easy *data, bool *done);
|
||||
#ifdef USE_SSL
|
||||
static CURLcode gopher_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode gopher_connecting(struct connectdata *conn, bool *done);
|
||||
static CURLcode gopher_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode gopher_connecting(struct Curl_easy *data, bool *done);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -103,15 +103,16 @@ const struct Curl_handler Curl_handler_gophers = {
|
||||
PROTOPT_SSL /* flags */
|
||||
};
|
||||
|
||||
static CURLcode gopher_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode gopher_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
(void)conn;
|
||||
(void)data;
|
||||
(void)done;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode gopher_connecting(struct connectdata *conn, bool *done)
|
||||
static CURLcode gopher_connecting(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
CURLcode result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||
if(result)
|
||||
connclose(conn, "Failed TLS connection");
|
||||
@ -120,10 +121,10 @@ static CURLcode gopher_connecting(struct connectdata *conn, bool *done)
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode gopher_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
char *gopherpath;
|
||||
char *path = data->state.up.path;
|
||||
@ -177,9 +178,9 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
if(strlen(sel) < 1)
|
||||
break;
|
||||
|
||||
result = Curl_write(conn, sockfd, sel, k, &amount);
|
||||
result = Curl_write(data, sockfd, sel, k, &amount);
|
||||
if(!result) { /* Which may not have written it all! */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, sel, amount);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@ -219,12 +220,12 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
free(sel_org);
|
||||
|
||||
if(!result)
|
||||
result = Curl_write(conn, sockfd, "\r\n", 2, &amount);
|
||||
result = Curl_write(data, sockfd, "\r\n", 2, &amount);
|
||||
if(result) {
|
||||
failf(data, "Failed sending Gopher request");
|
||||
return result;
|
||||
}
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
@ -565,7 +565,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
||||
if(!addr) {
|
||||
/* Check what IP specifics the app has requested and if we can provide
|
||||
* it. If not, bail out. */
|
||||
if(!Curl_ipvalid(conn))
|
||||
if(!Curl_ipvalid(data, conn))
|
||||
return CURLRESOLV_ERROR;
|
||||
|
||||
if(allowDOH && data->set.doh && !ipnum) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -99,7 +99,7 @@ enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
|
||||
/*
|
||||
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
|
||||
*/
|
||||
bool Curl_ipv6works(struct connectdata *conn);
|
||||
bool Curl_ipv6works(struct Curl_easy *data);
|
||||
#else
|
||||
#define Curl_ipv6works(x) FALSE
|
||||
#endif
|
||||
@ -108,7 +108,7 @@ bool Curl_ipv6works(struct connectdata *conn);
|
||||
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
|
||||
* been set and returns TRUE if they are OK.
|
||||
*/
|
||||
bool Curl_ipvalid(struct connectdata *conn);
|
||||
bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -61,8 +61,9 @@
|
||||
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
|
||||
* been set and returns TRUE if they are OK.
|
||||
*/
|
||||
bool Curl_ipvalid(struct connectdata *conn)
|
||||
bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
(void)data;
|
||||
if(conn->ip_version == CURL_IPRESOLVE_V6)
|
||||
/* An IPv6 address was requested and we can't get/use one */
|
||||
return FALSE;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -62,16 +62,15 @@
|
||||
/*
|
||||
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
|
||||
*/
|
||||
bool Curl_ipv6works(struct connectdata *conn)
|
||||
bool Curl_ipv6works(struct Curl_easy *data)
|
||||
{
|
||||
if(conn) {
|
||||
if(data) {
|
||||
/* the nature of most system is that IPv6 status doesn't come and go
|
||||
during a program's lifetime so we only probe the first time and then we
|
||||
have the info kept for fast re-use */
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(conn->data);
|
||||
DEBUGASSERT(conn->data->multi);
|
||||
return conn->data->multi->ipv6_works;
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->multi);
|
||||
return data->multi->ipv6_works;
|
||||
}
|
||||
else {
|
||||
int ipv6_works = -1;
|
||||
@ -82,7 +81,7 @@ bool Curl_ipv6works(struct connectdata *conn)
|
||||
ipv6_works = 0;
|
||||
else {
|
||||
ipv6_works = 1;
|
||||
Curl_closesocket(NULL, s);
|
||||
sclose(s);
|
||||
}
|
||||
return (ipv6_works>0)?TRUE:FALSE;
|
||||
}
|
||||
@ -92,10 +91,10 @@ bool Curl_ipv6works(struct connectdata *conn)
|
||||
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
|
||||
* been set and returns TRUE if they are OK.
|
||||
*/
|
||||
bool Curl_ipvalid(struct connectdata *conn)
|
||||
bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
if(conn->ip_version == CURL_IPRESOLVE_V6)
|
||||
return Curl_ipv6works(conn);
|
||||
return Curl_ipv6works(data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -161,7 +160,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
if((pf != PF_INET) && !Curl_ipv6works(conn))
|
||||
if((pf != PF_INET) && !Curl_ipv6works(data))
|
||||
/* The stack seems to be a non-IPv6 one */
|
||||
pf = PF_INET;
|
||||
|
||||
|
268
lib/http.c
268
lib/http.c
@ -94,22 +94,25 @@
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static int http_getsock_do(struct connectdata *conn,
|
||||
static int http_getsock_do(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
static bool http_should_fail(struct connectdata *conn);
|
||||
static bool http_should_fail(struct Curl_easy *data);
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
|
||||
static CURLcode add_haproxy_protocol_header(struct Curl_easy *data);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSL
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done);
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
static CURLcode https_connecting(struct Curl_easy *data, bool *done);
|
||||
static int https_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
#else
|
||||
#define https_connecting(x,y) CURLE_COULDNT_CONNECT
|
||||
#endif
|
||||
static CURLcode http_setup_conn(struct connectdata *conn);
|
||||
static CURLcode http_setup_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* HTTP handler interface.
|
||||
@ -165,19 +168,19 @@ const struct Curl_handler Curl_handler_https = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static CURLcode http_setup_conn(struct connectdata *conn)
|
||||
static CURLcode http_setup_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
|
||||
during this request */
|
||||
struct HTTP *http;
|
||||
struct Curl_easy *data = conn->data;
|
||||
DEBUGASSERT(data->req.p.http == NULL);
|
||||
|
||||
http = calloc(1, sizeof(struct HTTP));
|
||||
if(!http)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
Curl_mime_initpart(&http->form, conn->data);
|
||||
Curl_mime_initpart(&http->form, data);
|
||||
data->req.p.http = http;
|
||||
|
||||
if(data->set.httpversion == CURL_HTTP_VERSION_3) {
|
||||
@ -205,16 +208,16 @@ static CURLcode http_setup_conn(struct connectdata *conn)
|
||||
* if proxy headers are not available, then it will lookup into http header
|
||||
* link list
|
||||
*
|
||||
* It takes a connectdata struct as input instead of the Curl_easy simply to
|
||||
* know if this is a proxy request or not, as it then might check a different
|
||||
* header list. Provide the header prefix without colon!.
|
||||
* It takes a connectdata struct as input to see if this is a proxy request or
|
||||
* not, as it then might check a different header list. Provide the header
|
||||
* prefix without colon!
|
||||
*/
|
||||
char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
char *Curl_checkProxyheaders(struct Curl_easy *data,
|
||||
const struct connectdata *conn,
|
||||
const char *thisheader)
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
for(head = (conn->bits.proxy && data->set.sep_headers) ?
|
||||
data->set.proxyheaders : data->set.headers;
|
||||
@ -228,7 +231,7 @@ char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
}
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_checkProxyheaders(x,y) NULL
|
||||
#define Curl_checkProxyheaders(x,y,z) NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -291,11 +294,11 @@ char *Curl_copy_header_value(const char *header)
|
||||
*
|
||||
* Returns CURLcode.
|
||||
*/
|
||||
static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
static CURLcode http_output_basic(struct Curl_easy *data, bool proxy)
|
||||
{
|
||||
size_t size = 0;
|
||||
char *authorization = NULL;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
char **userp;
|
||||
const char *user;
|
||||
const char *pwd;
|
||||
@ -351,16 +354,15 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
*
|
||||
* Returns CURLcode.
|
||||
*/
|
||||
static CURLcode http_output_bearer(struct connectdata *conn)
|
||||
static CURLcode http_output_bearer(struct Curl_easy *data)
|
||||
{
|
||||
char **userp;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
userp = &data->state.aptr.userpwd;
|
||||
free(*userp);
|
||||
*userp = aprintf("Authorization: Bearer %s\r\n",
|
||||
conn->data->set.str[STRING_BEARER]);
|
||||
data->set.str[STRING_BEARER]);
|
||||
|
||||
if(!*userp) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
@ -433,9 +435,9 @@ static bool pickoneauth(struct auth *pick, unsigned long mask)
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
static CURLcode http_perhapsrewind(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *http = data->req.p.http;
|
||||
curl_off_t bytessent;
|
||||
curl_off_t expectsend = -1; /* default is unknown */
|
||||
@ -565,9 +567,9 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
* picked.
|
||||
*/
|
||||
|
||||
CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
CURLcode Curl_http_auth_act(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
bool pickhost = FALSE;
|
||||
bool pickproxy = FALSE;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -593,7 +595,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
conn->httpversion > 11) {
|
||||
infof(data, "Forcing HTTP/1.1 for NTLM");
|
||||
connclose(conn, "Force HTTP/1.1 connection");
|
||||
conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
|
||||
data->set.httpversion = CURL_HTTP_VERSION_1_1;
|
||||
}
|
||||
}
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
@ -611,7 +613,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
if((data->state.httpreq != HTTPREQ_GET) &&
|
||||
(data->state.httpreq != HTTPREQ_HEAD) &&
|
||||
!conn->bits.rewindaftersend) {
|
||||
result = http_perhapsrewind(conn);
|
||||
result = http_perhapsrewind(data, conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -638,7 +640,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
data->state.authhost.done = TRUE;
|
||||
}
|
||||
}
|
||||
if(http_should_fail(conn)) {
|
||||
if(http_should_fail(data)) {
|
||||
failf(data, "The requested URL returned error: %d",
|
||||
data->req.httpcode);
|
||||
result = CURLE_HTTP_RETURNED_ERROR;
|
||||
@ -653,7 +655,8 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
* and whether or not it is to a proxy.
|
||||
*/
|
||||
static CURLcode
|
||||
output_auth_headers(struct connectdata *conn,
|
||||
output_auth_headers(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
struct auth *authstatus,
|
||||
const char *request,
|
||||
const char *path,
|
||||
@ -661,7 +664,6 @@ output_auth_headers(struct connectdata *conn,
|
||||
{
|
||||
const char *auth = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
#ifdef CURL_DISABLE_CRYPTO_AUTH
|
||||
(void)request;
|
||||
@ -720,12 +722,12 @@ output_auth_headers(struct connectdata *conn,
|
||||
if(
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
(proxy && conn->bits.proxy_user_passwd &&
|
||||
!Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
|
||||
!Curl_checkProxyheaders(data, conn, "Proxy-authorization")) ||
|
||||
#endif
|
||||
(!proxy && conn->bits.user_passwd &&
|
||||
!Curl_checkheaders(conn, "Authorization"))) {
|
||||
!Curl_checkheaders(data, "Authorization"))) {
|
||||
auth = "Basic";
|
||||
result = http_output_basic(conn, proxy);
|
||||
result = http_output_basic(data, proxy);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -737,9 +739,9 @@ output_auth_headers(struct connectdata *conn,
|
||||
if(authstatus->picked == CURLAUTH_BEARER) {
|
||||
/* Bearer */
|
||||
if((!proxy && data->set.str[STRING_BEARER] &&
|
||||
!Curl_checkheaders(conn, "Authorization:"))) {
|
||||
!Curl_checkheaders(data, "Authorization:"))) {
|
||||
auth = "Bearer";
|
||||
result = http_output_bearer(conn);
|
||||
result = http_output_bearer(data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -770,7 +772,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
/**
|
||||
* Curl_http_output_auth() setups the authentication headers for the
|
||||
* host/proxy and the correct authentication
|
||||
* method. conn->data->state.authdone is set to TRUE when authentication is
|
||||
* method. data->state.authdone is set to TRUE when authentication is
|
||||
* done.
|
||||
*
|
||||
* @param conn all information about the current connection
|
||||
@ -782,7 +784,8 @@ output_auth_headers(struct connectdata *conn,
|
||||
* @returns CURLcode
|
||||
*/
|
||||
CURLcode
|
||||
Curl_http_output_auth(struct connectdata *conn,
|
||||
Curl_http_output_auth(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const char *request,
|
||||
Curl_HttpReq httpreq,
|
||||
const char *path,
|
||||
@ -790,7 +793,6 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
up the proxy tunnel */
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct auth *authhost;
|
||||
struct auth *authproxy;
|
||||
|
||||
@ -827,7 +829,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
/* Send proxy authentication header if needed */
|
||||
if(conn->bits.httpproxy &&
|
||||
(conn->bits.tunnel_proxy == (bit)proxytunnel)) {
|
||||
result = output_auth_headers(conn, authproxy, request, path, TRUE);
|
||||
result = output_auth_headers(data, conn, authproxy, request, path, TRUE);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -846,7 +848,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
!data->state.first_host ||
|
||||
data->set.allow_auth_to_other_hosts ||
|
||||
strcasecompare(data->state.first_host, conn->host.name)) {
|
||||
result = output_auth_headers(conn, authhost, request, path, FALSE);
|
||||
result = output_auth_headers(data, conn, authhost, request, path, FALSE);
|
||||
}
|
||||
else
|
||||
authhost->done = TRUE;
|
||||
@ -887,14 +889,13 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
* proxy CONNECT loop.
|
||||
*/
|
||||
|
||||
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
|
||||
const char *auth) /* the first non-space */
|
||||
{
|
||||
/*
|
||||
* This resource requires authentication
|
||||
*/
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
struct connectdata *conn = data->conn;
|
||||
#ifdef USE_SPNEGO
|
||||
curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state :
|
||||
&conn->http_negotiate_state;
|
||||
@ -1062,14 +1063,11 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
*
|
||||
* @retval TRUE communications should not continue
|
||||
*/
|
||||
static bool http_should_fail(struct connectdata *conn)
|
||||
static bool http_should_fail(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_easy *data;
|
||||
int httpcode;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
data = conn->data;
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
|
||||
httpcode = data->req.httpcode;
|
||||
|
||||
@ -1116,10 +1114,10 @@ static bool http_should_fail(struct connectdata *conn)
|
||||
** Either we're not authenticating, or we're supposed to
|
||||
** be authenticating something else. This is an error.
|
||||
*/
|
||||
if((httpcode == 401) && !conn->bits.user_passwd)
|
||||
if((httpcode == 401) && !data->conn->bits.user_passwd)
|
||||
return TRUE;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if((httpcode == 407) && !conn->bits.proxy_user_passwd)
|
||||
if((httpcode == 407) && !data->conn->bits.proxy_user_passwd)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
@ -1140,8 +1138,8 @@ static size_t readmoredata(char *buffer,
|
||||
size_t nitems,
|
||||
void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct HTTP *http = conn->data->req.p.http;
|
||||
struct Curl_easy *data = (struct Curl_easy *)userp;
|
||||
struct HTTP *http = data->req.p.http;
|
||||
size_t fullsize = size * nitems;
|
||||
|
||||
if(!http->postsize)
|
||||
@ -1149,7 +1147,7 @@ static size_t readmoredata(char *buffer,
|
||||
return 0;
|
||||
|
||||
/* make sure that a HTTP request is never sent away chunked! */
|
||||
conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
|
||||
data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
|
||||
|
||||
if(http->postsize <= (curl_off_t)fullsize) {
|
||||
memcpy(buffer, http->postdata, (size_t)http->postsize);
|
||||
@ -1159,8 +1157,8 @@ static size_t readmoredata(char *buffer,
|
||||
/* move backup data into focus and continue on that */
|
||||
http->postdata = http->backup.postdata;
|
||||
http->postsize = http->backup.postsize;
|
||||
conn->data->state.fread_func = http->backup.fread_func;
|
||||
conn->data->state.in = http->backup.fread_in;
|
||||
data->state.fread_func = http->backup.fread_func;
|
||||
data->state.in = http->backup.fread_in;
|
||||
|
||||
http->sending++; /* move one step up */
|
||||
|
||||
@ -1186,7 +1184,7 @@ static size_t readmoredata(char *buffer,
|
||||
* Returns CURLcode
|
||||
*/
|
||||
CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
/* add the number of sent bytes to this
|
||||
counter */
|
||||
curl_off_t *bytes_written,
|
||||
@ -1198,7 +1196,7 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
CURLcode result;
|
||||
char *ptr;
|
||||
size_t size;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct HTTP *http = data->req.p.http;
|
||||
size_t sendsize;
|
||||
curl_socket_t sockfd;
|
||||
@ -1274,7 +1272,7 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
sendsize = size;
|
||||
}
|
||||
|
||||
result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
|
||||
result = Curl_write(data, sockfd, ptr, sendsize, &amount);
|
||||
|
||||
if(!result) {
|
||||
/*
|
||||
@ -1321,7 +1319,7 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
|
||||
/* set the new pointers for the request-sending */
|
||||
data->state.fread_func = (curl_read_callback)readmoredata;
|
||||
data->state.in = (void *)conn;
|
||||
data->state.in = (void *)data;
|
||||
http->postdata = ptr;
|
||||
http->postsize = (curl_off_t)size;
|
||||
|
||||
@ -1421,9 +1419,10 @@ Curl_compareheader(const char *headerline, /* line to check */
|
||||
* Curl_http_connect() performs HTTP stuff to do at connect-time, called from
|
||||
* the generic Curl_connect().
|
||||
*/
|
||||
CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
CURLcode Curl_http_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
/* We default to persistent connections. We set this already in this connect
|
||||
function to make the re-use checks properly be able to check this bit. */
|
||||
@ -1446,9 +1445,9 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
/* nothing else to do except wait right now - we're not done here. */
|
||||
return CURLE_OK;
|
||||
|
||||
if(conn->data->set.haproxyprotocol) {
|
||||
if(data->set.haproxyprotocol) {
|
||||
/* add HAProxy PROXY protocol header */
|
||||
result = add_haproxy_protocol_header(conn);
|
||||
result = add_haproxy_protocol_header(data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -1456,7 +1455,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
if(conn->given->protocol & CURLPROTO_HTTPS) {
|
||||
/* perform SSL initialization */
|
||||
result = https_connecting(conn, done);
|
||||
result = https_connecting(data, done);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -1469,24 +1468,27 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
/* this returns the socket to wait for in the DO and DOING state for the multi
|
||||
interface and then we're always _sending_ a request and thus we wait for
|
||||
the single socket to become writable only */
|
||||
static int http_getsock_do(struct connectdata *conn,
|
||||
static int http_getsock_do(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
/* write mode */
|
||||
(void)data;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
|
||||
static CURLcode add_haproxy_protocol_header(struct Curl_easy *data)
|
||||
{
|
||||
char proxy_header[128];
|
||||
struct dynbuf req;
|
||||
CURLcode result;
|
||||
char tcp_version[5];
|
||||
DEBUGASSERT(data->conn);
|
||||
|
||||
/* Emit the correct prefix for IPv6 */
|
||||
if(conn->bits.ipv6) {
|
||||
if(data->conn->bits.ipv6) {
|
||||
strcpy(tcp_version, "TCP6");
|
||||
}
|
||||
else {
|
||||
@ -1497,10 +1499,10 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
|
||||
sizeof(proxy_header),
|
||||
"PROXY %s %s %s %li %li\r\n",
|
||||
tcp_version,
|
||||
conn->data->info.conn_local_ip,
|
||||
conn->data->info.conn_primary_ip,
|
||||
conn->data->info.conn_local_port,
|
||||
conn->data->info.conn_primary_port);
|
||||
data->info.conn_local_ip,
|
||||
data->info.conn_primary_ip,
|
||||
data->info.conn_local_port,
|
||||
data->info.conn_primary_port);
|
||||
|
||||
Curl_dyn_init(&req, DYN_HAXPROXY);
|
||||
|
||||
@ -1508,7 +1510,7 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_buffer_send(&req, conn, &conn->data->info.request_size,
|
||||
result = Curl_buffer_send(&req, data, &data->info.request_size,
|
||||
0, FIRSTSOCKET);
|
||||
|
||||
return result;
|
||||
@ -1516,10 +1518,11 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSL
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
static CURLcode https_connecting(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
|
||||
struct connectdata *conn = data->conn;
|
||||
DEBUGASSERT((data) && (data->conn->handler->flags & PROTOPT_SSL));
|
||||
|
||||
#ifdef ENABLE_QUIC
|
||||
if(conn->transport == TRNSPRT_QUIC) {
|
||||
@ -1536,9 +1539,11 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
static int https_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
(void)data;
|
||||
if(conn->handler->flags & PROTOPT_SSL)
|
||||
return Curl_ssl_getsock(conn, socks);
|
||||
return GETSOCK_BLANK;
|
||||
@ -1550,10 +1555,10 @@ static int https_getsock(struct connectdata *conn,
|
||||
* performed.
|
||||
*/
|
||||
|
||||
CURLcode Curl_http_done(struct connectdata *conn,
|
||||
CURLcode Curl_http_done(struct Curl_easy *data,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct HTTP *http = data->req.p.http;
|
||||
|
||||
/* Clear multipass flag. If authentication isn't done yet, then it will get
|
||||
@ -1653,7 +1658,7 @@ static CURLcode expect100(struct Curl_easy *data,
|
||||
/* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
|
||||
Expect: 100-continue to the headers which actually speeds up post
|
||||
operations (as there is one packet coming back from the web server) */
|
||||
const char *ptr = Curl_checkheaders(conn, "Expect");
|
||||
const char *ptr = Curl_checkheaders(data, "Expect");
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
@ -1719,7 +1724,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
CURLcode Curl_add_custom_headers(struct Curl_easy *data,
|
||||
bool is_connect,
|
||||
#ifndef USE_HYPER
|
||||
struct dynbuf *req
|
||||
@ -1728,11 +1733,11 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
char *ptr;
|
||||
struct curl_slist *h[2];
|
||||
struct curl_slist *headers;
|
||||
int numlists = 1; /* by default */
|
||||
struct Curl_easy *data = conn->data;
|
||||
int i;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
@ -1876,15 +1881,14 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PARSEDATE
|
||||
CURLcode Curl_add_timecondition(const struct connectdata *conn,
|
||||
CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
#ifndef USE_HYPER
|
||||
struct dynbuf *req
|
||||
struct dynbuf *req
|
||||
#else
|
||||
void *req
|
||||
void *req
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
const struct tm *tm;
|
||||
struct tm keeptime;
|
||||
CURLcode result;
|
||||
@ -1917,7 +1921,7 @@ CURLcode Curl_add_timecondition(const struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
if(Curl_checkheaders(conn, condp)) {
|
||||
if(Curl_checkheaders(data, condp)) {
|
||||
/* A custom header was specified; it will be sent instead. */
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -2000,13 +2004,13 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
|
||||
*reqp = httpreq;
|
||||
}
|
||||
|
||||
CURLcode Curl_http_useragent(struct Curl_easy *data, struct connectdata *conn)
|
||||
CURLcode Curl_http_useragent(struct Curl_easy *data)
|
||||
{
|
||||
/* The User-Agent string might have been allocated in url.c already, because
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(Curl_checkheaders(conn, "User-Agent")) {
|
||||
if(Curl_checkheaders(data, "User-Agent")) {
|
||||
free(data->state.aptr.uagent);
|
||||
data->state.aptr.uagent = NULL;
|
||||
}
|
||||
@ -2029,7 +2033,7 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
|
||||
}
|
||||
Curl_safefree(data->state.aptr.host);
|
||||
|
||||
ptr = Curl_checkheaders(conn, "Host");
|
||||
ptr = Curl_checkheaders(data, "Host");
|
||||
if(ptr && (!data->state.this_is_a_follow ||
|
||||
strcasecompare(data->state.first_host, conn->host.name))) {
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
@ -2245,7 +2249,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
|
||||
|
||||
#ifndef CURL_DISABLE_MIME
|
||||
if(http->sendit) {
|
||||
const char *cthdr = Curl_checkheaders(conn, "Content-Type");
|
||||
const char *cthdr = Curl_checkheaders(data, "Content-Type");
|
||||
|
||||
/* Read and seek body only. */
|
||||
http->sendit->flags |= MIME_BODY_ONLY;
|
||||
@ -2270,7 +2274,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr = Curl_checkheaders(conn, "Transfer-Encoding");
|
||||
ptr = Curl_checkheaders(data, "Transfer-Encoding");
|
||||
if(ptr) {
|
||||
/* Some kind of TE is requested, check if 'chunked' is chosen */
|
||||
data->req.upload_chunky =
|
||||
@ -2331,7 +2335,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
http->postsize = data->state.infilesize;
|
||||
|
||||
if((http->postsize != -1) && !data->req.upload_chunky &&
|
||||
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
|
||||
(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
result = Curl_dyn_addf(r, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
|
||||
"\r\n", http->postsize);
|
||||
@ -2354,7 +2358,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||
|
||||
/* this sends the buffer and frees all the buffer resources */
|
||||
result = Curl_buffer_send(r, conn, &data->info.request_size, 0,
|
||||
result = Curl_buffer_send(r, data, &data->info.request_size, 0,
|
||||
FIRSTSOCKET);
|
||||
if(result)
|
||||
failf(data, "Failed sending PUT request");
|
||||
@ -2375,7 +2379,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_buffer_send(r, conn, &data->info.request_size, 0,
|
||||
result = Curl_buffer_send(r, data, &data->info.request_size, 0,
|
||||
FIRSTSOCKET);
|
||||
if(result)
|
||||
failf(data, "Failed sending POST request");
|
||||
@ -2391,7 +2395,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
|
||||
if(http->postsize != -1 && !data->req.upload_chunky &&
|
||||
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
|
||||
(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
|
||||
/* we allow replacing this header if not during auth negotiation,
|
||||
although it isn't very wise to actually set your own */
|
||||
result = Curl_dyn_addf(r,
|
||||
@ -2418,7 +2422,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
the somewhat bigger ones we allow the app to disable it. Just make
|
||||
sure that the expect100header is always set to the preferred value
|
||||
here. */
|
||||
ptr = Curl_checkheaders(conn, "Expect");
|
||||
ptr = Curl_checkheaders(data, "Expect");
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
@ -2445,7 +2449,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
http->sending = HTTPSEND_BODY;
|
||||
|
||||
/* this sends the buffer and frees all the buffer resources */
|
||||
result = Curl_buffer_send(r, conn, &data->info.request_size, 0,
|
||||
result = Curl_buffer_send(r, data, &data->info.request_size, 0,
|
||||
FIRSTSOCKET);
|
||||
if(result)
|
||||
failf(data, "Failed sending POST request");
|
||||
@ -2471,7 +2475,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
|
||||
if((http->postsize != -1) && !data->req.upload_chunky &&
|
||||
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
|
||||
(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
|
||||
/* we allow replacing this header if not during auth negotiation,
|
||||
although it isn't very wise to actually set your own */
|
||||
result = Curl_dyn_addf(r, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
|
||||
@ -2480,7 +2484,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!Curl_checkheaders(conn, "Content-Type")) {
|
||||
if(!Curl_checkheaders(data, "Content-Type")) {
|
||||
result = Curl_dyn_add(r, "Content-Type: application/"
|
||||
"x-www-form-urlencoded\r\n");
|
||||
if(result)
|
||||
@ -2491,7 +2495,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
the somewhat bigger ones we allow the app to disable it. Just make
|
||||
sure that the expect100header is always set to the preferred value
|
||||
here. */
|
||||
ptr = Curl_checkheaders(conn, "Expect");
|
||||
ptr = Curl_checkheaders(data, "Expect");
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
@ -2565,7 +2569,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
http->sending = HTTPSEND_BODY;
|
||||
|
||||
data->state.fread_func = (curl_read_callback)readmoredata;
|
||||
data->state.in = (void *)conn;
|
||||
data->state.in = (void *)data;
|
||||
|
||||
/* set the upload size to the progress meter */
|
||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||
@ -2604,7 +2608,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
/* issue the request */
|
||||
result = Curl_buffer_send(r, conn, &data->info.request_size,
|
||||
result = Curl_buffer_send(r, data, &data->info.request_size,
|
||||
(size_t)included_body, FIRSTSOCKET);
|
||||
|
||||
if(result)
|
||||
@ -2620,7 +2624,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
|
||||
return result;
|
||||
|
||||
/* issue the request */
|
||||
result = Curl_buffer_send(r, conn, &data->info.request_size, 0,
|
||||
result = Curl_buffer_send(r, data, &data->info.request_size, 0,
|
||||
FIRSTSOCKET);
|
||||
|
||||
if(result)
|
||||
@ -2640,7 +2644,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *addcookies = NULL;
|
||||
if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
|
||||
if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie"))
|
||||
addcookies = data->set.str[STRING_COOKIE];
|
||||
|
||||
if(data->cookies || addcookies) {
|
||||
@ -2697,7 +2701,6 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
|
||||
#endif
|
||||
|
||||
CURLcode Curl_http_range(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
Curl_HttpReq httpreq)
|
||||
{
|
||||
if(data->state.use_range) {
|
||||
@ -2707,14 +2710,14 @@ CURLcode Curl_http_range(struct Curl_easy *data,
|
||||
* ones if any such are specified.
|
||||
*/
|
||||
if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
|
||||
!Curl_checkheaders(conn, "Range")) {
|
||||
!Curl_checkheaders(data, "Range")) {
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
free(data->state.aptr.rangeline);
|
||||
data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
|
||||
data->state.range);
|
||||
}
|
||||
else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
|
||||
!Curl_checkheaders(conn, "Content-Range")) {
|
||||
!Curl_checkheaders(data, "Content-Range")) {
|
||||
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
free(data->state.aptr.rangeline);
|
||||
@ -2902,9 +2905,9 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
* request is to be performed. This creates and sends a properly constructed
|
||||
* HTTP request.
|
||||
*/
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct HTTP *http;
|
||||
Curl_HttpReq httpreq;
|
||||
@ -2927,7 +2930,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
case CURL_HTTP_VERSION_2:
|
||||
conn->httpversion = 20; /* we know we're on HTTP/2 now */
|
||||
|
||||
result = Curl_http2_switched(conn, NULL, 0);
|
||||
result = Curl_http2_switched(data, NULL, 0);
|
||||
if(result)
|
||||
return result;
|
||||
break;
|
||||
@ -2937,8 +2940,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
default:
|
||||
/* Check if user wants to use HTTP/2 with clear TCP*/
|
||||
#ifdef USE_NGHTTP2
|
||||
if(conn->data->set.httpversion ==
|
||||
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
|
||||
if(data->set.httpversion == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
|
||||
/* We don't support HTTP/2 proxies yet. Also it's debatable
|
||||
@ -2950,7 +2952,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
|
||||
conn->httpversion = 20;
|
||||
|
||||
result = Curl_http2_switched(conn, NULL, 0);
|
||||
result = Curl_http2_switched(data, NULL, 0);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -2960,7 +2962,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
else {
|
||||
/* prepare for a http2 request */
|
||||
result = Curl_http2_setup(conn);
|
||||
result = Curl_http2_setup(data, conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -2972,7 +2974,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_http_useragent(data, conn);
|
||||
result = Curl_http_useragent(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -2986,7 +2988,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(!pq)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
result = Curl_http_output_auth(conn, request, httpreq,
|
||||
result = Curl_http_output_auth(data, conn, request, httpreq,
|
||||
(pq ? pq : data->state.up.path), FALSE);
|
||||
free(pq);
|
||||
if(result)
|
||||
@ -2994,13 +2996,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
Curl_safefree(data->state.aptr.ref);
|
||||
if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
|
||||
if(data->change.referer && !Curl_checkheaders(data, "Referer")) {
|
||||
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
|
||||
if(!data->state.aptr.ref)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!Curl_checkheaders(conn, "Accept-Encoding") &&
|
||||
if(!Curl_checkheaders(data, "Accept-Encoding") &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
Curl_safefree(data->state.aptr.accept_encoding);
|
||||
data->state.aptr.accept_encoding =
|
||||
@ -3016,14 +3018,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
#ifdef HAVE_LIBZ
|
||||
/* we only consider transfer-encoding magic if libz support is built-in */
|
||||
|
||||
if(!Curl_checkheaders(conn, "TE") &&
|
||||
if(!Curl_checkheaders(data, "TE") &&
|
||||
data->set.http_transfer_encoding) {
|
||||
/* When we are to insert a TE: header in the request, we must also insert
|
||||
TE in a Connection: header, so we need to merge the custom provided
|
||||
Connection: header and prevent the original to get sent. Note that if
|
||||
the user has inserted his/her own TE: header we don't do this magic
|
||||
but then assume that the user will handle it all! */
|
||||
char *cptr = Curl_checkheaders(conn, "Connection");
|
||||
char *cptr = Curl_checkheaders(data, "Connection");
|
||||
#define TE_HEADER "TE: gzip\r\n"
|
||||
|
||||
Curl_safefree(data->state.aptr.te);
|
||||
@ -3048,13 +3050,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n";
|
||||
p_accept = Curl_checkheaders(data, "Accept")?NULL:"Accept: */*\r\n";
|
||||
|
||||
result = Curl_http_resume(data, conn, httpreq);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_http_range(data, conn, httpreq);
|
||||
result = Curl_http_range(data, httpreq);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -3074,7 +3076,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_ALTSVC
|
||||
if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) {
|
||||
if(conn->bits.altused && !Curl_checkheaders(data, "Alt-Used")) {
|
||||
altused = aprintf("Alt-Used: %s:%d\r\n",
|
||||
conn->conn_to_host.name, conn->conn_to_port);
|
||||
if(!altused) {
|
||||
@ -3121,7 +3123,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
(conn->bits.httpproxy &&
|
||||
!conn->bits.tunnel_proxy &&
|
||||
!Curl_checkProxyheaders(conn, "Proxy-Connection"))?
|
||||
!Curl_checkProxyheaders(data, conn, "Proxy-Connection"))?
|
||||
"Proxy-Connection: Keep-Alive\r\n":"",
|
||||
#else
|
||||
"",
|
||||
@ -3155,9 +3157,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
result = Curl_http_cookies(data, conn, &req);
|
||||
if(!result)
|
||||
result = Curl_add_timecondition(conn, &req);
|
||||
result = Curl_add_timecondition(data, &req);
|
||||
if(!result)
|
||||
result = Curl_add_custom_headers(conn, FALSE, &req);
|
||||
result = Curl_add_custom_headers(data, FALSE, &req);
|
||||
|
||||
if(!result) {
|
||||
http->postdata = NULL; /* nothing to post at this point */
|
||||
@ -3515,7 +3517,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
if(!auth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = Curl_http_input_auth(conn, proxy, auth);
|
||||
result = Curl_http_input_auth(data, proxy, auth);
|
||||
|
||||
free(auth);
|
||||
|
||||
@ -3560,7 +3562,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
|
||||
|
||||
/* some cases of POST and PUT etc needs to rewind the data
|
||||
stream at this point */
|
||||
result = http_perhapsrewind(conn);
|
||||
result = http_perhapsrewind(data, conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -3849,7 +3851,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
|
||||
/* switch to http2 now. The bytes after response headers
|
||||
are also processed here, otherwise they are lost. */
|
||||
result = Curl_http2_switched(conn, k->str, *nread);
|
||||
result = Curl_http2_switched(data, k->str, *nread);
|
||||
if(result)
|
||||
return result;
|
||||
*nread = 0;
|
||||
@ -3923,7 +3925,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
|
||||
headerlen = Curl_dyn_len(&data->state.headerb);
|
||||
result = Curl_client_write(conn, writetype,
|
||||
result = Curl_client_write(data, writetype,
|
||||
Curl_dyn_ptr(&data->state.headerb),
|
||||
headerlen);
|
||||
if(result)
|
||||
@ -3936,7 +3938,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
* When all the headers have been parsed, see if we should give
|
||||
* up and return an error.
|
||||
*/
|
||||
if(http_should_fail(conn)) {
|
||||
if(http_should_fail(data)) {
|
||||
failf(data, "The requested URL returned error: %d",
|
||||
k->httpcode);
|
||||
return CURLE_HTTP_RETURNED_ERROR;
|
||||
@ -3948,7 +3950,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
/* Curl_http_auth_act() checks what authentication methods
|
||||
* that are available and decides which one (if any) to
|
||||
* use. It will set 'newurl' if an auth method was picked. */
|
||||
result = Curl_http_auth_act(conn);
|
||||
result = Curl_http_auth_act(data);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@ -3986,8 +3988,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
infof(data, "Got 417 while waiting for a 100\n");
|
||||
data->state.disableexpect = TRUE;
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(conn->data->change.url);
|
||||
Curl_done_sending(conn, k);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
Curl_done_sending(data, k);
|
||||
}
|
||||
else if(data->set.http_keep_sending_on_error) {
|
||||
infof(data, "HTTP error before end of send, keep sending\n");
|
||||
@ -3999,7 +4001,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
else {
|
||||
infof(data, "HTTP error before end of send, stop sending\n");
|
||||
streamclose(conn, "Stop sending data before everything sent");
|
||||
result = Curl_done_sending(conn, k);
|
||||
result = Curl_done_sending(data, k);
|
||||
if(result)
|
||||
return result;
|
||||
k->upload_done = TRUE;
|
||||
@ -4237,7 +4239,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, headp,
|
||||
Curl_dyn_len(&data->state.headerb));
|
||||
|
||||
result = Curl_client_write(conn, writetype, headp,
|
||||
result = Curl_client_write(data, writetype, headp,
|
||||
Curl_dyn_len(&data->state.headerb));
|
||||
if(result)
|
||||
return result;
|
||||
|
29
lib/http.h
29
lib/http.h
@ -51,11 +51,12 @@ bool Curl_compareheader(const char *headerline, /* line to check */
|
||||
|
||||
char *Curl_copy_header_value(const char *header);
|
||||
|
||||
char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
char *Curl_checkProxyheaders(struct Curl_easy *data,
|
||||
const struct connectdata *conn,
|
||||
const char *thisheader);
|
||||
#ifndef USE_HYPER
|
||||
CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
curl_off_t *bytes_written,
|
||||
size_t included_body_bytes,
|
||||
int socketindex);
|
||||
@ -63,14 +64,14 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
|
||||
#define Curl_buffer_send(a,b,c,d,e) CURLE_OK
|
||||
#endif
|
||||
|
||||
CURLcode Curl_add_timecondition(const struct connectdata *conn,
|
||||
CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
#ifndef USE_HYPER
|
||||
struct dynbuf *req
|
||||
struct dynbuf *req
|
||||
#else
|
||||
void *headers
|
||||
void *headers
|
||||
#endif
|
||||
);
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
CURLcode Curl_add_custom_headers(struct Curl_easy *data,
|
||||
bool is_connect,
|
||||
#ifndef USE_HYPER
|
||||
struct dynbuf *req
|
||||
@ -84,7 +85,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
|
||||
|
||||
void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
|
||||
const char **method, Curl_HttpReq *);
|
||||
CURLcode Curl_http_useragent(struct Curl_easy *data, struct connectdata *conn);
|
||||
CURLcode Curl_http_useragent(struct Curl_easy *data);
|
||||
CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn);
|
||||
CURLcode Curl_http_target(struct Curl_easy *data, struct connectdata *conn,
|
||||
struct dynbuf *req);
|
||||
@ -108,21 +109,20 @@ CURLcode Curl_http_resume(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
Curl_HttpReq httpreq);
|
||||
CURLcode Curl_http_range(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
Curl_HttpReq httpreq);
|
||||
CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool *done);
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
|
||||
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_http(struct Curl_easy *data, bool *done);
|
||||
CURLcode Curl_http_done(struct Curl_easy *data, CURLcode, bool premature);
|
||||
CURLcode Curl_http_connect(struct Curl_easy *data, bool *done);
|
||||
|
||||
/* These functions are in http.c */
|
||||
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
|
||||
const char *auth);
|
||||
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
||||
CURLcode Curl_http_auth_act(struct Curl_easy *data);
|
||||
|
||||
/* If only the PICKNONE bit is set, there has been a round-trip and we
|
||||
selected to use no auth at all. Ie, we actively select no auth, as opposed
|
||||
@ -301,7 +301,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
* @returns CURLcode
|
||||
*/
|
||||
CURLcode
|
||||
Curl_http_output_auth(struct connectdata *conn,
|
||||
Curl_http_output_auth(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const char *request,
|
||||
Curl_HttpReq httpreq,
|
||||
const char *path,
|
||||
|
204
lib/http2.c
204
lib/http2.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -65,12 +65,13 @@
|
||||
#endif
|
||||
|
||||
|
||||
static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err);
|
||||
static bool http2_connisdead(struct connectdata *conn);
|
||||
static bool http2_connisdead(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static int h2_session_send(struct Curl_easy *data,
|
||||
nghttp2_session *h2);
|
||||
static int h2_process_pending_input(struct connectdata *conn,
|
||||
static int h2_process_pending_input(struct Curl_easy *data,
|
||||
struct http_conn *httpc,
|
||||
CURLcode *err);
|
||||
|
||||
@ -92,11 +93,12 @@ void Curl_http2_init_userset(struct UserDefined *set)
|
||||
set->stream_weight = NGHTTP2_DEFAULT_WEIGHT;
|
||||
}
|
||||
|
||||
static int http2_perform_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
static int http2_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
{
|
||||
const struct http_conn *c = &conn->proto.httpc;
|
||||
struct SingleRequest *k = &conn->data->req;
|
||||
struct SingleRequest *k = &data->req;
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
@ -114,12 +116,6 @@ static int http2_perform_getsock(const struct connectdata *conn,
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static int http2_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
return http2_perform_getsock(conn, socks);
|
||||
}
|
||||
|
||||
/*
|
||||
* http2_stream_free() free HTTP2 stream related data
|
||||
*/
|
||||
@ -140,18 +136,22 @@ static void http2_stream_free(struct HTTP *http)
|
||||
* connection cache and not the "main" one. Don't touch the easy handle!
|
||||
*/
|
||||
|
||||
static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
static CURLcode http2_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
(void)dead_connection;
|
||||
#ifndef DEBUG_HTTP2
|
||||
(void)data;
|
||||
#endif
|
||||
|
||||
H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
|
||||
H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now\n"));
|
||||
|
||||
nghttp2_session_del(c->h2);
|
||||
Curl_safefree(c->inbuf);
|
||||
|
||||
H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
|
||||
H2BUGF(infof(data, "HTTP/2 DISCONNECT done\n"));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -163,7 +163,7 @@ static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
* Instead, if it is readable, run Curl_connalive() to peek at the socket
|
||||
* and distinguish between closed and data.
|
||||
*/
|
||||
static bool http2_connisdead(struct connectdata *conn)
|
||||
static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
int sval;
|
||||
bool dead = TRUE;
|
||||
@ -193,14 +193,14 @@ static bool http2_connisdead(struct connectdata *conn)
|
||||
if(httpc->recv_underlying)
|
||||
/* if called "too early", this pointer isn't setup yet! */
|
||||
nread = ((Curl_recv *)httpc->recv_underlying)(
|
||||
conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
|
||||
data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
|
||||
if(nread != -1) {
|
||||
infof(conn->data,
|
||||
infof(data,
|
||||
"%d bytes stray data read before trying h2 connection\n",
|
||||
(int)nread);
|
||||
httpc->nread_inbuf = 0;
|
||||
httpc->inbuflen = nread;
|
||||
(void)h2_process_pending_input(conn, httpc, &result);
|
||||
(void)h2_process_pending_input(data, httpc, &result);
|
||||
}
|
||||
else
|
||||
/* the read failed so let's say this is dead anyway */
|
||||
@ -211,24 +211,25 @@ static bool http2_connisdead(struct connectdata *conn)
|
||||
return dead;
|
||||
}
|
||||
|
||||
static unsigned int http2_conncheck(struct connectdata *check,
|
||||
static unsigned int http2_conncheck(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
unsigned int checks_to_perform)
|
||||
{
|
||||
unsigned int ret_val = CONNRESULT_NONE;
|
||||
struct http_conn *c = &check->proto.httpc;
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
int rc;
|
||||
bool send_frames = false;
|
||||
|
||||
if(checks_to_perform & CONNCHECK_ISDEAD) {
|
||||
if(http2_connisdead(check))
|
||||
if(http2_connisdead(data, conn))
|
||||
ret_val |= CONNRESULT_DEAD;
|
||||
}
|
||||
|
||||
if(checks_to_perform & CONNCHECK_KEEPALIVE) {
|
||||
struct curltime now = Curl_now();
|
||||
timediff_t elapsed = Curl_timediff(now, check->keepalive);
|
||||
timediff_t elapsed = Curl_timediff(now, conn->keepalive);
|
||||
|
||||
if(elapsed > check->upkeep_interval_ms) {
|
||||
if(elapsed > conn->upkeep_interval_ms) {
|
||||
/* Perform an HTTP/2 PING */
|
||||
rc = nghttp2_submit_ping(c->h2, 0, ZERO_NULL);
|
||||
if(!rc) {
|
||||
@ -237,18 +238,18 @@ static unsigned int http2_conncheck(struct connectdata *check,
|
||||
send_frames = true;
|
||||
}
|
||||
else {
|
||||
failf(check->data, "nghttp2_submit_ping() failed: %s(%d)",
|
||||
failf(data, "nghttp2_submit_ping() failed: %s(%d)",
|
||||
nghttp2_strerror(rc), rc);
|
||||
}
|
||||
|
||||
check->keepalive = now;
|
||||
conn->keepalive = now;
|
||||
}
|
||||
}
|
||||
|
||||
if(send_frames) {
|
||||
rc = nghttp2_session_send(c->h2);
|
||||
if(rc)
|
||||
failf(check->data, "nghttp2_session_send() failed: %s(%d)",
|
||||
failf(data, "nghttp2_session_send() failed: %s(%d)",
|
||||
nghttp2_strerror(rc), rc);
|
||||
}
|
||||
|
||||
@ -295,7 +296,7 @@ static const struct Curl_handler Curl_handler_http2 = {
|
||||
http2_getsock, /* proto_getsock */
|
||||
http2_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
http2_perform_getsock, /* perform_getsock */
|
||||
http2_getsock, /* perform_getsock */
|
||||
http2_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
http2_conncheck, /* connection_check */
|
||||
@ -317,7 +318,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
|
||||
http2_getsock, /* proto_getsock */
|
||||
http2_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
http2_perform_getsock, /* perform_getsock */
|
||||
http2_getsock, /* perform_getsock */
|
||||
http2_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
http2_conncheck, /* connection_check */
|
||||
@ -343,7 +344,7 @@ int Curl_http2_ver(char *p, size_t len)
|
||||
* written. See the documentation of nghttp2_send_callback for the details.
|
||||
*/
|
||||
static ssize_t send_callback(nghttp2_session *h2,
|
||||
const uint8_t *data, size_t length, int flags,
|
||||
const uint8_t *mem, size_t length, int flags,
|
||||
void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
@ -358,8 +359,8 @@ static ssize_t send_callback(nghttp2_session *h2,
|
||||
/* called before setup properly! */
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
|
||||
data, length, &result);
|
||||
written = ((Curl_send*)c->send_underlying)(conn->data, FIRSTSOCKET,
|
||||
mem, length, &result);
|
||||
|
||||
if(result == CURLE_AGAIN) {
|
||||
return NGHTTP2_ERR_WOULDBLOCK;
|
||||
@ -1215,7 +1216,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
||||
/*
|
||||
* Initialize nghttp2 for a Curl connection
|
||||
*/
|
||||
static CURLcode http2_init(struct connectdata *conn)
|
||||
static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
if(!conn->proto.httpc.h2) {
|
||||
int rc;
|
||||
@ -1228,7 +1229,7 @@ static CURLcode http2_init(struct connectdata *conn)
|
||||
rc = nghttp2_session_callbacks_new(&callbacks);
|
||||
|
||||
if(rc) {
|
||||
failf(conn->data, "Couldn't initialize nghttp2 callbacks!");
|
||||
failf(data, "Couldn't initialize nghttp2 callbacks!");
|
||||
return CURLE_OUT_OF_MEMORY; /* most likely at least */
|
||||
}
|
||||
|
||||
@ -1257,7 +1258,7 @@ static CURLcode http2_init(struct connectdata *conn)
|
||||
nghttp2_session_callbacks_del(callbacks);
|
||||
|
||||
if(rc) {
|
||||
failf(conn->data, "Couldn't initialize nghttp2!");
|
||||
failf(data, "Couldn't initialize nghttp2!");
|
||||
return CURLE_OUT_OF_MEMORY; /* most likely at least */
|
||||
}
|
||||
}
|
||||
@ -1274,7 +1275,8 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
|
||||
ssize_t binlen;
|
||||
char *base64;
|
||||
size_t blen;
|
||||
struct SingleRequest *k = &conn->data->req;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
uint8_t *binsettings = conn->proto.httpc.binsettings;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
|
||||
@ -1285,13 +1287,13 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
|
||||
httpc->local_settings,
|
||||
httpc->local_settings_num);
|
||||
if(binlen <= 0) {
|
||||
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
|
||||
failf(data, "nghttp2 unexpectedly failed on pack_settings_payload");
|
||||
Curl_dyn_free(req);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
conn->proto.httpc.binlen = binlen;
|
||||
|
||||
result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
|
||||
result = Curl_base64url_encode(data, (const char *)binsettings, binlen,
|
||||
&base64, &blen);
|
||||
if(result) {
|
||||
Curl_dyn_free(req);
|
||||
@ -1325,14 +1327,13 @@ static int should_close_session(struct http_conn *httpc)
|
||||
* This function returns 0 if it succeeds, or -1 and error code will
|
||||
* be assigned to *err.
|
||||
*/
|
||||
static int h2_process_pending_input(struct connectdata *conn,
|
||||
static int h2_process_pending_input(struct Curl_easy *data,
|
||||
struct http_conn *httpc,
|
||||
CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
char *inbuf;
|
||||
ssize_t rv;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
nread = httpc->inbuflen - httpc->nread_inbuf;
|
||||
inbuf = httpc->inbuf + httpc->nread_inbuf;
|
||||
@ -1372,7 +1373,7 @@ static int h2_process_pending_input(struct connectdata *conn,
|
||||
the connection may not be reused. This is set when a
|
||||
GOAWAY frame has been received or when the limit of stream
|
||||
identifiers has been reached. */
|
||||
connclose(conn, "http/2: No new requests allowed");
|
||||
connclose(data->conn, "http/2: No new requests allowed");
|
||||
}
|
||||
|
||||
if(should_close_session(httpc)) {
|
||||
@ -1382,7 +1383,7 @@ static int h2_process_pending_input(struct connectdata *conn,
|
||||
*err = CURLE_HTTP2;
|
||||
else {
|
||||
/* not an error per se, but should still close the connection */
|
||||
connclose(conn, "GOAWAY received");
|
||||
connclose(data->conn, "GOAWAY received");
|
||||
*err = CURLE_OK;
|
||||
}
|
||||
return -1;
|
||||
@ -1393,7 +1394,8 @@ static int h2_process_pending_input(struct connectdata *conn,
|
||||
/*
|
||||
* Called from transfer.c:done_sending when we stop uploading.
|
||||
*/
|
||||
CURLcode Curl_http2_done_sending(struct connectdata *conn)
|
||||
CURLcode Curl_http2_done_sending(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
@ -1401,7 +1403,7 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
|
||||
(conn->handler == &Curl_handler_http2)) {
|
||||
/* make sure this is only attempted for HTTP/2 transfers */
|
||||
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
nghttp2_session *h2 = httpc->h2;
|
||||
@ -1414,13 +1416,11 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
|
||||
/* resume sending here to trigger the callback to get called again so
|
||||
that it can signal EOF to nghttp2 */
|
||||
(void)nghttp2_session_resume_data(h2, stream->stream_id);
|
||||
|
||||
(void)h2_process_pending_input(conn, httpc, &result);
|
||||
(void)h2_process_pending_input(data, httpc, &result);
|
||||
}
|
||||
|
||||
/* If nghttp2 still has pending frames unsent */
|
||||
if(nghttp2_session_want_write(h2)) {
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
int rv;
|
||||
|
||||
@ -1451,7 +1451,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
drained_transfer(data, httpc);
|
||||
|
||||
if(httpc->pause_stream_id == 0) {
|
||||
if(h2_process_pending_input(conn, httpc, err) != 0) {
|
||||
if(h2_process_pending_input(data, httpc, err) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1499,7 +1499,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, trailp, len);
|
||||
/* pass the trailers one by one to the callback */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailp, len);
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, trailp, len);
|
||||
if(result) {
|
||||
*err = result;
|
||||
return -1;
|
||||
@ -1563,12 +1563,12 @@ static int h2_session_send(struct Curl_easy *data,
|
||||
return nghttp2_session_send(h2);
|
||||
}
|
||||
|
||||
static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
|
||||
(void)sockindex; /* we always do HTTP2 on sockindex 0 */
|
||||
@ -1632,7 +1632,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
/* We have paused nghttp2, but we have no pause data (see
|
||||
on_data_chunk_recv). */
|
||||
httpc->pause_stream_id = 0;
|
||||
if(h2_process_pending_input(conn, httpc, err) != 0) {
|
||||
if(h2_process_pending_input(data, httpc, err) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1660,7 +1660,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
frames, then we have to call it again with 0-length data.
|
||||
Without this, on_stream_close callback will not be called,
|
||||
and stream could be hanged. */
|
||||
if(h2_process_pending_input(conn, httpc, err) != 0) {
|
||||
if(h2_process_pending_input(data, httpc, err) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1694,7 +1694,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
|
||||
if(httpc->inbuflen == 0) {
|
||||
nread = ((Curl_recv *)httpc->recv_underlying)(
|
||||
conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
|
||||
data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
|
||||
|
||||
if(nread == -1) {
|
||||
if(*err != CURLE_AGAIN)
|
||||
@ -1725,7 +1725,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
nread));
|
||||
}
|
||||
|
||||
if(h2_process_pending_input(conn, httpc, err) != 0)
|
||||
if(h2_process_pending_input(data, httpc, err) != 0)
|
||||
return -1;
|
||||
}
|
||||
if(stream->memlen) {
|
||||
@ -1831,7 +1831,7 @@ static header_instruction inspect_header(const char *name, size_t namelen,
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t http2_send(struct Curl_easy *data, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
/*
|
||||
@ -1840,8 +1840,9 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
* request.
|
||||
*/
|
||||
int rv;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
nghttp2_nv *nva = NULL;
|
||||
size_t nheader;
|
||||
size_t i;
|
||||
@ -1855,16 +1856,16 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
|
||||
(void)sockindex;
|
||||
|
||||
H2BUGF(infof(conn->data, "http2_send len=%zu\n", len));
|
||||
H2BUGF(infof(data, "http2_send len=%zu\n", len));
|
||||
|
||||
if(stream->stream_id != -1) {
|
||||
if(stream->close_handled) {
|
||||
infof(conn->data, "stream %d closed\n", stream->stream_id);
|
||||
infof(data, "stream %d closed\n", stream->stream_id);
|
||||
*err = CURLE_HTTP2_STREAM;
|
||||
return -1;
|
||||
}
|
||||
else if(stream->closed) {
|
||||
return http2_handle_stream_close(conn, conn->data, stream, err);
|
||||
return http2_handle_stream_close(conn, data, stream, err);
|
||||
}
|
||||
/* If stream_id != -1, we have dispatched request HEADERS, and now
|
||||
are going to send or sending request body in DATA frame */
|
||||
@ -1875,7 +1876,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
*err = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
rv = h2_session_send(conn->data, h2);
|
||||
rv = h2_session_send(data, h2);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
*err = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
@ -1888,7 +1889,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
stream->upload_len = 0;
|
||||
|
||||
if(should_close_session(httpc)) {
|
||||
H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
|
||||
H2BUGF(infof(data, "http2_send: nothing to do in this session\n"));
|
||||
*err = CURLE_HTTP2;
|
||||
return -1;
|
||||
}
|
||||
@ -1901,7 +1902,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
nghttp2_session_resume_data(h2, stream->stream_id);
|
||||
}
|
||||
|
||||
H2BUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len,
|
||||
H2BUGF(infof(data, "http2_send returns %zu for stream %u\n", len,
|
||||
stream->stream_id));
|
||||
return len;
|
||||
}
|
||||
@ -1945,7 +1946,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
nva[0].valuelen = (size_t)(end - hdbuf);
|
||||
nva[0].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[0])) {
|
||||
failf(conn->data, "Failed sending HTTP request: Header overflow");
|
||||
failf(data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1967,7 +1968,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
nva[1].valuelen = (size_t)(end - hdbuf);
|
||||
nva[1].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[1])) {
|
||||
failf(conn->data, "Failed sending HTTP request: Header overflow");
|
||||
failf(data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1980,7 +1981,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
nva[2].valuelen = strlen((char *)nva[2].value);
|
||||
nva[2].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[2])) {
|
||||
failf(conn->data, "Failed sending HTTP request: Header overflow");
|
||||
failf(data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -2040,7 +2041,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
|
||||
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[i])) {
|
||||
failf(conn->data, "Failed sending HTTP request: Header overflow");
|
||||
failf(data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
++i;
|
||||
@ -2064,30 +2065,30 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
for(i = 0; i < nheader; ++i) {
|
||||
acc += nva[i].namelen + nva[i].valuelen;
|
||||
|
||||
H2BUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
|
||||
H2BUGF(infof(data, "h2 header: %.*s:%.*s\n",
|
||||
nva[i].namelen, nva[i].name,
|
||||
nva[i].valuelen, nva[i].value));
|
||||
}
|
||||
|
||||
if(acc > MAX_ACC) {
|
||||
infof(conn->data, "http2_send: Warning: The cumulative length of all "
|
||||
infof(data, "http2_send: Warning: The cumulative length of all "
|
||||
"headers exceeds %d bytes and that could cause the "
|
||||
"stream to be rejected.\n", MAX_ACC);
|
||||
}
|
||||
}
|
||||
|
||||
h2_pri_spec(conn->data, &pri_spec);
|
||||
h2_pri_spec(data, &pri_spec);
|
||||
|
||||
H2BUGF(infof(conn->data, "http2_send request allowed %d (easy handle %p)\n",
|
||||
nghttp2_session_check_request_allowed(h2), (void *)conn->data));
|
||||
H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)\n",
|
||||
nghttp2_session_check_request_allowed(h2), (void *)data));
|
||||
|
||||
switch(conn->data->state.httpreq) {
|
||||
switch(data->state.httpreq) {
|
||||
case HTTPREQ_POST:
|
||||
case HTTPREQ_POST_FORM:
|
||||
case HTTPREQ_POST_MIME:
|
||||
case HTTPREQ_PUT:
|
||||
if(conn->data->state.infilesize != -1)
|
||||
stream->upload_left = conn->data->state.infilesize;
|
||||
if(data->state.infilesize != -1)
|
||||
stream->upload_left = data->state.infilesize;
|
||||
else
|
||||
/* data sending without specifying the data amount up front */
|
||||
stream->upload_left = -1; /* unknown, but not zero */
|
||||
@ -2095,32 +2096,32 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
data_prd.read_callback = data_source_read_callback;
|
||||
data_prd.source.ptr = NULL;
|
||||
stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
|
||||
&data_prd, conn->data);
|
||||
&data_prd, data);
|
||||
break;
|
||||
default:
|
||||
stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
|
||||
NULL, conn->data);
|
||||
NULL, data);
|
||||
}
|
||||
|
||||
Curl_safefree(nva);
|
||||
|
||||
if(stream_id < 0) {
|
||||
H2BUGF(infof(conn->data,
|
||||
H2BUGF(infof(data,
|
||||
"http2_send() nghttp2_submit_request error (%s)%d\n",
|
||||
nghttp2_strerror(stream_id), stream_id));
|
||||
*err = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
|
||||
stream_id, (void *)conn->data);
|
||||
infof(data, "Using Stream ID: %x (easy handle %p)\n",
|
||||
stream_id, (void *)data);
|
||||
stream->stream_id = stream_id;
|
||||
|
||||
/* this does not call h2_session_send() since there can not have been any
|
||||
* priority update since the nghttp2_submit_request() call above */
|
||||
rv = nghttp2_session_send(h2);
|
||||
if(rv != 0) {
|
||||
H2BUGF(infof(conn->data,
|
||||
H2BUGF(infof(data,
|
||||
"http2_send() nghttp2_session_send error (%s)%d\n",
|
||||
nghttp2_strerror(rv), rv));
|
||||
|
||||
@ -2129,7 +2130,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
if(should_close_session(httpc)) {
|
||||
H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
|
||||
H2BUGF(infof(data, "http2_send: nothing to do in this session\n"));
|
||||
*err = CURLE_HTTP2;
|
||||
return -1;
|
||||
}
|
||||
@ -2151,13 +2152,14 @@ fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
CURLcode Curl_http2_setup(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
|
||||
DEBUGASSERT(conn->data->state.buffer);
|
||||
DEBUGASSERT(data->state.buffer);
|
||||
|
||||
stream->stream_id = -1;
|
||||
|
||||
@ -2173,18 +2175,18 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
else
|
||||
conn->handler = &Curl_handler_http2;
|
||||
|
||||
result = http2_init(conn);
|
||||
result = http2_init(data, conn);
|
||||
if(result) {
|
||||
Curl_dyn_free(&stream->header_recvbuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
infof(conn->data, "Using HTTP2, server supports multi-use\n");
|
||||
infof(data, "Using HTTP2, server supports multi-use\n");
|
||||
stream->upload_left = 0;
|
||||
stream->upload_mem = NULL;
|
||||
stream->upload_len = 0;
|
||||
stream->mem = conn->data->state.buffer;
|
||||
stream->len = conn->data->set.buffer_size;
|
||||
stream->mem = data->state.buffer;
|
||||
stream->len = data->set.buffer_size;
|
||||
|
||||
httpc->inbuflen = 0;
|
||||
httpc->nread_inbuf = 0;
|
||||
@ -2196,22 +2198,22 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
conn->httpversion = 20;
|
||||
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
|
||||
|
||||
infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
|
||||
multi_connchanged(conn->data->multi);
|
||||
infof(data, "Connection state changed (HTTP/2 confirmed)\n");
|
||||
multi_connchanged(data->multi);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
CURLcode Curl_http2_switched(struct Curl_easy *data,
|
||||
const char *mem, size_t nread)
|
||||
{
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
int rv;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
|
||||
result = Curl_http2_setup(conn);
|
||||
result = Curl_http2_setup(data, conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -2220,7 +2222,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
conn->recv[FIRSTSOCKET] = http2_recv;
|
||||
conn->send[FIRSTSOCKET] = http2_send;
|
||||
|
||||
if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
|
||||
if(data->req.upgr101 == UPGR101_RECEIVED) {
|
||||
/* stream 1 is opened implicitly on upgrade */
|
||||
stream->stream_id = 1;
|
||||
/* queue SETTINGS frame (again) */
|
||||
@ -2270,13 +2272,13 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
data into stream->mem, overwriting data already there. */
|
||||
if(H2_BUFSIZE < nread) {
|
||||
failf(data, "connection buffer size is too small to store data following "
|
||||
"HTTP Upgrade response header: buflen=%d, datalen=%zu",
|
||||
"HTTP Upgrade response header: buflen=%d, datalen=%zu",
|
||||
H2_BUFSIZE, nread);
|
||||
return CURLE_HTTP2;
|
||||
}
|
||||
|
||||
infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer"
|
||||
" after upgrade: len=%zu\n",
|
||||
infof(data, "Copying HTTP/2 data in stream buffer to connection buffer"
|
||||
" after upgrade: len=%zu\n",
|
||||
nread);
|
||||
|
||||
if(nread)
|
||||
@ -2286,7 +2288,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
|
||||
DEBUGASSERT(httpc->nread_inbuf == 0);
|
||||
|
||||
if(-1 == h2_process_pending_input(conn, httpc, &result))
|
||||
if(-1 == h2_process_pending_input(data, httpc, &result))
|
||||
return CURLE_HTTP2;
|
||||
|
||||
return CURLE_OK;
|
||||
|
15
lib/http2.h
15
lib/http2.h
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -44,14 +44,15 @@ void Curl_http2_init_state(struct UrlState *state);
|
||||
void Curl_http2_init_userset(struct UserDefined *set);
|
||||
CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
|
||||
struct connectdata *conn);
|
||||
CURLcode Curl_http2_setup(struct connectdata *conn);
|
||||
CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
const char *data, size_t nread);
|
||||
CURLcode Curl_http2_setup(struct Curl_easy *data, struct connectdata *conn);
|
||||
CURLcode Curl_http2_switched(struct Curl_easy *data,
|
||||
const char *ptr, size_t nread);
|
||||
/* called from http_setup_conn */
|
||||
void Curl_http2_setup_conn(struct connectdata *conn);
|
||||
void Curl_http2_setup_req(struct Curl_easy *data);
|
||||
void Curl_http2_done(struct Curl_easy *data, bool premature);
|
||||
CURLcode Curl_http2_done_sending(struct connectdata *conn);
|
||||
CURLcode Curl_http2_done_sending(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
CURLcode Curl_http2_add_child(struct Curl_easy *parent,
|
||||
struct Curl_easy *child,
|
||||
bool exclusive);
|
||||
@ -64,14 +65,14 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause);
|
||||
bool Curl_h2_http_1_1_error(struct connectdata *conn);
|
||||
#else /* USE_NGHTTP2 */
|
||||
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_setup(x,y) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_setup_conn(x) Curl_nop_stmt
|
||||
#define Curl_http2_setup_req(x)
|
||||
#define Curl_http2_init_state(x)
|
||||
#define Curl_http2_init_userset(x)
|
||||
#define Curl_http2_done(x,y)
|
||||
#define Curl_http2_done_sending(x)
|
||||
#define Curl_http2_done_sending(x,y)
|
||||
#define Curl_http2_add_child(x, y, z)
|
||||
#define Curl_http2_remove_child(x, y)
|
||||
#define Curl_http2_cleanup_dependencies(x)
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -96,7 +96,7 @@ CURLcode Curl_output_aws_sigv4(struct connectdata *conn, bool proxy)
|
||||
char date_str[64];
|
||||
const char *post_data = data->set.postfields ?
|
||||
data->set.postfields : "";
|
||||
const char *content_type = Curl_checkheaders(conn, "Content-Type");
|
||||
const char *content_type = Curl_checkheaders(data, "Content-Type");
|
||||
unsigned char sha_d[32];
|
||||
char sha_hex[65];
|
||||
char *cred_scope = NULL;
|
||||
@ -116,7 +116,7 @@ CURLcode Curl_output_aws_sigv4(struct connectdata *conn, bool proxy)
|
||||
DEBUGASSERT(!proxy);
|
||||
(void)proxy;
|
||||
|
||||
if(Curl_checkheaders(conn, "Authorization")) {
|
||||
if(Curl_checkheaders(data, "Authorization")) {
|
||||
/* Authorization already present, Bailing out */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
/* the original data is written to the client, but we go on with the
|
||||
chunk read process, to properly calculate the content length*/
|
||||
if(data->set.http_te_skip && !k->ignorebody) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, datap, datalen);
|
||||
if(result) {
|
||||
*extrap = result;
|
||||
return CHUNKE_PASSTHRU_ERROR;
|
||||
@ -198,7 +198,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
if(!conn->data->set.http_ce_skip && k->writer_stack)
|
||||
result = Curl_unencode_write(conn, k->writer_stack, datap, piece);
|
||||
else
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, datap, piece);
|
||||
|
||||
if(result) {
|
||||
*extrap = result;
|
||||
@ -249,7 +249,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
return CHUNKE_BAD_CHUNK;
|
||||
|
||||
if(!data->set.http_te_skip) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, tr, trlen);
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, tr, trlen);
|
||||
if(result) {
|
||||
*extrap = result;
|
||||
return CHUNKE_PASSTHRU_ERROR;
|
||||
|
@ -184,7 +184,8 @@ static void connect_done(struct connectdata *conn)
|
||||
infof(conn->data, "CONNECT phase completed!\n");
|
||||
}
|
||||
|
||||
static CURLcode CONNECT_host(struct connectdata *conn,
|
||||
static CURLcode CONNECT_host(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int remote_port,
|
||||
char **connecthostp,
|
||||
@ -203,7 +204,7 @@ static CURLcode CONNECT_host(struct connectdata *conn,
|
||||
if(!hostheader)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!Curl_checkProxyheaders(conn, "Host")) {
|
||||
if(!Curl_checkProxyheaders(data, conn, "Host")) {
|
||||
host = aprintf("Host: %s\r\n", hostheader);
|
||||
if(!host) {
|
||||
free(hostheader);
|
||||
@ -258,12 +259,13 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
/* initialize a dynamic send-buffer */
|
||||
Curl_dyn_init(&req, DYN_HTTP_REQUEST);
|
||||
|
||||
result = CONNECT_host(conn, hostname, remote_port, &hostheader, &host);
|
||||
result = CONNECT_host(data, conn,
|
||||
hostname, remote_port, &hostheader, &host);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Setup the proxy-authorization header, if any */
|
||||
result = Curl_http_output_auth(conn, "CONNECT", HTTPREQ_GET,
|
||||
result = Curl_http_output_auth(data, conn, "CONNECT", HTTPREQ_GET,
|
||||
hostheader, TRUE);
|
||||
|
||||
if(!result) {
|
||||
@ -272,10 +274,10 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
const char *httpv =
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? "1.0" : "1.1";
|
||||
|
||||
if(!Curl_checkProxyheaders(conn, "Proxy-Connection"))
|
||||
if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection"))
|
||||
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
|
||||
|
||||
if(!Curl_checkProxyheaders(conn, "User-Agent") &&
|
||||
if(!Curl_checkProxyheaders(data, conn, "User-Agent") &&
|
||||
data->set.str[STRING_USERAGENT])
|
||||
useragent = data->state.aptr.uagent;
|
||||
|
||||
@ -295,7 +297,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
proxyconn);
|
||||
|
||||
if(!result)
|
||||
result = Curl_add_custom_headers(conn, TRUE, &req);
|
||||
result = Curl_add_custom_headers(data, TRUE, &req);
|
||||
|
||||
if(!result)
|
||||
/* CRLF terminate the request */
|
||||
@ -304,7 +306,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
if(!result) {
|
||||
/* Send the connect request to the proxy */
|
||||
/* BLOCKING */
|
||||
result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
|
||||
result = Curl_buffer_send(&req, data, &data->info.request_size, 0,
|
||||
sockindex);
|
||||
}
|
||||
if(result)
|
||||
@ -340,7 +342,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
|
||||
/* Read one byte at a time to avoid a race condition. Wait at most one
|
||||
second before looping to ensure continuous pgrsUpdates. */
|
||||
result = Curl_read(conn, tunnelsocket, &byte, 1, &gotbytes);
|
||||
result = Curl_read(data, tunnelsocket, &byte, 1, &gotbytes);
|
||||
if(result == CURLE_AGAIN)
|
||||
/* socket buffer drained, return */
|
||||
return CURLE_OK;
|
||||
@ -428,7 +430,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
|
||||
result = Curl_client_write(conn, writetype, linep, perline);
|
||||
result = Curl_client_write(data, writetype, linep, perline);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -508,7 +510,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
if(!auth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = Curl_http_input_auth(conn, proxy, auth);
|
||||
result = Curl_http_input_auth(data, proxy, auth);
|
||||
|
||||
free(auth);
|
||||
|
||||
@ -567,7 +569,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
if(data->info.httpproxycode/100 != 2) {
|
||||
/* Deal with the possibly already received authenticate
|
||||
headers. 'newurl' is set to a new URL if we must loop. */
|
||||
result = Curl_http_auth_act(conn);
|
||||
result = Curl_http_auth_act(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -580,7 +582,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
|
||||
if(s->close_connection && data->req.newurl) {
|
||||
/* Connection closed by server. Don't use it anymore */
|
||||
Curl_closesocket(conn, conn->sock[sockindex]);
|
||||
Curl_closesocket(data, conn, conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
break;
|
||||
}
|
||||
@ -606,7 +608,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
data->req.newurl = NULL;
|
||||
/* failure, close this connection to avoid re-use */
|
||||
streamclose(conn, "proxy CONNECT failure");
|
||||
Curl_closesocket(conn, conn->sock[sockindex]);
|
||||
Curl_closesocket(data, conn, conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
@ -733,7 +735,8 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = CONNECT_host(conn, hostname, remote_port, &hostheader, &host);
|
||||
result = CONNECT_host(data, conn, hostname, remote_port,
|
||||
&hostheader, &host);
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
@ -743,7 +746,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
/* Setup the proxy-authorization header, if any */
|
||||
result = Curl_http_output_auth(conn, "CONNECT", HTTPREQ_GET,
|
||||
result = Curl_http_output_auth(data, conn, "CONNECT", HTTPREQ_GET,
|
||||
hostheader, TRUE);
|
||||
if(result)
|
||||
goto error;
|
||||
@ -776,7 +779,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
Curl_hyper_header(data, headers, data->state.aptr.uagent))
|
||||
goto error;
|
||||
|
||||
if(!Curl_checkProxyheaders(conn, "Proxy-Connection") &&
|
||||
if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection") &&
|
||||
Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive"))
|
||||
goto error;
|
||||
|
||||
|
443
lib/imap.c
443
lib/imap.c
File diff suppressed because it is too large
Load Diff
39
lib/krb5.c
39
lib/krb5.c
@ -2,7 +2,7 @@
|
||||
*
|
||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* Copyright (c) 2004 - 2020 Daniel Stenberg
|
||||
* Copyright (c) 2004 - 2021 Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -89,7 +89,7 @@ static CURLcode ftpsend(struct connectdata *conn, const char *cmd)
|
||||
#ifdef HAVE_GSSAPI
|
||||
conn->data_prot = PROT_CMD;
|
||||
#endif
|
||||
result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
|
||||
result = Curl_write(conn->data, conn->sock[FIRSTSOCKET], sptr, write_len,
|
||||
&bytes_written);
|
||||
#ifdef HAVE_GSSAPI
|
||||
DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
|
||||
@ -246,7 +246,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
if(result)
|
||||
return -2;
|
||||
|
||||
if(Curl_GetFTPResponse(&nread, conn, NULL))
|
||||
if(Curl_GetFTPResponse(data, &nread, NULL))
|
||||
return -1;
|
||||
|
||||
if(data->state.buffer[0] != '3')
|
||||
@ -331,7 +331,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
break;
|
||||
}
|
||||
|
||||
if(Curl_GetFTPResponse(&nread, conn, NULL)) {
|
||||
if(Curl_GetFTPResponse(data, &nread, NULL)) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -443,7 +443,7 @@ static char level_to_char(int level)
|
||||
|
||||
/* Send an FTP command defined by |message| and the optional arguments. The
|
||||
function returns the ftp_code. If an error occurs, -1 is returned. */
|
||||
static int ftp_send_command(struct connectdata *conn, const char *message, ...)
|
||||
static int ftp_send_command(struct Curl_easy *data, const char *message, ...)
|
||||
{
|
||||
int ftp_code;
|
||||
ssize_t nread = 0;
|
||||
@ -454,11 +454,11 @@ static int ftp_send_command(struct connectdata *conn, const char *message, ...)
|
||||
mvsnprintf(print_buffer, sizeof(print_buffer), message, args);
|
||||
va_end(args);
|
||||
|
||||
if(ftpsend(conn, print_buffer)) {
|
||||
if(ftpsend(data->conn, print_buffer)) {
|
||||
ftp_code = -1;
|
||||
}
|
||||
else {
|
||||
if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
|
||||
if(Curl_GetFTPResponse(data, &nread, &ftp_code))
|
||||
ftp_code = -1;
|
||||
}
|
||||
|
||||
@ -503,7 +503,7 @@ socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
|
||||
ssize_t written;
|
||||
|
||||
while(len > 0) {
|
||||
result = Curl_write_plain(conn, fd, to_p, len, &written);
|
||||
result = Curl_write_plain(conn->data, fd, to_p, len, &written);
|
||||
if(!result) {
|
||||
len -= written;
|
||||
to_p += written;
|
||||
@ -556,18 +556,19 @@ buffer_read(struct krb5buffer *buf, void *data, size_t len)
|
||||
}
|
||||
|
||||
/* Matches Curl_recv signature */
|
||||
static ssize_t sec_recv(struct connectdata *conn, int sockindex,
|
||||
static ssize_t sec_recv(struct Curl_easy *data, int sockindex,
|
||||
char *buffer, size_t len, CURLcode *err)
|
||||
{
|
||||
size_t bytes_read;
|
||||
size_t total_read = 0;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t fd = conn->sock[sockindex];
|
||||
|
||||
*err = CURLE_OK;
|
||||
|
||||
/* Handle clear text response. */
|
||||
if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
|
||||
return sread(fd, buffer, len);
|
||||
return sread(fd, buffer, len);
|
||||
|
||||
if(conn->in_buffer.eof_flag) {
|
||||
conn->in_buffer.eof_flag = 0;
|
||||
@ -673,9 +674,10 @@ static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
|
||||
}
|
||||
|
||||
/* Matches Curl_send signature */
|
||||
static ssize_t sec_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t sec_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buffer, size_t len, CURLcode *err)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t fd = conn->sock[sockindex];
|
||||
*err = CURLE_OK;
|
||||
return sec_write(conn, fd, buffer, len);
|
||||
@ -736,9 +738,10 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
static int sec_set_protection_level(struct connectdata *conn)
|
||||
static int sec_set_protection_level(struct Curl_easy *data)
|
||||
{
|
||||
int code;
|
||||
struct connectdata *conn = data->conn;
|
||||
enum protection_level level = conn->request_data_prot;
|
||||
|
||||
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
|
||||
@ -757,7 +760,7 @@ static int sec_set_protection_level(struct connectdata *conn)
|
||||
char *pbsz;
|
||||
static unsigned int buffer_size = 1 << 20; /* 1048576 */
|
||||
|
||||
code = ftp_send_command(conn, "PBSZ %u", buffer_size);
|
||||
code = ftp_send_command(data, "PBSZ %u", buffer_size);
|
||||
if(code < 0)
|
||||
return -1;
|
||||
|
||||
@ -767,7 +770,7 @@ static int sec_set_protection_level(struct connectdata *conn)
|
||||
}
|
||||
conn->buffer_size = buffer_size;
|
||||
|
||||
pbsz = strstr(conn->data->state.buffer, "PBSZ=");
|
||||
pbsz = strstr(data->state.buffer, "PBSZ=");
|
||||
if(pbsz) {
|
||||
/* ignore return code, use default value if it fails */
|
||||
(void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
|
||||
@ -776,8 +779,8 @@ static int sec_set_protection_level(struct connectdata *conn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Now try to negotiate the protection level. */
|
||||
code = ftp_send_command(conn, "PROT %c", level_to_char(level));
|
||||
/* Now try to negiociate the protection level. */
|
||||
code = ftp_send_command(data, "PROT %c", level_to_char(level));
|
||||
|
||||
if(code < 0)
|
||||
return -1;
|
||||
@ -830,7 +833,7 @@ static CURLcode choose_mech(struct connectdata *conn)
|
||||
}
|
||||
|
||||
infof(data, "Trying mechanism %s...\n", mech->name);
|
||||
ret = ftp_send_command(conn, "AUTH %s", mech->name);
|
||||
ret = ftp_send_command(data, "AUTH %s", mech->name);
|
||||
if(ret < 0)
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
|
||||
@ -873,7 +876,7 @@ static CURLcode choose_mech(struct connectdata *conn)
|
||||
conn->command_prot = PROT_SAFE;
|
||||
/* Set the requested protection level */
|
||||
/* BLOCKING */
|
||||
(void)sec_set_protection_level(conn);
|
||||
(void)sec_set_protection_level(data);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
|
26
lib/ldap.c
26
lib/ldap.c
@ -126,7 +126,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp);
|
||||
#endif
|
||||
|
||||
|
||||
static CURLcode ldap_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode ldap_do(struct Curl_easy *data, bool *done);
|
||||
|
||||
/*
|
||||
* LDAP protocol handler.
|
||||
@ -266,7 +266,7 @@ static int ldap_win_bind(struct connectdata *conn, LDAP *server,
|
||||
#endif
|
||||
|
||||
|
||||
static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
int rc = 0;
|
||||
@ -275,7 +275,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
LDAPMessage *ldapmsg = NULL;
|
||||
LDAPMessage *entryIterator;
|
||||
int num = 0;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
int ldap_proto = LDAP_VERSION3;
|
||||
int ldap_ssl = 0;
|
||||
char *val_b64 = NULL;
|
||||
@ -536,14 +536,14 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
#endif
|
||||
name_len = strlen(name);
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
|
||||
if(result) {
|
||||
FREE_ON_WINLDAP(name);
|
||||
ldap_memfree(dn);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) name,
|
||||
name_len);
|
||||
if(result) {
|
||||
FREE_ON_WINLDAP(name);
|
||||
@ -551,7 +551,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
goto quit;
|
||||
}
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
if(result) {
|
||||
FREE_ON_WINLDAP(name);
|
||||
ldap_memfree(dn);
|
||||
@ -589,7 +589,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
vals = ldap_get_values_len(server, entryIterator, attribute);
|
||||
if(vals != NULL) {
|
||||
for(i = 0; (vals[i] != NULL); i++) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
FREE_ON_WINLDAP(attr);
|
||||
@ -600,7 +600,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
goto quit;
|
||||
}
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
(char *) attr, attr_len);
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
@ -612,7 +612,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
goto quit;
|
||||
}
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2);
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
FREE_ON_WINLDAP(attr);
|
||||
@ -644,7 +644,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
if(val_b64_sz > 0) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, val_b64,
|
||||
val_b64_sz);
|
||||
free(val_b64);
|
||||
if(result) {
|
||||
@ -661,7 +661,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, vals[i]->bv_val,
|
||||
vals[i]->bv_len);
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
@ -676,7 +676,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
dlsize += vals[i]->bv_len;
|
||||
}
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
if(result) {
|
||||
ldap_value_free_len(vals);
|
||||
FREE_ON_WINLDAP(attr);
|
||||
@ -698,7 +698,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
FREE_ON_WINLDAP(attr);
|
||||
ldap_memfree(attribute);
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
if(result)
|
||||
goto quit;
|
||||
dlsize++;
|
||||
|
141
lib/mqtt.c
141
lib/mqtt.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2020 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2019, Björn Stenberg, <bjorn@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@ -59,10 +59,12 @@
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static CURLcode mqtt_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode mqtt_doing(struct connectdata *conn, bool *done);
|
||||
static int mqtt_getsock(struct connectdata *conn, curl_socket_t *sock);
|
||||
static CURLcode mqtt_setup_conn(struct connectdata *conn);
|
||||
static CURLcode mqtt_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode mqtt_doing(struct Curl_easy *data, bool *done);
|
||||
static int mqtt_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static CURLcode mqtt_setup_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* MQTT protocol handler.
|
||||
@ -90,12 +92,13 @@ const struct Curl_handler Curl_handler_mqtt = {
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
static CURLcode mqtt_setup_conn(struct connectdata *conn)
|
||||
static CURLcode mqtt_setup_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
|
||||
during this request */
|
||||
struct MQTT *mq;
|
||||
struct Curl_easy *data = conn->data;
|
||||
(void)conn;
|
||||
DEBUGASSERT(data->req.p.mqtt == NULL);
|
||||
|
||||
mq = calloc(1, sizeof(struct MQTT));
|
||||
@ -105,15 +108,15 @@ static CURLcode mqtt_setup_conn(struct connectdata *conn)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_send(struct connectdata *conn,
|
||||
static CURLcode mqtt_send(struct Curl_easy *data,
|
||||
char *buf, size_t len)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct MQTT *mq = data->req.p.mqtt;
|
||||
ssize_t n;
|
||||
result = Curl_write(conn, sockfd, buf, len, &n);
|
||||
result = Curl_write(data, sockfd, buf, len, &n);
|
||||
if(!result)
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)n);
|
||||
if(len != (size_t)n) {
|
||||
@ -130,14 +133,16 @@ static CURLcode mqtt_send(struct connectdata *conn,
|
||||
/* Generic function called by the multi interface to figure out what socket(s)
|
||||
to wait for and for what actions during the DOING and PROTOCONNECT
|
||||
states */
|
||||
static int mqtt_getsock(struct connectdata *conn,
|
||||
static int mqtt_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
{
|
||||
(void)data;
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
}
|
||||
|
||||
static CURLcode mqtt_connect(struct connectdata *conn)
|
||||
static CURLcode mqtt_connect(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
const size_t client_id_offset = 14;
|
||||
@ -157,31 +162,31 @@ static CURLcode mqtt_connect(struct connectdata *conn)
|
||||
packet[1] = (packetlen - 2) & 0x7f;
|
||||
packet[client_id_offset - 1] = MQTT_CLIENTID_LEN;
|
||||
|
||||
result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[clen],
|
||||
result = Curl_rand_hex(data, (unsigned char *)&client_id[clen],
|
||||
MQTT_CLIENTID_LEN - clen + 1);
|
||||
memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN);
|
||||
infof(conn->data, "Using client id '%s'\n", client_id);
|
||||
infof(data, "Using client id '%s'\n", client_id);
|
||||
if(!result)
|
||||
result = mqtt_send(conn, packet, packetlen);
|
||||
result = mqtt_send(data, packet, packetlen);
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_disconnect(struct connectdata *conn)
|
||||
static CURLcode mqtt_disconnect(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
result = mqtt_send(conn, (char *)"\xe0\x00", 2);
|
||||
result = mqtt_send(data, (char *)"\xe0\x00", 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_verify_connack(struct connectdata *conn)
|
||||
static CURLcode mqtt_verify_connack(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
unsigned char readbuf[MQTT_CONNACK_LEN];
|
||||
ssize_t nread;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
result = Curl_read(conn, sockfd, (char *)readbuf, MQTT_CONNACK_LEN, &nread);
|
||||
result = Curl_read(data, sockfd, (char *)readbuf, MQTT_CONNACK_LEN, &nread);
|
||||
if(result)
|
||||
goto fail;
|
||||
|
||||
@ -204,18 +209,18 @@ fail:
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_get_topic(struct connectdata *conn,
|
||||
static CURLcode mqtt_get_topic(struct Curl_easy *data,
|
||||
char **topic, size_t *topiclen)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *path = conn->data->state.up.path;
|
||||
char *path = data->state.up.path;
|
||||
|
||||
if(strlen(path) > 1) {
|
||||
result = Curl_urldecode(conn->data, path + 1, 0, topic, topiclen,
|
||||
result = Curl_urldecode(data, path + 1, 0, topic, topiclen,
|
||||
REJECT_NADA);
|
||||
}
|
||||
else {
|
||||
failf(conn->data, "Error: No topic specified.");
|
||||
failf(data, "Error: No topic specified.");
|
||||
result = CURLE_URL_MALFORMAT;
|
||||
}
|
||||
return result;
|
||||
@ -238,7 +243,7 @@ static int mqtt_encode_len(char *buf, size_t len)
|
||||
return i;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_subscribe(struct connectdata *conn)
|
||||
static CURLcode mqtt_subscribe(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *topic = NULL;
|
||||
@ -247,8 +252,9 @@ static CURLcode mqtt_subscribe(struct connectdata *conn)
|
||||
size_t packetlen;
|
||||
char encodedsize[4];
|
||||
size_t n;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
result = mqtt_get_topic(conn, &topic, &topiclen);
|
||||
result = mqtt_get_topic(data, &topic, &topiclen);
|
||||
if(result)
|
||||
goto fail;
|
||||
|
||||
@ -274,7 +280,7 @@ static CURLcode mqtt_subscribe(struct connectdata *conn)
|
||||
memcpy(&packet[5 + n], topic, topiclen);
|
||||
packet[5 + n + topiclen] = 0; /* QoS zero */
|
||||
|
||||
result = mqtt_send(conn, (char *)packet, packetlen);
|
||||
result = mqtt_send(data, (char *)packet, packetlen);
|
||||
|
||||
fail:
|
||||
free(topic);
|
||||
@ -285,19 +291,20 @@ fail:
|
||||
/*
|
||||
* Called when the first byte was already read.
|
||||
*/
|
||||
static CURLcode mqtt_verify_suback(struct connectdata *conn)
|
||||
static CURLcode mqtt_verify_suback(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
unsigned char readbuf[MQTT_SUBACK_LEN];
|
||||
ssize_t nread;
|
||||
struct mqtt_conn *mqtt = &conn->proto.mqtt;
|
||||
|
||||
result = Curl_read(conn, sockfd, (char *)readbuf, MQTT_SUBACK_LEN, &nread);
|
||||
result = Curl_read(data, sockfd, (char *)readbuf, MQTT_SUBACK_LEN, &nread);
|
||||
if(result)
|
||||
goto fail;
|
||||
|
||||
Curl_debug(conn->data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
|
||||
|
||||
/* fixme */
|
||||
if(nread < MQTT_SUBACK_LEN) {
|
||||
@ -315,10 +322,10 @@ fail:
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_publish(struct connectdata *conn)
|
||||
static CURLcode mqtt_publish(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result;
|
||||
char *payload = conn->data->set.postfields;
|
||||
char *payload = data->set.postfields;
|
||||
size_t payloadlen;
|
||||
char *topic = NULL;
|
||||
size_t topiclen;
|
||||
@ -327,7 +334,7 @@ static CURLcode mqtt_publish(struct connectdata *conn)
|
||||
size_t remaininglength;
|
||||
size_t encodelen;
|
||||
char encodedbytes[4];
|
||||
curl_off_t postfieldsize = conn->data->set.postfieldsize;
|
||||
curl_off_t postfieldsize = data->set.postfieldsize;
|
||||
|
||||
if(!payload)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
@ -336,7 +343,7 @@ static CURLcode mqtt_publish(struct connectdata *conn)
|
||||
else
|
||||
payloadlen = (size_t)postfieldsize;
|
||||
|
||||
result = mqtt_get_topic(conn, &topic, &topiclen);
|
||||
result = mqtt_get_topic(data, &topic, &topiclen);
|
||||
if(result)
|
||||
goto fail;
|
||||
|
||||
@ -360,7 +367,7 @@ static CURLcode mqtt_publish(struct connectdata *conn)
|
||||
i += topiclen;
|
||||
memcpy(&pkt[i], payload, payloadlen);
|
||||
i += payloadlen;
|
||||
result = mqtt_send(conn, (char *)pkt, i);
|
||||
result = mqtt_send(data, (char *)pkt, i);
|
||||
|
||||
fail:
|
||||
free(pkt);
|
||||
@ -403,13 +410,14 @@ static const char *statenames[]={
|
||||
#endif
|
||||
|
||||
/* The only way to change state */
|
||||
static void mqstate(struct connectdata *conn,
|
||||
static void mqstate(struct Curl_easy *data,
|
||||
enum mqttstate state,
|
||||
enum mqttstate nextstate) /* used if state == FIRST */
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct mqtt_conn *mqtt = &conn->proto.mqtt;
|
||||
#ifdef CURLDEBUG
|
||||
infof(conn->data, "%s (from %s) (next is %s)\n",
|
||||
infof(data, "%s (from %s) (next is %s)\n",
|
||||
statenames[state],
|
||||
statenames[mqtt->state],
|
||||
(state == MQTT_FIRST)? statenames[nextstate] : "");
|
||||
@ -423,13 +431,12 @@ static void mqstate(struct connectdata *conn,
|
||||
/* for the publish packet */
|
||||
#define MQTT_HEADER_LEN 5 /* max 5 bytes */
|
||||
|
||||
static CURLcode mqtt_read_publish(struct connectdata *conn,
|
||||
bool *done)
|
||||
static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
ssize_t nread;
|
||||
struct Curl_easy *data = conn->data;
|
||||
unsigned char *pkt = (unsigned char *)data->state.buffer;
|
||||
size_t remlen;
|
||||
struct mqtt_conn *mqtt = &conn->proto.mqtt;
|
||||
@ -439,11 +446,11 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
|
||||
switch(mqtt->state) {
|
||||
MQTT_SUBACK_COMING:
|
||||
case MQTT_SUBACK_COMING:
|
||||
result = mqtt_verify_suback(conn);
|
||||
result = mqtt_verify_suback(data);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
mqstate(conn, MQTT_FIRST, MQTT_PUBWAIT);
|
||||
mqstate(data, MQTT_FIRST, MQTT_PUBWAIT);
|
||||
break;
|
||||
|
||||
case MQTT_SUBACK:
|
||||
@ -451,9 +458,9 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
|
||||
/* we are expecting PUBLISH or SUBACK */
|
||||
packet = mq->firstbyte & 0xf0;
|
||||
if(packet == MQTT_MSG_PUBLISH)
|
||||
mqstate(conn, MQTT_PUB_REMAIN, MQTT_NOSTATE);
|
||||
mqstate(data, MQTT_PUB_REMAIN, MQTT_NOSTATE);
|
||||
else if(packet == MQTT_MSG_SUBACK) {
|
||||
mqstate(conn, MQTT_SUBACK_COMING, MQTT_NOSTATE);
|
||||
mqstate(data, MQTT_SUBACK_COMING, MQTT_NOSTATE);
|
||||
goto MQTT_SUBACK_COMING;
|
||||
}
|
||||
else if(packet == MQTT_MSG_DISCONNECT) {
|
||||
@ -480,7 +487,7 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
|
||||
size_t rest = mq->npacket;
|
||||
if(rest > (size_t)data->set.buffer_size)
|
||||
rest = (size_t)data->set.buffer_size;
|
||||
result = Curl_read(conn, sockfd, (char *)pkt, rest, &nread);
|
||||
result = Curl_read(data, sockfd, (char *)pkt, rest, &nread);
|
||||
if(result) {
|
||||
if(CURLE_AGAIN == result) {
|
||||
infof(data, "EEEE AAAAGAIN\n");
|
||||
@ -500,13 +507,13 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
|
||||
|
||||
/* if QoS is set, message contains packet id */
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)pkt, nread);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)pkt, nread);
|
||||
if(result)
|
||||
goto end;
|
||||
|
||||
if(!mq->npacket)
|
||||
/* no more PUBLISH payload, back to subscribe wait state */
|
||||
mqstate(conn, MQTT_FIRST, MQTT_PUBWAIT);
|
||||
mqstate(data, MQTT_FIRST, MQTT_PUBWAIT);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -518,27 +525,25 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode mqtt_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
*done = FALSE; /* unconditionally */
|
||||
|
||||
result = mqtt_connect(conn);
|
||||
result = mqtt_connect(data);
|
||||
if(result) {
|
||||
failf(data, "Error %d sending MQTT CONN request", result);
|
||||
return result;
|
||||
}
|
||||
mqstate(conn, MQTT_FIRST, MQTT_CONNACK);
|
||||
mqstate(data, MQTT_FIRST, MQTT_CONNACK);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
|
||||
static CURLcode mqtt_doing(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct mqtt_conn *mqtt = &conn->proto.mqtt;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct MQTT *mq = data->req.p.mqtt;
|
||||
ssize_t nread;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
@ -550,7 +555,7 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
|
||||
if(mq->nsend) {
|
||||
/* send the remainder of an outgoing packet */
|
||||
char *ptr = mq->sendleftovers;
|
||||
result = mqtt_send(conn, mq->sendleftovers, mq->nsend);
|
||||
result = mqtt_send(data, mq->sendleftovers, mq->nsend);
|
||||
free(ptr);
|
||||
if(result)
|
||||
return result;
|
||||
@ -560,17 +565,17 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
|
||||
switch(mqtt->state) {
|
||||
case MQTT_FIRST:
|
||||
/* Read the initial byte only */
|
||||
result = Curl_read(conn, sockfd, (char *)&mq->firstbyte, 1, &nread);
|
||||
result = Curl_read(data, sockfd, (char *)&mq->firstbyte, 1, &nread);
|
||||
if(!nread)
|
||||
break;
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
|
||||
/* remember the first byte */
|
||||
mq->npacket = 0;
|
||||
mqstate(conn, MQTT_REMAINING_LENGTH, MQTT_NOSTATE);
|
||||
mqstate(data, MQTT_REMAINING_LENGTH, MQTT_NOSTATE);
|
||||
/* FALLTHROUGH */
|
||||
case MQTT_REMAINING_LENGTH:
|
||||
do {
|
||||
result = Curl_read(conn, sockfd, (char *)&byte, 1, &nread);
|
||||
result = Curl_read(data, sockfd, (char *)&byte, 1, &nread);
|
||||
if(!nread)
|
||||
break;
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
|
||||
@ -581,10 +586,10 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
|
||||
mq->remaining_length = mqtt_decode_len(&pkt[0], mq->npacket, NULL);
|
||||
mq->npacket = 0;
|
||||
if(mq->remaining_length) {
|
||||
mqstate(conn, mqtt->nextstate, MQTT_NOSTATE);
|
||||
mqstate(data, mqtt->nextstate, MQTT_NOSTATE);
|
||||
break;
|
||||
}
|
||||
mqstate(conn, MQTT_FIRST, MQTT_FIRST);
|
||||
mqstate(data, MQTT_FIRST, MQTT_FIRST);
|
||||
|
||||
if(mq->firstbyte == MQTT_MSG_DISCONNECT) {
|
||||
infof(data, "Got DISCONNECT\n");
|
||||
@ -592,22 +597,22 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
|
||||
}
|
||||
break;
|
||||
case MQTT_CONNACK:
|
||||
result = mqtt_verify_connack(conn);
|
||||
result = mqtt_verify_connack(data);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
if(conn->data->state.httpreq == HTTPREQ_POST) {
|
||||
result = mqtt_publish(conn);
|
||||
if(data->state.httpreq == HTTPREQ_POST) {
|
||||
result = mqtt_publish(data);
|
||||
if(!result) {
|
||||
result = mqtt_disconnect(conn);
|
||||
result = mqtt_disconnect(data);
|
||||
*done = TRUE;
|
||||
}
|
||||
mqtt->nextstate = MQTT_FIRST;
|
||||
}
|
||||
else {
|
||||
result = mqtt_subscribe(conn);
|
||||
result = mqtt_subscribe(data);
|
||||
if(!result) {
|
||||
mqstate(conn, MQTT_FIRST, MQTT_SUBACK);
|
||||
mqstate(data, MQTT_FIRST, MQTT_SUBACK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -615,11 +620,11 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
|
||||
case MQTT_SUBACK:
|
||||
case MQTT_PUBWAIT:
|
||||
case MQTT_PUB_REMAIN:
|
||||
result = mqtt_read_publish(conn, done);
|
||||
result = mqtt_read_publish(data, done);
|
||||
break;
|
||||
|
||||
default:
|
||||
failf(conn->data, "State not handled yet");
|
||||
failf(data, "State not handled yet");
|
||||
*done = TRUE;
|
||||
break;
|
||||
}
|
||||
|
101
lib/multi.c
101
lib/multi.c
@ -586,7 +586,7 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
|
||||
/* this calls the protocol-specific function pointer previously set */
|
||||
if(conn->handler->done)
|
||||
result = conn->handler->done(conn, status, premature);
|
||||
result = conn->handler->done(data, status, premature);
|
||||
else
|
||||
result = status;
|
||||
|
||||
@ -697,17 +697,13 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
static int close_connect_only(struct connectdata *conn, void *param)
|
||||
static int close_connect_only(struct Curl_easy *data,
|
||||
struct connectdata *conn, void *param)
|
||||
{
|
||||
struct Curl_easy *data = param;
|
||||
|
||||
(void)param;
|
||||
if(data->state.lastconnect_id != conn->connection_id)
|
||||
return 0;
|
||||
|
||||
if(conn->data != data)
|
||||
return 1;
|
||||
conn->data = NULL;
|
||||
|
||||
if(!conn->bits.connect_only)
|
||||
return 1;
|
||||
|
||||
@ -816,7 +812,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
if(data->state.lastconnect_id != -1) {
|
||||
/* Mark any connect-only connection for closure */
|
||||
Curl_conncache_foreach(data, data->state.conn_cache,
|
||||
data, &close_connect_only);
|
||||
NULL, close_connect_only);
|
||||
}
|
||||
|
||||
#ifdef USE_LIBPSL
|
||||
@ -945,27 +941,30 @@ static int waitproxyconnect_getsock(struct connectdata *conn,
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
static int domore_getsock(struct connectdata *conn,
|
||||
static int domore_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
if(conn && conn->handler->domore_getsock)
|
||||
return conn->handler->domore_getsock(conn, socks);
|
||||
return conn->handler->domore_getsock(data, conn, socks);
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
|
||||
static int doing_getsock(struct connectdata *conn,
|
||||
static int doing_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
if(conn && conn->handler->doing_getsock)
|
||||
return conn->handler->doing_getsock(conn, socks);
|
||||
return conn->handler->doing_getsock(data, conn, socks);
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
|
||||
static int protocol_getsock(struct connectdata *conn,
|
||||
static int protocol_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
if(conn->handler->proto_getsock)
|
||||
return conn->handler->proto_getsock(conn, socks);
|
||||
return conn->handler->proto_getsock(data, conn, socks);
|
||||
/* Backup getsock logic. Since there is a live socket in use, we must wait
|
||||
for it or it will be removed from watching when the multi_socket API is
|
||||
used. */
|
||||
@ -978,10 +977,11 @@ static int protocol_getsock(struct connectdata *conn,
|
||||
static int multi_getsock(struct Curl_easy *data,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
/* The no connection case can happen when this is called from
|
||||
curl_multi_remove_handle() => singlesocket() => multi_getsock().
|
||||
*/
|
||||
if(!data->conn)
|
||||
if(!conn)
|
||||
return 0;
|
||||
|
||||
if(data->mstate > CURLM_STATE_CONNECT &&
|
||||
@ -995,30 +995,30 @@ static int multi_getsock(struct Curl_easy *data,
|
||||
return 0;
|
||||
|
||||
case CURLM_STATE_WAITRESOLVE:
|
||||
return Curl_resolv_getsock(data->conn, socks);
|
||||
return Curl_resolv_getsock(conn, socks);
|
||||
|
||||
case CURLM_STATE_PROTOCONNECT:
|
||||
case CURLM_STATE_SENDPROTOCONNECT:
|
||||
return protocol_getsock(data->conn, socks);
|
||||
return protocol_getsock(data, conn, socks);
|
||||
|
||||
case CURLM_STATE_DO:
|
||||
case CURLM_STATE_DOING:
|
||||
return doing_getsock(data->conn, socks);
|
||||
return doing_getsock(data, conn, socks);
|
||||
|
||||
case CURLM_STATE_WAITPROXYCONNECT:
|
||||
return waitproxyconnect_getsock(data->conn, socks);
|
||||
return waitproxyconnect_getsock(conn, socks);
|
||||
|
||||
case CURLM_STATE_WAITCONNECT:
|
||||
return waitconnect_getsock(data->conn, socks);
|
||||
return waitconnect_getsock(conn, socks);
|
||||
|
||||
case CURLM_STATE_DO_MORE:
|
||||
return domore_getsock(data->conn, socks);
|
||||
return domore_getsock(data, conn, socks);
|
||||
|
||||
case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
|
||||
to waiting for the same as the *PERFORM
|
||||
states */
|
||||
case CURLM_STATE_PERFORM:
|
||||
return Curl_single_getsock(data->conn, socks);
|
||||
return Curl_single_getsock(data, conn, socks);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1401,7 +1401,8 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done)
|
||||
|
||||
if(conn->handler->do_it)
|
||||
/* generic protocol-specific function pointer set in curl_connect() */
|
||||
result = conn->handler->do_it(conn, done);
|
||||
result = conn->handler->do_it(data, done);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1414,14 +1415,15 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done)
|
||||
* DOING state there's more work to do!
|
||||
*/
|
||||
|
||||
static CURLcode multi_do_more(struct connectdata *conn, int *complete)
|
||||
static CURLcode multi_do_more(struct Curl_easy *data, int *complete)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
*complete = 0;
|
||||
|
||||
if(conn->handler->do_more)
|
||||
result = conn->handler->do_more(conn, complete);
|
||||
result = conn->handler->do_more(data, complete);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1432,14 +1434,14 @@ static CURLcode multi_do_more(struct connectdata *conn, int *complete)
|
||||
* protocol layer.
|
||||
*/
|
||||
|
||||
static CURLcode protocol_connecting(struct connectdata *conn,
|
||||
bool *done)
|
||||
static CURLcode protocol_connecting(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
if(conn && conn->handler->connecting) {
|
||||
*done = FALSE;
|
||||
result = conn->handler->connecting(conn, done);
|
||||
result = conn->handler->connecting(data, done);
|
||||
}
|
||||
else
|
||||
*done = TRUE;
|
||||
@ -1452,13 +1454,14 @@ static CURLcode protocol_connecting(struct connectdata *conn,
|
||||
* until the DOING phase is done on protocol layer.
|
||||
*/
|
||||
|
||||
static CURLcode protocol_doing(struct connectdata *conn, bool *done)
|
||||
static CURLcode protocol_doing(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
if(conn && conn->handler->doing) {
|
||||
*done = FALSE;
|
||||
result = conn->handler->doing(conn, done);
|
||||
result = conn->handler->doing(data, done);
|
||||
}
|
||||
else
|
||||
*done = TRUE;
|
||||
@ -1471,11 +1474,11 @@ static CURLcode protocol_doing(struct connectdata *conn, bool *done)
|
||||
* proceed with some action.
|
||||
*
|
||||
*/
|
||||
static CURLcode protocol_connect(struct connectdata *conn,
|
||||
static CURLcode protocol_connect(struct Curl_easy *data,
|
||||
bool *protocol_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
struct connectdata *conn = data->conn;
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(protocol_done);
|
||||
|
||||
@ -1514,7 +1517,7 @@ static CURLcode protocol_connect(struct connectdata *conn,
|
||||
/* is there a protocol-specific connect() procedure? */
|
||||
|
||||
/* Call the protocol-specific connect function */
|
||||
result = conn->handler->connect_it(conn, protocol_done);
|
||||
result = conn->handler->connect_it(data, protocol_done);
|
||||
}
|
||||
else
|
||||
*protocol_done = TRUE;
|
||||
@ -1785,7 +1788,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
case CURLM_STATE_WAITPROXYCONNECT:
|
||||
/* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
|
||||
DEBUGASSERT(data->conn);
|
||||
result = Curl_http_connect(data->conn, &protocol_connected);
|
||||
result = Curl_http_connect(data, &protocol_connected);
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(data->conn->bits.proxy_connect_closed) {
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
@ -1816,7 +1819,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
case CURLM_STATE_WAITCONNECT:
|
||||
/* awaiting a completion of an asynch TCP connect */
|
||||
DEBUGASSERT(data->conn);
|
||||
result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected);
|
||||
result = Curl_is_connected(data, data->conn, FIRSTSOCKET, &connected);
|
||||
if(connected && !result) {
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
if(
|
||||
@ -1849,7 +1852,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
break;
|
||||
|
||||
case CURLM_STATE_SENDPROTOCONNECT:
|
||||
result = protocol_connect(data->conn, &protocol_connected);
|
||||
result = protocol_connect(data, &protocol_connected);
|
||||
if(!result && !protocol_connected)
|
||||
/* switch to waiting state */
|
||||
multistate(data, CURLM_STATE_PROTOCONNECT);
|
||||
@ -1868,7 +1871,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
case CURLM_STATE_PROTOCONNECT:
|
||||
/* protocol-specific connect phase */
|
||||
result = protocol_connecting(data->conn, &protocol_connected);
|
||||
result = protocol_connecting(data, &protocol_connected);
|
||||
if(!result && protocol_connected) {
|
||||
/* after the connect has completed, go WAITDO or DO */
|
||||
multistate(data, CURLM_STATE_DO);
|
||||
@ -1994,7 +1997,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
case CURLM_STATE_DOING:
|
||||
/* we continue DOING until the DO phase is complete */
|
||||
DEBUGASSERT(data->conn);
|
||||
result = protocol_doing(data->conn, &dophase_done);
|
||||
result = protocol_doing(data, &dophase_done);
|
||||
if(!result) {
|
||||
if(dophase_done) {
|
||||
/* after DO, go DO_DONE or DO_MORE */
|
||||
@ -2017,7 +2020,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
* When we are connected, DO MORE and then go DO_DONE
|
||||
*/
|
||||
DEBUGASSERT(data->conn);
|
||||
result = multi_do_more(data->conn, &control);
|
||||
result = multi_do_more(data, &control);
|
||||
|
||||
if(!result) {
|
||||
if(control) {
|
||||
@ -2280,14 +2283,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* allow a previously set error code take precedence */
|
||||
if(!result)
|
||||
result = res;
|
||||
|
||||
/*
|
||||
* If there are other handles on the connection, multi_done won't set
|
||||
* conn to NULL. In such a case, curl_multi_remove_handle() can
|
||||
* access free'd data, if the connection is free'd and the handle
|
||||
* removed before we perform the processing in CURLM_STATE_COMPLETED
|
||||
*/
|
||||
Curl_detach_connnection(data);
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
@ -3329,16 +3324,18 @@ size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
|
||||
* When information about a connection has appeared, call this!
|
||||
*/
|
||||
|
||||
void Curl_multiuse_state(struct connectdata *conn,
|
||||
void Curl_multiuse_state(struct Curl_easy *data,
|
||||
int bundlestate) /* use BUNDLE_* defines */
|
||||
{
|
||||
struct connectdata *conn;
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->multi);
|
||||
conn = data->conn;
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(conn->bundle);
|
||||
DEBUGASSERT(conn->data);
|
||||
DEBUGASSERT(conn->data->multi);
|
||||
|
||||
conn->bundle->multiuse = bundlestate;
|
||||
process_pending_handles(conn->data->multi);
|
||||
process_pending_handles(data->multi);
|
||||
}
|
||||
|
||||
static void process_pending_handles(struct Curl_multi *multi)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -69,7 +69,7 @@ size_t Curl_multi_max_host_connections(struct Curl_multi *multi);
|
||||
/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
|
||||
size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
|
||||
|
||||
void Curl_multiuse_state(struct connectdata *conn,
|
||||
void Curl_multiuse_state(struct Curl_easy *data,
|
||||
int bundlestate); /* use BUNDLE_* defines */
|
||||
|
||||
/*
|
||||
|
@ -5,8 +5,8 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
|
||||
* Copyright (C) 2011 - 2020, 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
|
||||
@ -76,12 +76,14 @@ extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
|
||||
LDAP **ld);
|
||||
#endif
|
||||
|
||||
static CURLcode ldap_setup_connection(struct connectdata *conn);
|
||||
static CURLcode ldap_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
|
||||
static CURLcode ldap_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
|
||||
static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
|
||||
static CURLcode ldap_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static CURLcode ldap_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode ldap_done(struct Curl_easy *data, CURLcode, bool);
|
||||
static CURLcode ldap_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode ldap_connecting(struct Curl_easy *data, bool *done);
|
||||
static CURLcode ldap_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
|
||||
static Curl_recv ldap_recv;
|
||||
|
||||
@ -169,11 +171,11 @@ struct ldapreqinfo {
|
||||
int nument;
|
||||
};
|
||||
|
||||
static CURLcode ldap_setup_connection(struct connectdata *conn)
|
||||
static CURLcode ldap_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct ldapconninfo *li;
|
||||
LDAPURLDesc *lud;
|
||||
struct Curl_easy *data = conn->data;
|
||||
int rc, proto;
|
||||
CURLcode status;
|
||||
|
||||
@ -205,10 +207,10 @@ static CURLcode ldap_setup_connection(struct connectdata *conn)
|
||||
static Sockbuf_IO ldapsb_tls;
|
||||
#endif
|
||||
|
||||
static CURLcode ldap_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode ldap_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
struct Curl_easy *data = conn->data;
|
||||
int rc, proto = LDAP_VERSION3;
|
||||
char hosturl[1024];
|
||||
char *ptr;
|
||||
@ -252,10 +254,10 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
|
||||
static CURLcode ldap_connecting(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
struct Curl_easy *data = conn->data;
|
||||
LDAPMessage *msg = NULL;
|
||||
struct timeval tv = {0, 1}, *tvp;
|
||||
int rc, err;
|
||||
@ -357,10 +359,12 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
static CURLcode ldap_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead_connection)
|
||||
{
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
(void) dead_connection;
|
||||
(void) data;
|
||||
|
||||
if(li) {
|
||||
if(li->ld) {
|
||||
@ -373,15 +377,15 @@ static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
struct ldapreqinfo *lr;
|
||||
CURLcode status = CURLE_OK;
|
||||
int rc = 0;
|
||||
LDAPURLDesc *ludp = NULL;
|
||||
int msgid;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
connkeep(conn, "OpenLDAP do");
|
||||
|
||||
@ -418,10 +422,11 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
|
||||
static CURLcode ldap_done(struct Curl_easy *data, CURLcode res,
|
||||
bool premature)
|
||||
{
|
||||
struct ldapreqinfo *lr = conn->data->req.p.ldap;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapreqinfo *lr = data->req.p.ldap;
|
||||
|
||||
(void)res;
|
||||
(void)premature;
|
||||
@ -440,11 +445,11 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
size_t len, CURLcode *err)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ldapconninfo *li = conn->proto.ldapc;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ldapreqinfo *lr = data->req.p.ldap;
|
||||
int rc, ret;
|
||||
LDAPMessage *msg = NULL;
|
||||
@ -512,20 +517,20 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||
bv.bv_len);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
@ -546,18 +551,18 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
binary = 0;
|
||||
|
||||
if(bvals == NULL) {
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||
bv.bv_len);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":\n", 2);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)":\n", 2);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
@ -568,20 +573,20 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
|
||||
for(i = 0; bvals[i].bv_val != NULL; i++) {
|
||||
int binval = 0;
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
|
||||
bv.bv_len);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)":", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
@ -619,7 +624,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
*err = error;
|
||||
return -1;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
(char *)": ", 2);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
@ -628,7 +633,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
|
||||
data->req.bytecount += 2;
|
||||
if(val_b64_sz > 0) {
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, val_b64,
|
||||
val_b64_sz);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
@ -639,13 +644,13 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)" ", 1);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, bvals[i].bv_val,
|
||||
bvals[i].bv_len);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
@ -654,7 +659,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
|
||||
data->req.bytecount += bvals[i].bv_len + 1;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
@ -663,14 +668,14 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
data->req.bytecount++;
|
||||
}
|
||||
ber_memfree(bvals);
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
}
|
||||
data->req.bytecount++;
|
||||
}
|
||||
writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
|
||||
if(writeerr) {
|
||||
*err = writeerr;
|
||||
return -1;
|
||||
@ -724,7 +729,7 @@ ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
|
||||
ber_slen_t ret;
|
||||
CURLcode err = CURLE_RECV_ERROR;
|
||||
|
||||
ret = (li->recv)(conn, FIRSTSOCKET, buf, len, &err);
|
||||
ret = (li->recv)(conn->data, FIRSTSOCKET, buf, len, &err);
|
||||
if(ret < 0 && err == CURLE_AGAIN) {
|
||||
SET_SOCKERRNO(EWOULDBLOCK);
|
||||
}
|
||||
@ -739,7 +744,7 @@ ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
|
||||
ber_slen_t ret;
|
||||
CURLcode err = CURLE_SEND_ERROR;
|
||||
|
||||
ret = (li->send)(conn, FIRSTSOCKET, buf, len, &err);
|
||||
ret = (li->send)(conn->data, FIRSTSOCKET, buf, len, &err);
|
||||
if(ret < 0 && err == CURLE_AGAIN) {
|
||||
SET_SOCKERRNO(EWOULDBLOCK);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -44,10 +44,10 @@
|
||||
|
||||
/* Returns timeout in ms. 0 or negative number means the timeout has already
|
||||
triggered */
|
||||
timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
|
||||
timediff_t Curl_pp_state_timeout(struct Curl_easy *data,
|
||||
struct pingpong *pp, bool disconnecting)
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
struct Curl_easy *data = conn->data;
|
||||
timediff_t timeout_ms; /* in milliseconds */
|
||||
timediff_t response_time = (data->set.server_response_timeout)?
|
||||
data->set.server_response_timeout: pp->response_time;
|
||||
@ -77,15 +77,15 @@ timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
|
||||
/*
|
||||
* Curl_pp_statemach()
|
||||
*/
|
||||
CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
|
||||
CURLcode Curl_pp_statemach(struct Curl_easy *data,
|
||||
struct pingpong *pp, bool block,
|
||||
bool disconnecting)
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
int rc;
|
||||
timediff_t interval_ms;
|
||||
timediff_t timeout_ms = Curl_pp_state_timeout(pp, disconnecting);
|
||||
struct Curl_easy *data = conn->data;
|
||||
timediff_t timeout_ms = Curl_pp_state_timeout(data, pp, disconnecting);
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(timeout_ms <= 0) {
|
||||
@ -131,17 +131,17 @@ CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(rc)
|
||||
result = pp->statemach_act(conn);
|
||||
result = pp->statemachine(data, pp->conn);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* initialize stuff to prepare for reading a fresh new response */
|
||||
void Curl_pp_init(struct pingpong *pp)
|
||||
void Curl_pp_init(struct Curl_easy *data, struct pingpong *pp)
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
DEBUGASSERT(data);
|
||||
pp->nread_resp = 0;
|
||||
pp->linestart_resp = conn->data->state.buffer;
|
||||
pp->linestart_resp = data->state.buffer;
|
||||
pp->pending_resp = TRUE;
|
||||
pp->response = Curl_now(); /* start response time-out now! */
|
||||
}
|
||||
@ -162,7 +162,8 @@ void Curl_pp_setup(struct pingpong *pp)
|
||||
*
|
||||
* made to never block
|
||||
*/
|
||||
CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
CURLcode Curl_pp_vsendf(struct Curl_easy *data,
|
||||
struct pingpong *pp,
|
||||
const char *fmt,
|
||||
va_list args)
|
||||
{
|
||||
@ -171,7 +172,6 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
char *s;
|
||||
CURLcode result;
|
||||
struct connectdata *conn = pp->conn;
|
||||
struct Curl_easy *data;
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
enum protection_level data_sec;
|
||||
@ -184,7 +184,6 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
if(!conn)
|
||||
/* can't send without a connection! */
|
||||
return CURLE_SEND_ERROR;
|
||||
data = conn->data;
|
||||
|
||||
Curl_dyn_reset(&pp->sendbuf);
|
||||
result = Curl_dyn_vaddf(&pp->sendbuf, fmt, args);
|
||||
@ -198,7 +197,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
|
||||
write_len = Curl_dyn_len(&pp->sendbuf);
|
||||
s = Curl_dyn_ptr(&pp->sendbuf);
|
||||
Curl_pp_init(pp);
|
||||
Curl_pp_init(data, pp);
|
||||
|
||||
result = Curl_convert_to_network(data, s, write_len);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
@ -208,7 +207,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
#ifdef HAVE_GSSAPI
|
||||
conn->data_prot = PROT_CMD;
|
||||
#endif
|
||||
result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
|
||||
result = Curl_write(data, conn->sock[FIRSTSOCKET], s, write_len,
|
||||
&bytes_written);
|
||||
if(result)
|
||||
return result;
|
||||
@ -246,14 +245,14 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
*
|
||||
* made to never block
|
||||
*/
|
||||
CURLcode Curl_pp_sendf(struct pingpong *pp,
|
||||
CURLcode Curl_pp_sendf(struct Curl_easy *data, struct pingpong *pp,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
CURLcode result;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
result = Curl_pp_vsendf(pp, fmt, ap);
|
||||
result = Curl_pp_vsendf(data, pp, fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
@ -265,7 +264,8 @@ CURLcode Curl_pp_sendf(struct pingpong *pp,
|
||||
*
|
||||
* Reads a piece of a server response.
|
||||
*/
|
||||
CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
CURLcode Curl_pp_readresp(struct Curl_easy *data,
|
||||
curl_socket_t sockfd,
|
||||
struct pingpong *pp,
|
||||
int *code, /* return the server code if done */
|
||||
size_t *size) /* size of the response */
|
||||
@ -275,7 +275,6 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
ssize_t gotbytes;
|
||||
char *ptr;
|
||||
struct connectdata *conn = pp->conn;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char * const buf = data->state.buffer;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
@ -315,7 +314,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
#endif
|
||||
DEBUGASSERT((ptr + data->set.buffer_size - pp->nread_resp) <=
|
||||
(buf + data->set.buffer_size + 1));
|
||||
result = Curl_read(conn, sockfd, ptr,
|
||||
result = Curl_read(data, sockfd, ptr,
|
||||
data->set.buffer_size - pp->nread_resp,
|
||||
&gotbytes);
|
||||
#ifdef HAVE_GSSAPI
|
||||
@ -371,12 +370,12 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
* for "headers". The response lines can be seen as a kind of
|
||||
* headers.
|
||||
*/
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER,
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER,
|
||||
pp->linestart_resp, perline);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(pp->endofresp(conn, pp->linestart_resp, perline, code)) {
|
||||
if(pp->endofresp(data, conn, pp->linestart_resp, perline, code)) {
|
||||
/* This is the end of the last line, copy the last line to the
|
||||
start of the buffer and null-terminate, for old times sake */
|
||||
size_t n = ptr - pp->linestart_resp;
|
||||
@ -456,8 +455,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
return result;
|
||||
}
|
||||
|
||||
int Curl_pp_getsock(struct pingpong *pp,
|
||||
curl_socket_t *socks)
|
||||
int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks)
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
@ -477,7 +475,7 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp)
|
||||
struct connectdata *conn = pp->conn;
|
||||
ssize_t written;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize -
|
||||
CURLcode result = Curl_write(conn->data, sock, pp->sendthis + pp->sendsize -
|
||||
pp->sendleft, pp->sendleft, &written);
|
||||
if(result)
|
||||
return result;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -62,37 +62,44 @@ struct pingpong {
|
||||
off, used to time-out response reading */
|
||||
timediff_t response_time; /* When no timeout is given, this is the amount of
|
||||
milliseconds we await for a server response. */
|
||||
struct connectdata *conn; /* points to the connectdata struct that this
|
||||
belongs to */
|
||||
struct connectdata *conn; /* the connection */
|
||||
struct dynbuf sendbuf;
|
||||
|
||||
/* Function pointers the protocols MUST implement and provide for the
|
||||
pingpong layer to function */
|
||||
|
||||
CURLcode (*statemach_act)(struct connectdata *conn);
|
||||
|
||||
bool (*endofresp)(struct connectdata *conn, char *ptr, size_t len,
|
||||
int *code);
|
||||
CURLcode (*statemachine)(struct Curl_easy *data, struct connectdata *conn);
|
||||
bool (*endofresp)(struct Curl_easy *data, struct connectdata *conn,
|
||||
char *ptr, size_t len, int *code);
|
||||
};
|
||||
|
||||
#define PINGPONG_SETUP(pp,s,e) \
|
||||
do { \
|
||||
pp->response_time = RESP_TIMEOUT; \
|
||||
pp->statemachine = s; \
|
||||
pp->endofresp = e; \
|
||||
pp->conn = conn; \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* Curl_pp_statemach()
|
||||
*
|
||||
* called repeatedly until done. Set 'wait' to make it wait a while on the
|
||||
* socket if there's no traffic.
|
||||
*/
|
||||
CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
|
||||
bool disconnecting);
|
||||
CURLcode Curl_pp_statemach(struct Curl_easy *data, struct pingpong *pp,
|
||||
bool block, bool disconnecting);
|
||||
|
||||
/* initialize stuff to prepare for reading a fresh new response */
|
||||
void Curl_pp_init(struct pingpong *pp);
|
||||
void Curl_pp_init(struct Curl_easy *data, struct pingpong *pp);
|
||||
|
||||
/* setup for the transfer */
|
||||
void Curl_pp_setup(struct pingpong *pp);
|
||||
|
||||
/* Returns timeout in ms. 0 or negative number means the timeout has already
|
||||
triggered */
|
||||
timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
|
||||
timediff_t Curl_pp_state_timeout(struct Curl_easy *data,
|
||||
struct pingpong *pp, bool disconnecting);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
@ -105,7 +112,8 @@ timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
|
||||
*
|
||||
* made to never block
|
||||
*/
|
||||
CURLcode Curl_pp_sendf(struct pingpong *pp,
|
||||
CURLcode Curl_pp_sendf(struct Curl_easy *data,
|
||||
struct pingpong *pp,
|
||||
const char *fmt, ...);
|
||||
|
||||
/***********************************************************************
|
||||
@ -118,7 +126,8 @@ CURLcode Curl_pp_sendf(struct pingpong *pp,
|
||||
*
|
||||
* made to never block
|
||||
*/
|
||||
CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
CURLcode Curl_pp_vsendf(struct Curl_easy *data,
|
||||
struct pingpong *pp,
|
||||
const char *fmt,
|
||||
va_list args);
|
||||
|
||||
@ -127,7 +136,8 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
*
|
||||
* Reads a piece of a server response.
|
||||
*/
|
||||
CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
CURLcode Curl_pp_readresp(struct Curl_easy *data,
|
||||
curl_socket_t sockfd,
|
||||
struct pingpong *pp,
|
||||
int *code, /* return the server code if done */
|
||||
size_t *size); /* size of the response */
|
||||
|
345
lib/pop3.c
345
lib/pop3.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -88,22 +88,27 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Local API functions */
|
||||
static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done);
|
||||
static CURLcode pop3_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode pop3_regular_transfer(struct Curl_easy *data, bool *done);
|
||||
static CURLcode pop3_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode pop3_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature);
|
||||
static CURLcode pop3_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode pop3_disconnect(struct connectdata *conn, bool dead);
|
||||
static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done);
|
||||
static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
|
||||
static CURLcode pop3_setup_connection(struct connectdata *conn);
|
||||
static CURLcode pop3_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode pop3_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static int pop3_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static CURLcode pop3_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static CURLcode pop3_parse_url_options(struct connectdata *conn);
|
||||
static CURLcode pop3_parse_url_path(struct connectdata *conn);
|
||||
static CURLcode pop3_parse_custom_request(struct connectdata *conn);
|
||||
static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech,
|
||||
static CURLcode pop3_parse_url_path(struct Curl_easy *data);
|
||||
static CURLcode pop3_parse_custom_request(struct Curl_easy *data);
|
||||
static CURLcode pop3_perform_auth(struct Curl_easy *data,
|
||||
struct connectdata *conn, const char *mech,
|
||||
const char *initresp);
|
||||
static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp);
|
||||
static CURLcode pop3_continue_auth(struct Curl_easy *data,
|
||||
struct connectdata *conn, const char *resp);
|
||||
static void pop3_get_message(char *buffer, char **outptr);
|
||||
|
||||
/*
|
||||
@ -195,10 +200,11 @@ static void pop3_to_pop3s(struct connectdata *conn)
|
||||
* capabilities from the CAPA response including the supported authentication
|
||||
* types and allowed SASL mechanisms.
|
||||
*/
|
||||
static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
|
||||
int *resp)
|
||||
static bool pop3_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
||||
char *line, size_t len, int *resp)
|
||||
{
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
(void)data;
|
||||
|
||||
/* Do we have an error response? */
|
||||
if(len >= 4 && !memcmp("-ERR", line, 4)) {
|
||||
@ -279,9 +285,9 @@ static void pop3_get_message(char *buffer, char **outptr)
|
||||
*
|
||||
* This is the ONLY way to change POP3 state!
|
||||
*/
|
||||
static void state(struct connectdata *conn, pop3state newstate)
|
||||
static void state(struct Curl_easy *data, pop3state newstate)
|
||||
{
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
struct pop3_conn *pop3c = &data->conn->proto.pop3c;
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
/* for debug purposes */
|
||||
static const char * const names[] = {
|
||||
@ -300,7 +306,7 @@ static void state(struct connectdata *conn, pop3state newstate)
|
||||
};
|
||||
|
||||
if(pop3c->state != newstate)
|
||||
infof(conn->data, "POP3 %p state change from %s to %s\n",
|
||||
infof(data, "POP3 %p state change from %s to %s\n",
|
||||
(void *)pop3c, names[pop3c->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
@ -314,7 +320,8 @@ static void state(struct connectdata *conn, pop3state newstate)
|
||||
* Sends the CAPA command in order to obtain a list of server side supported
|
||||
* capabilities.
|
||||
*/
|
||||
static CURLcode pop3_perform_capa(struct connectdata *conn)
|
||||
static CURLcode pop3_perform_capa(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
@ -324,10 +331,10 @@ static CURLcode pop3_perform_capa(struct connectdata *conn)
|
||||
pop3c->tls_supported = FALSE; /* Clear the TLS capability */
|
||||
|
||||
/* Send the CAPA command */
|
||||
result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA");
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "%s", "CAPA");
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_CAPA);
|
||||
state(data, POP3_CAPA);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -338,13 +345,14 @@ static CURLcode pop3_perform_capa(struct connectdata *conn)
|
||||
*
|
||||
* Sends the STLS command to start the upgrade to TLS.
|
||||
*/
|
||||
static CURLcode pop3_perform_starttls(struct connectdata *conn)
|
||||
static CURLcode pop3_perform_starttls(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
/* Send the STLS command */
|
||||
CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
|
||||
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "STLS");
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_STARTTLS);
|
||||
state(data, POP3_STARTTLS);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -355,7 +363,8 @@ static CURLcode pop3_perform_starttls(struct connectdata *conn)
|
||||
*
|
||||
* Performs the upgrade to TLS.
|
||||
*/
|
||||
static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
|
||||
static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
/* Start the SSL connection */
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
@ -364,11 +373,11 @@ static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
|
||||
|
||||
if(!result) {
|
||||
if(pop3c->state != POP3_UPGRADETLS)
|
||||
state(conn, POP3_UPGRADETLS);
|
||||
state(data, POP3_UPGRADETLS);
|
||||
|
||||
if(pop3c->ssldone) {
|
||||
pop3_to_pop3s(conn);
|
||||
result = pop3_perform_capa(conn);
|
||||
result = pop3_perform_capa(data, conn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,23 +390,24 @@ static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
|
||||
*
|
||||
* Sends a clear text USER command to authenticate with.
|
||||
*/
|
||||
static CURLcode pop3_perform_user(struct connectdata *conn)
|
||||
static CURLcode pop3_perform_user(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we don't */
|
||||
if(!conn->bits.user_passwd) {
|
||||
state(conn, POP3_STOP);
|
||||
state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Send the USER command */
|
||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s",
|
||||
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "USER %s",
|
||||
conn->user ? conn->user : "");
|
||||
if(!result)
|
||||
state(conn, POP3_USER);
|
||||
state(data, POP3_USER);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -409,7 +419,8 @@ static CURLcode pop3_perform_user(struct connectdata *conn)
|
||||
*
|
||||
* Sends an APOP command to authenticate with.
|
||||
*/
|
||||
static CURLcode pop3_perform_apop(struct connectdata *conn)
|
||||
static CURLcode pop3_perform_apop(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
@ -421,7 +432,7 @@ static CURLcode pop3_perform_apop(struct connectdata *conn)
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we don't */
|
||||
if(!conn->bits.user_passwd) {
|
||||
state(conn, POP3_STOP);
|
||||
state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -444,10 +455,10 @@ static CURLcode pop3_perform_apop(struct connectdata *conn)
|
||||
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
msnprintf(&secret[2 * i], 3, "%02x", digest[i]);
|
||||
|
||||
result = Curl_pp_sendf(&pop3c->pp, "APOP %s %s", conn->user, secret);
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s", conn->user, secret);
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_APOP);
|
||||
state(data, POP3_APOP);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -460,7 +471,8 @@ static CURLcode pop3_perform_apop(struct connectdata *conn)
|
||||
* Sends an AUTH command allowing the client to login with the given SASL
|
||||
* authentication mechanism.
|
||||
*/
|
||||
static CURLcode pop3_perform_auth(struct connectdata *conn,
|
||||
static CURLcode pop3_perform_auth(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const char *mech,
|
||||
const char *initresp)
|
||||
{
|
||||
@ -469,11 +481,11 @@ static CURLcode pop3_perform_auth(struct connectdata *conn,
|
||||
|
||||
if(initresp) { /* AUTH <mech> ...<crlf> */
|
||||
/* Send the AUTH command with the initial response */
|
||||
result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp);
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "AUTH %s %s", mech, initresp);
|
||||
}
|
||||
else {
|
||||
/* Send the AUTH command */
|
||||
result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "AUTH %s", mech);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -485,12 +497,13 @@ static CURLcode pop3_perform_auth(struct connectdata *conn,
|
||||
*
|
||||
* Sends SASL continuation data or cancellation.
|
||||
*/
|
||||
static CURLcode pop3_continue_auth(struct connectdata *conn,
|
||||
static CURLcode pop3_continue_auth(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const char *resp)
|
||||
{
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
|
||||
return Curl_pp_sendf(&pop3c->pp, "%s", resp);
|
||||
return Curl_pp_sendf(data, &pop3c->pp, "%s", resp);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@ -501,7 +514,8 @@ static CURLcode pop3_continue_auth(struct connectdata *conn,
|
||||
* authentication mechanism, falling back to APOP and clear text should a
|
||||
* common mechanism not be available between the client and server.
|
||||
*/
|
||||
static CURLcode pop3_perform_authentication(struct connectdata *conn)
|
||||
static CURLcode pop3_perform_authentication(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
@ -510,7 +524,7 @@ static CURLcode pop3_perform_authentication(struct connectdata *conn)
|
||||
/* Check we have enough data to authenticate with and end the
|
||||
connect phase if we don't */
|
||||
if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) {
|
||||
state(conn, POP3_STOP);
|
||||
state(data, POP3_STOP);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -520,22 +534,22 @@ static CURLcode pop3_perform_authentication(struct connectdata *conn)
|
||||
|
||||
if(!result)
|
||||
if(progress == SASL_INPROGRESS)
|
||||
state(conn, POP3_AUTH);
|
||||
state(data, POP3_AUTH);
|
||||
}
|
||||
|
||||
if(!result && progress == SASL_IDLE) {
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
|
||||
/* Perform APOP authentication */
|
||||
result = pop3_perform_apop(conn);
|
||||
result = pop3_perform_apop(data, conn);
|
||||
else
|
||||
#endif
|
||||
if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
|
||||
/* Perform clear text authentication */
|
||||
result = pop3_perform_user(conn);
|
||||
result = pop3_perform_user(data, conn);
|
||||
else {
|
||||
/* Other mechanisms not supported */
|
||||
infof(conn->data, "No known authentication mechanisms supported!\n");
|
||||
infof(data, "No known authentication mechanisms supported!\n");
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
@ -549,15 +563,15 @@ static CURLcode pop3_perform_authentication(struct connectdata *conn)
|
||||
*
|
||||
* Sends a POP3 based command.
|
||||
*/
|
||||
static CURLcode pop3_perform_command(struct connectdata *conn)
|
||||
static CURLcode pop3_perform_command(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct POP3 *pop3 = data->req.p.pop3;
|
||||
const char *command = NULL;
|
||||
|
||||
/* Calculate the default command */
|
||||
if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) {
|
||||
if(pop3->id[0] == '\0' || data->set.ftp_list_only) {
|
||||
command = "LIST";
|
||||
|
||||
if(pop3->id[0] != '\0')
|
||||
@ -569,16 +583,16 @@ static CURLcode pop3_perform_command(struct connectdata *conn)
|
||||
|
||||
/* Send the command */
|
||||
if(pop3->id[0] != '\0')
|
||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
|
||||
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s %s",
|
||||
(pop3->custom && pop3->custom[0] != '\0' ?
|
||||
pop3->custom : command), pop3->id);
|
||||
else
|
||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s",
|
||||
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s",
|
||||
(pop3->custom && pop3->custom[0] != '\0' ?
|
||||
pop3->custom : command));
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_COMMAND);
|
||||
state(data, POP3_COMMAND);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -589,24 +603,25 @@ static CURLcode pop3_perform_command(struct connectdata *conn)
|
||||
*
|
||||
* Performs the quit action prior to sclose() be called.
|
||||
*/
|
||||
static CURLcode pop3_perform_quit(struct connectdata *conn)
|
||||
static CURLcode pop3_perform_quit(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
/* Send the QUIT command */
|
||||
CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
|
||||
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "QUIT");
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_QUIT);
|
||||
state(data, POP3_QUIT);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For the initial server greeting */
|
||||
static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
|
||||
static CURLcode pop3_state_servergreet_resp(struct Curl_easy *data,
|
||||
int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
const char *line = data->state.buffer;
|
||||
size_t len = strlen(line);
|
||||
@ -654,18 +669,18 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
result = pop3_perform_capa(conn);
|
||||
result = pop3_perform_capa(data, conn);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For CAPA responses */
|
||||
static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
|
||||
static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
const char *line = data->state.buffer;
|
||||
size_t len = strlen(line);
|
||||
@ -728,36 +743,35 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
|
||||
/* We don't have a SSL/TLS connection yet, but SSL is requested */
|
||||
if(pop3c->tls_supported)
|
||||
/* Switch to TLS connection now */
|
||||
result = pop3_perform_starttls(conn);
|
||||
result = pop3_perform_starttls(data, conn);
|
||||
else if(data->set.use_ssl == CURLUSESSL_TRY)
|
||||
/* Fallback and carry on with authentication */
|
||||
result = pop3_perform_authentication(conn);
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
else {
|
||||
failf(data, "STLS not supported.");
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
result = pop3_perform_authentication(conn);
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
}
|
||||
else {
|
||||
/* Clear text is supported when CAPA isn't recognised */
|
||||
pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
|
||||
|
||||
result = pop3_perform_authentication(conn);
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For STARTTLS responses */
|
||||
static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
|
||||
static CURLcode pop3_state_starttls_resp(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(pop3code != '+') {
|
||||
@ -766,21 +780,21 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
else
|
||||
result = pop3_perform_authentication(conn);
|
||||
result = pop3_perform_authentication(data, conn);
|
||||
}
|
||||
else
|
||||
result = pop3_perform_upgrade_tls(conn);
|
||||
result = pop3_perform_upgrade_tls(data, conn);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For SASL authentication responses */
|
||||
static CURLcode pop3_state_auth_resp(struct connectdata *conn,
|
||||
static CURLcode pop3_state_auth_resp(struct Curl_easy *data,
|
||||
int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
saslprogress progress;
|
||||
|
||||
@ -790,18 +804,18 @@ static CURLcode pop3_state_auth_resp(struct connectdata *conn,
|
||||
if(!result)
|
||||
switch(progress) {
|
||||
case SASL_DONE:
|
||||
state(conn, POP3_STOP); /* Authenticated */
|
||||
state(data, POP3_STOP); /* Authenticated */
|
||||
break;
|
||||
case SASL_IDLE: /* No mechanism left after cancellation */
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
|
||||
/* Perform APOP authentication */
|
||||
result = pop3_perform_apop(conn);
|
||||
result = pop3_perform_apop(data, conn);
|
||||
else
|
||||
#endif
|
||||
if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
|
||||
/* Perform clear text authentication */
|
||||
result = pop3_perform_user(conn);
|
||||
result = pop3_perform_user(data, conn);
|
||||
else {
|
||||
failf(data, "Authentication cancelled");
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
@ -816,12 +830,10 @@ static CURLcode pop3_state_auth_resp(struct connectdata *conn,
|
||||
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
/* For APOP responses */
|
||||
static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code,
|
||||
static CURLcode pop3_state_apop_resp(struct Curl_easy *data, int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(pop3code != '+') {
|
||||
@ -830,19 +842,18 @@ static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code,
|
||||
}
|
||||
else
|
||||
/* End of connect phase */
|
||||
state(conn, POP3_STOP);
|
||||
state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For USER responses */
|
||||
static CURLcode pop3_state_user_resp(struct connectdata *conn, int pop3code,
|
||||
static CURLcode pop3_state_user_resp(struct Curl_easy *data, int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(pop3code != '+') {
|
||||
@ -851,21 +862,19 @@ static CURLcode pop3_state_user_resp(struct connectdata *conn, int pop3code,
|
||||
}
|
||||
else
|
||||
/* Send the PASS command */
|
||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s",
|
||||
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "PASS %s",
|
||||
conn->passwd ? conn->passwd : "");
|
||||
if(!result)
|
||||
state(conn, POP3_PASS);
|
||||
state(data, POP3_PASS);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For PASS responses */
|
||||
static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code,
|
||||
static CURLcode pop3_state_pass_resp(struct Curl_easy *data, int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(pop3code != '+') {
|
||||
@ -874,18 +883,18 @@ static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code,
|
||||
}
|
||||
else
|
||||
/* End of connect phase */
|
||||
state(conn, POP3_STOP);
|
||||
state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For command responses */
|
||||
static CURLcode pop3_state_command_resp(struct connectdata *conn,
|
||||
static CURLcode pop3_state_command_resp(struct Curl_easy *data,
|
||||
int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct POP3 *pop3 = data->req.p.pop3;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
struct pingpong *pp = &pop3c->pp;
|
||||
@ -893,7 +902,7 @@ static CURLcode pop3_state_command_resp(struct connectdata *conn,
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(pop3code != '+') {
|
||||
state(conn, POP3_STOP);
|
||||
state(data, POP3_STOP);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
@ -917,7 +926,7 @@ static CURLcode pop3_state_command_resp(struct connectdata *conn,
|
||||
"headers" after the body */
|
||||
|
||||
if(!data->set.opt_no_body) {
|
||||
result = Curl_pop3_write(conn, pp->cache, pp->cache_size);
|
||||
result = Curl_pop3_write(data, pp->cache, pp->cache_size);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -931,12 +940,13 @@ static CURLcode pop3_state_command_resp(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* End of DO phase */
|
||||
state(conn, POP3_STOP);
|
||||
state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
static CURLcode pop3_statemachine(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
@ -944,10 +954,11 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
struct pingpong *pp = &pop3c->pp;
|
||||
size_t nread = 0;
|
||||
(void)data;
|
||||
|
||||
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
|
||||
if(pop3c->state == POP3_UPGRADETLS)
|
||||
return pop3_perform_upgrade_tls(conn);
|
||||
return pop3_perform_upgrade_tls(data, conn);
|
||||
|
||||
/* Flush any data that needs to be sent */
|
||||
if(pp->sendleft)
|
||||
@ -955,9 +966,9 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
|
||||
do {
|
||||
/* Read the response from the server */
|
||||
result = Curl_pp_readresp(sock, pp, &pop3code, &nread);
|
||||
if(result)
|
||||
return result;
|
||||
result = Curl_pp_readresp(data, sock, pp, &pop3code, &nread);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!pop3code)
|
||||
break;
|
||||
@ -965,44 +976,44 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
/* We have now received a full POP3 server response */
|
||||
switch(pop3c->state) {
|
||||
case POP3_SERVERGREET:
|
||||
result = pop3_state_servergreet_resp(conn, pop3code, pop3c->state);
|
||||
result = pop3_state_servergreet_resp(data, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_CAPA:
|
||||
result = pop3_state_capa_resp(conn, pop3code, pop3c->state);
|
||||
result = pop3_state_capa_resp(data, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_STARTTLS:
|
||||
result = pop3_state_starttls_resp(conn, pop3code, pop3c->state);
|
||||
result = pop3_state_starttls_resp(data, conn, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_AUTH:
|
||||
result = pop3_state_auth_resp(conn, pop3code, pop3c->state);
|
||||
result = pop3_state_auth_resp(data, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
case POP3_APOP:
|
||||
result = pop3_state_apop_resp(conn, pop3code, pop3c->state);
|
||||
result = pop3_state_apop_resp(data, pop3code, pop3c->state);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case POP3_USER:
|
||||
result = pop3_state_user_resp(conn, pop3code, pop3c->state);
|
||||
result = pop3_state_user_resp(data, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_PASS:
|
||||
result = pop3_state_pass_resp(conn, pop3code, pop3c->state);
|
||||
result = pop3_state_pass_resp(data, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_COMMAND:
|
||||
result = pop3_state_command_resp(conn, pop3code, pop3c->state);
|
||||
result = pop3_state_command_resp(data, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_QUIT:
|
||||
/* fallthrough, just stop! */
|
||||
default:
|
||||
/* internal error */
|
||||
state(conn, POP3_STOP);
|
||||
state(data, POP3_STOP);
|
||||
break;
|
||||
}
|
||||
} while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
|
||||
@ -1011,9 +1022,10 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* Called repeatedly until done from multi.c */
|
||||
static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done)
|
||||
static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
|
||||
if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) {
|
||||
@ -1022,30 +1034,30 @@ static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_pp_statemach(&pop3c->pp, FALSE, FALSE);
|
||||
result = Curl_pp_statemach(data, &pop3c->pp, FALSE, FALSE);
|
||||
*done = (pop3c->state == POP3_STOP) ? TRUE : FALSE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode pop3_block_statemach(struct connectdata *conn,
|
||||
static CURLcode pop3_block_statemach(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool disconnecting)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
|
||||
while(pop3c->state != POP3_STOP && !result)
|
||||
result = Curl_pp_statemach(&pop3c->pp, TRUE, disconnecting);
|
||||
result = Curl_pp_statemach(data, &pop3c->pp, TRUE, disconnecting);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Allocate and initialize the POP3 struct for the current Curl_easy if
|
||||
required */
|
||||
static CURLcode pop3_init(struct connectdata *conn)
|
||||
static CURLcode pop3_init(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct POP3 *pop3;
|
||||
|
||||
pop3 = data->req.p.pop3 = calloc(sizeof(struct POP3), 1);
|
||||
@ -1056,8 +1068,10 @@ static CURLcode pop3_init(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* For the POP3 "protocol connect" and "doing" phases only */
|
||||
static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
static int pop3_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
{
|
||||
(void)data;
|
||||
return Curl_pp_getsock(&conn->proto.pop3c.pp, socks);
|
||||
}
|
||||
|
||||
@ -1071,9 +1085,10 @@ static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
* The variable 'done' points to will be TRUE if the protocol-layer connect
|
||||
* phase is done when this function returns, or FALSE if not.
|
||||
*/
|
||||
static CURLcode pop3_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode pop3_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
struct pingpong *pp = &pop3c->pp;
|
||||
|
||||
@ -1082,11 +1097,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
|
||||
/* We always support persistent connections in POP3 */
|
||||
connkeep(conn, "POP3 default");
|
||||
|
||||
/* Set the default response time-out */
|
||||
pp->response_time = RESP_TIMEOUT;
|
||||
pp->statemach_act = pop3_statemach_act;
|
||||
pp->endofresp = pop3_endofresp;
|
||||
pp->conn = conn;
|
||||
PINGPONG_SETUP(pp, pop3_statemachine, pop3_endofresp);
|
||||
|
||||
/* Set the default preferred authentication type and mechanism */
|
||||
pop3c->preftype = POP3_TYPE_ANY;
|
||||
@ -1094,7 +1105,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
/* Initialise the pingpong layer */
|
||||
Curl_pp_setup(pp);
|
||||
Curl_pp_init(pp);
|
||||
Curl_pp_init(data, pp);
|
||||
|
||||
/* Parse the URL options */
|
||||
result = pop3_parse_url_options(conn);
|
||||
@ -1102,9 +1113,9 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
|
||||
/* Start off waiting for the server greeting response */
|
||||
state(conn, POP3_SERVERGREET);
|
||||
state(data, POP3_SERVERGREET);
|
||||
|
||||
result = pop3_multi_statemach(conn, done);
|
||||
result = pop3_multi_statemach(data, done);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1118,11 +1129,10 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
|
||||
*
|
||||
* Input argument is already checked for validity.
|
||||
*/
|
||||
static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode pop3_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct POP3 *pop3 = data->req.p.pop3;
|
||||
|
||||
(void)premature;
|
||||
@ -1131,7 +1141,7 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
|
||||
return CURLE_OK;
|
||||
|
||||
if(status) {
|
||||
connclose(conn, "POP3 done with bad status");
|
||||
connclose(data->conn, "POP3 done with bad status");
|
||||
result = status; /* use the already set error code */
|
||||
}
|
||||
|
||||
@ -1152,16 +1162,17 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
|
||||
* This is the actual DO function for POP3. Get a message/listing according to
|
||||
* the options previously setup.
|
||||
*/
|
||||
static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
|
||||
static CURLcode pop3_perform(struct Curl_easy *data, bool *connected,
|
||||
bool *dophase_done)
|
||||
{
|
||||
/* This is POP3 and no proxy */
|
||||
CURLcode result = CURLE_OK;
|
||||
struct POP3 *pop3 = conn->data->req.p.pop3;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct POP3 *pop3 = data->req.p.pop3;
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
|
||||
if(conn->data->set.opt_no_body) {
|
||||
if(data->set.opt_no_body) {
|
||||
/* Requested no body means no transfer */
|
||||
pop3->transfer = FTPTRANSFER_INFO;
|
||||
}
|
||||
@ -1169,17 +1180,16 @@ static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
|
||||
*dophase_done = FALSE; /* not done yet */
|
||||
|
||||
/* Start the first command in the DO phase */
|
||||
result = pop3_perform_command(conn);
|
||||
result = pop3_perform_command(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Run the state-machine */
|
||||
result = pop3_multi_statemach(conn, dophase_done);
|
||||
|
||||
result = pop3_multi_statemach(data, dophase_done);
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1193,23 +1203,22 @@ static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
|
||||
*
|
||||
* The input argument is already checked for validity.
|
||||
*/
|
||||
static CURLcode pop3_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode pop3_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
|
||||
/* Parse the URL path */
|
||||
result = pop3_parse_url_path(conn);
|
||||
result = pop3_parse_url_path(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Parse the custom request */
|
||||
result = pop3_parse_custom_request(conn);
|
||||
result = pop3_parse_custom_request(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = pop3_regular_transfer(conn, done);
|
||||
result = pop3_regular_transfer(data, done);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1221,19 +1230,20 @@ static CURLcode pop3_do(struct connectdata *conn, bool *done)
|
||||
* Disconnect from an POP3 server. Cleanup protocol-specific per-connection
|
||||
* resources. BLOCKING.
|
||||
*/
|
||||
static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
static CURLcode pop3_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead_connection)
|
||||
{
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
(void)data;
|
||||
|
||||
/* We cannot send quit unconditionally. If this connection is stale or
|
||||
bad in any way, sending quit and waiting around here will make the
|
||||
disconnect wait in vain and cause more problems than we need to. */
|
||||
|
||||
/* The POP3 session may or may not have been allocated/setup at this
|
||||
point! */
|
||||
if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart)
|
||||
if(!pop3_perform_quit(conn))
|
||||
(void)pop3_block_statemach(conn, TRUE); /* ignore errors on QUIT */
|
||||
if(!dead_connection && conn->bits.protoconnstart) {
|
||||
if(!pop3_perform_quit(data, conn))
|
||||
(void)pop3_block_statemach(data, conn, TRUE); /* ignore errors on QUIT */
|
||||
}
|
||||
|
||||
/* Disconnect from the server */
|
||||
Curl_pp_disconnect(&pop3c->pp);
|
||||
@ -1248,25 +1258,25 @@ static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
}
|
||||
|
||||
/* Call this when the DO phase has completed */
|
||||
static CURLcode pop3_dophase_done(struct connectdata *conn, bool connected)
|
||||
static CURLcode pop3_dophase_done(struct Curl_easy *data, bool connected)
|
||||
{
|
||||
(void)conn;
|
||||
(void)data;
|
||||
(void)connected;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Called from multi.c while DOing */
|
||||
static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done)
|
||||
static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done)
|
||||
{
|
||||
CURLcode result = pop3_multi_statemach(conn, dophase_done);
|
||||
CURLcode result = pop3_multi_statemach(data, dophase_done);
|
||||
|
||||
if(result)
|
||||
DEBUGF(infof(conn->data, "DO phase failed\n"));
|
||||
DEBUGF(infof(data, "DO phase failed\n"));
|
||||
else if(*dophase_done) {
|
||||
result = pop3_dophase_done(conn, FALSE /* not connected */);
|
||||
result = pop3_dophase_done(data, FALSE /* not connected */);
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1281,12 +1291,11 @@ static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done)
|
||||
* Performs all commands done before a regular transfer between a local and a
|
||||
* remote host.
|
||||
*/
|
||||
static CURLcode pop3_regular_transfer(struct connectdata *conn,
|
||||
static CURLcode pop3_regular_transfer(struct Curl_easy *data,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
bool connected = FALSE;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* Make sure size is unknown at this point */
|
||||
data->req.size = -1;
|
||||
@ -1298,19 +1307,20 @@ static CURLcode pop3_regular_transfer(struct connectdata *conn,
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
|
||||
/* Carry out the perform */
|
||||
result = pop3_perform(conn, &connected, dophase_done);
|
||||
result = pop3_perform(data, &connected, dophase_done);
|
||||
|
||||
/* Perform post DO phase operations if necessary */
|
||||
if(!result && *dophase_done)
|
||||
result = pop3_dophase_done(conn, connected);
|
||||
result = pop3_dophase_done(data, connected);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode pop3_setup_connection(struct connectdata *conn)
|
||||
static CURLcode pop3_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
/* Initialise the POP3 layer */
|
||||
CURLcode result = pop3_init(conn);
|
||||
CURLcode result = pop3_init(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -1385,10 +1395,9 @@ static CURLcode pop3_parse_url_options(struct connectdata *conn)
|
||||
*
|
||||
* Parse the URL path into separate path components.
|
||||
*/
|
||||
static CURLcode pop3_parse_url_path(struct connectdata *conn)
|
||||
static CURLcode pop3_parse_url_path(struct Curl_easy *data)
|
||||
{
|
||||
/* The POP3 struct is already initialised in pop3_connect() */
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct POP3 *pop3 = data->req.p.pop3;
|
||||
const char *path = &data->state.up.path[1]; /* skip leading path */
|
||||
|
||||
@ -1402,10 +1411,9 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn)
|
||||
*
|
||||
* Parse the custom request.
|
||||
*/
|
||||
static CURLcode pop3_parse_custom_request(struct connectdata *conn)
|
||||
static CURLcode pop3_parse_custom_request(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct POP3 *pop3 = data->req.p.pop3;
|
||||
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
|
||||
|
||||
@ -1423,13 +1431,12 @@ static CURLcode pop3_parse_custom_request(struct connectdata *conn)
|
||||
* This function scans the body after the end-of-body and writes everything
|
||||
* until the end is found.
|
||||
*/
|
||||
CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
|
||||
CURLcode Curl_pop3_write(struct Curl_easy *data, char *str, size_t nread)
|
||||
{
|
||||
/* This code could be made into a special function in the handler struct */
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
||||
struct connectdata *conn = data->conn;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
bool strip_dot = FALSE;
|
||||
size_t last = 0;
|
||||
@ -1450,7 +1457,7 @@ CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
|
||||
|
||||
if(i) {
|
||||
/* Write out the body part that didn't match */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, &str[last],
|
||||
i - last);
|
||||
|
||||
if(result)
|
||||
@ -1508,7 +1515,7 @@ CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
|
||||
if(prev) {
|
||||
/* If the partial match was the CRLF and dot then only write the CRLF
|
||||
as the server would have inserted the dot */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB,
|
||||
strip_dot ? prev - 1 : prev);
|
||||
|
||||
if(result)
|
||||
@ -1524,7 +1531,7 @@ CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
|
||||
/* We have a full match so the transfer is done, however we must transfer
|
||||
the CRLF at the start of the EOB as this is considered to be part of the
|
||||
message as per RFC-1939, sect. 3 */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB, 2);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB, 2);
|
||||
|
||||
k->keepon &= ~KEEP_RECV;
|
||||
pop3c->eob = 0;
|
||||
@ -1537,7 +1544,7 @@ CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
|
||||
return CURLE_OK;
|
||||
|
||||
if(nread - last) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, &str[last],
|
||||
nread - last);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2009 - 2021, 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
|
||||
@ -90,6 +90,6 @@ extern const struct Curl_handler Curl_handler_pop3s;
|
||||
|
||||
/* This function scans the body after the end-of-body and writes everything
|
||||
* until the end is found */
|
||||
CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread);
|
||||
CURLcode Curl_pop3_write(struct Curl_easy *data, char *str, size_t nread);
|
||||
|
||||
#endif /* HEADER_CURL_POP3_H */
|
||||
|
87
lib/rtsp.c
87
lib/rtsp.c
@ -48,11 +48,13 @@
|
||||
((int)((unsigned char)((p)[3]))))
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
static CURLcode rtsp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
static CURLcode rtsp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead);
|
||||
static int rtsp_getsock_do(struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode rtsp_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode rtsp_done(struct Curl_easy *data, CURLcode, bool premature);
|
||||
static CURLcode rtsp_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode rtsp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
static int rtsp_getsock_do(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
|
||||
/*
|
||||
* Parse and write out any available RTP data.
|
||||
@ -66,17 +68,20 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
|
||||
ssize_t *nread,
|
||||
bool *readmore);
|
||||
|
||||
static CURLcode rtsp_setup_connection(struct connectdata *conn);
|
||||
static unsigned int rtsp_conncheck(struct connectdata *check,
|
||||
static CURLcode rtsp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static unsigned int rtsp_conncheck(struct Curl_easy *data,
|
||||
struct connectdata *check,
|
||||
unsigned int checks_to_perform);
|
||||
|
||||
/* this returns the socket to wait for in the DO and DOING state for the multi
|
||||
interface and then we're always _sending_ a request and thus we wait for
|
||||
the single socket to become writable only */
|
||||
static int rtsp_getsock_do(struct connectdata *conn,
|
||||
static int rtsp_getsock_do(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
/* write mode */
|
||||
(void)data;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
@ -111,11 +116,13 @@ const struct Curl_handler Curl_handler_rtsp = {
|
||||
};
|
||||
|
||||
|
||||
static CURLcode rtsp_setup_connection(struct connectdata *conn)
|
||||
static CURLcode rtsp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct RTSP *rtsp;
|
||||
(void)conn;
|
||||
|
||||
conn->data->req.p.rtsp = rtsp = calloc(1, sizeof(struct RTSP));
|
||||
data->req.p.rtsp = rtsp = calloc(1, sizeof(struct RTSP));
|
||||
if(!rtsp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@ -156,13 +163,15 @@ static bool rtsp_connisdead(struct connectdata *check)
|
||||
/*
|
||||
* Function to check on various aspects of a connection.
|
||||
*/
|
||||
static unsigned int rtsp_conncheck(struct connectdata *check,
|
||||
static unsigned int rtsp_conncheck(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
unsigned int checks_to_perform)
|
||||
{
|
||||
unsigned int ret_val = CONNRESULT_NONE;
|
||||
(void)data;
|
||||
|
||||
if(checks_to_perform & CONNCHECK_ISDEAD) {
|
||||
if(rtsp_connisdead(check))
|
||||
if(rtsp_connisdead(conn))
|
||||
ret_val |= CONNRESULT_DEAD;
|
||||
}
|
||||
|
||||
@ -170,12 +179,11 @@ static unsigned int rtsp_conncheck(struct connectdata *check,
|
||||
}
|
||||
|
||||
|
||||
static CURLcode rtsp_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode rtsp_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode httpStatus;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
httpStatus = Curl_http_connect(conn, done);
|
||||
httpStatus = Curl_http_connect(data, done);
|
||||
|
||||
/* Initialize the CSeq if not already done */
|
||||
if(data->state.rtsp_next_client_CSeq == 0)
|
||||
@ -183,23 +191,24 @@ static CURLcode rtsp_connect(struct connectdata *conn, bool *done)
|
||||
if(data->state.rtsp_next_server_CSeq == 0)
|
||||
data->state.rtsp_next_server_CSeq = 1;
|
||||
|
||||
conn->proto.rtspc.rtp_channel = -1;
|
||||
data->conn->proto.rtspc.rtp_channel = -1;
|
||||
|
||||
return httpStatus;
|
||||
}
|
||||
|
||||
static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead)
|
||||
static CURLcode rtsp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead)
|
||||
{
|
||||
(void) dead;
|
||||
(void) data;
|
||||
Curl_safefree(conn->proto.rtspc.rtp_buf);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode rtsp_done(struct connectdata *conn,
|
||||
static CURLcode rtsp_done(struct Curl_easy *data,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct RTSP *rtsp = data->req.p.rtsp;
|
||||
CURLcode httpStatus;
|
||||
|
||||
@ -207,7 +216,7 @@ static CURLcode rtsp_done(struct connectdata *conn,
|
||||
if(data->set.rtspreq == RTSPREQ_RECEIVE)
|
||||
premature = TRUE;
|
||||
|
||||
httpStatus = Curl_http_done(conn, status, premature);
|
||||
httpStatus = Curl_http_done(data, status, premature);
|
||||
|
||||
if(rtsp) {
|
||||
/* Check the sequence numbers */
|
||||
@ -220,7 +229,7 @@ static CURLcode rtsp_done(struct connectdata *conn,
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
}
|
||||
if(data->set.rtspreq == RTSPREQ_RECEIVE &&
|
||||
(conn->proto.rtspc.rtp_channel == -1)) {
|
||||
(data->conn->proto.rtspc.rtp_channel == -1)) {
|
||||
infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
|
||||
}
|
||||
}
|
||||
@ -228,9 +237,9 @@ static CURLcode rtsp_done(struct connectdata *conn,
|
||||
return httpStatus;
|
||||
}
|
||||
|
||||
static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
CURLcode result = CURLE_OK;
|
||||
Curl_RtspReq rtspreq = data->set.rtspreq;
|
||||
struct RTSP *rtsp = data->req.p.rtsp;
|
||||
@ -330,7 +339,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
/* Transport Header for SETUP requests */
|
||||
p_transport = Curl_checkheaders(conn, "Transport");
|
||||
p_transport = Curl_checkheaders(data, "Transport");
|
||||
if(rtspreq == RTSPREQ_SETUP && !p_transport) {
|
||||
/* New Transport: setting? */
|
||||
if(data->set.str[STRING_RTSP_TRANSPORT]) {
|
||||
@ -354,11 +363,11 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
/* Accept Headers for DESCRIBE requests */
|
||||
if(rtspreq == RTSPREQ_DESCRIBE) {
|
||||
/* Accept Header */
|
||||
p_accept = Curl_checkheaders(conn, "Accept")?
|
||||
p_accept = Curl_checkheaders(data, "Accept")?
|
||||
NULL:"Accept: application/sdp\r\n";
|
||||
|
||||
/* Accept-Encoding header */
|
||||
if(!Curl_checkheaders(conn, "Accept-Encoding") &&
|
||||
if(!Curl_checkheaders(data, "Accept-Encoding") &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
Curl_safefree(data->state.aptr.accept_encoding);
|
||||
data->state.aptr.accept_encoding =
|
||||
@ -375,17 +384,17 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(Curl_checkheaders(conn, "User-Agent") && data->state.aptr.uagent) {
|
||||
if(Curl_checkheaders(data, "User-Agent") && data->state.aptr.uagent) {
|
||||
Curl_safefree(data->state.aptr.uagent);
|
||||
data->state.aptr.uagent = NULL;
|
||||
}
|
||||
else if(!Curl_checkheaders(conn, "User-Agent") &&
|
||||
else if(!Curl_checkheaders(data, "User-Agent") &&
|
||||
data->set.str[STRING_USERAGENT]) {
|
||||
p_uagent = data->state.aptr.uagent;
|
||||
}
|
||||
|
||||
/* setup the authentication headers */
|
||||
result = Curl_http_output_auth(conn, p_request, HTTPREQ_GET,
|
||||
result = Curl_http_output_auth(data, conn, p_request, HTTPREQ_GET,
|
||||
p_stream_uri, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
@ -395,7 +404,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
|
||||
/* Referrer */
|
||||
Curl_safefree(data->state.aptr.ref);
|
||||
if(data->change.referer && !Curl_checkheaders(conn, "Referer"))
|
||||
if(data->change.referer && !Curl_checkheaders(data, "Referer"))
|
||||
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
|
||||
else
|
||||
data->state.aptr.ref = NULL;
|
||||
@ -412,7 +421,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
(rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) {
|
||||
|
||||
/* Check to see if there is a range set in the custom headers */
|
||||
if(!Curl_checkheaders(conn, "Range") && data->state.range) {
|
||||
if(!Curl_checkheaders(data, "Range") && data->state.range) {
|
||||
Curl_safefree(data->state.aptr.rangeline);
|
||||
data->state.aptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
|
||||
p_range = data->state.aptr.rangeline;
|
||||
@ -422,11 +431,11 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
/*
|
||||
* Sanity check the custom headers
|
||||
*/
|
||||
if(Curl_checkheaders(conn, "CSeq")) {
|
||||
if(Curl_checkheaders(data, "CSeq")) {
|
||||
failf(data, "CSeq cannot be set as a custom header.");
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
}
|
||||
if(Curl_checkheaders(conn, "Session")) {
|
||||
if(Curl_checkheaders(data, "Session")) {
|
||||
failf(data, "Session ID cannot be set as a custom header.");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
@ -485,12 +494,12 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
|
||||
if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
|
||||
result = Curl_add_timecondition(conn, &req_buffer);
|
||||
result = Curl_add_timecondition(data, &req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_add_custom_headers(conn, FALSE, &req_buffer);
|
||||
result = Curl_add_custom_headers(data, FALSE, &req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -513,7 +522,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
if(putsize > 0 || postsize > 0) {
|
||||
/* As stated in the http comments, it is probably not wise to
|
||||
* actually set a custom Content-Length in the headers */
|
||||
if(!Curl_checkheaders(conn, "Content-Length")) {
|
||||
if(!Curl_checkheaders(data, "Content-Length")) {
|
||||
result =
|
||||
Curl_dyn_addf(&req_buffer,
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
|
||||
@ -524,7 +533,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
|
||||
if(rtspreq == RTSPREQ_SET_PARAMETER ||
|
||||
rtspreq == RTSPREQ_GET_PARAMETER) {
|
||||
if(!Curl_checkheaders(conn, "Content-Type")) {
|
||||
if(!Curl_checkheaders(data, "Content-Type")) {
|
||||
result = Curl_dyn_addf(&req_buffer,
|
||||
"Content-Type: text/parameters\r\n");
|
||||
if(result)
|
||||
@ -533,7 +542,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
if(rtspreq == RTSPREQ_ANNOUNCE) {
|
||||
if(!Curl_checkheaders(conn, "Content-Type")) {
|
||||
if(!Curl_checkheaders(data, "Content-Type")) {
|
||||
result = Curl_dyn_addf(&req_buffer,
|
||||
"Content-Type: application/sdp\r\n");
|
||||
if(result)
|
||||
@ -565,7 +574,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
/* issue the request */
|
||||
result = Curl_buffer_send(&req_buffer, conn,
|
||||
result = Curl_buffer_send(&req_buffer, data,
|
||||
&data->info.request_size, 0, FIRSTSOCKET);
|
||||
if(result) {
|
||||
failf(data, "Failed sending RTSP request");
|
||||
|
65
lib/sendf.c
65
lib/sendf.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -293,7 +293,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
||||
* 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,
|
||||
CURLcode Curl_write(struct Curl_easy *data,
|
||||
curl_socket_t sockfd,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
@ -301,9 +301,14 @@ CURLcode Curl_write(struct connectdata *conn,
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
CURLcode result = CURLE_OK;
|
||||
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||
struct connectdata *conn;
|
||||
int num;
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
conn = data->conn;
|
||||
num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||
|
||||
bytes_written = conn->send[num](conn, num, mem, len, &result);
|
||||
bytes_written = conn->send[num](data, num, mem, len, &result);
|
||||
|
||||
*written = bytes_written;
|
||||
if(bytes_written >= 0)
|
||||
@ -326,11 +331,17 @@ CURLcode Curl_write(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t Curl_send_plain(struct connectdata *conn, int num,
|
||||
ssize_t Curl_send_plain(struct Curl_easy *data, int num,
|
||||
const void *mem, size_t len, CURLcode *code)
|
||||
{
|
||||
curl_socket_t sockfd = conn->sock[num];
|
||||
struct connectdata *conn;
|
||||
curl_socket_t sockfd;
|
||||
ssize_t bytes_written;
|
||||
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
conn = data->conn;
|
||||
sockfd = conn->sock[num];
|
||||
/* WinSock will destroy unread received data if send() is
|
||||
failed.
|
||||
To avoid lossage of received data, recv() must be
|
||||
@ -373,9 +384,9 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
|
||||
}
|
||||
else {
|
||||
char buffer[STRERROR_LEN];
|
||||
failf(conn->data, "Send failure: %s",
|
||||
failf(data, "Send failure: %s",
|
||||
Curl_strerror(err, buffer, sizeof(buffer)));
|
||||
conn->data->state.os_errno = err;
|
||||
data->state.os_errno = err;
|
||||
*code = CURLE_SEND_ERROR;
|
||||
}
|
||||
}
|
||||
@ -387,28 +398,31 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
|
||||
* server using plain sockets only. Otherwise meant to have the exact same
|
||||
* proto as Curl_write()
|
||||
*/
|
||||
CURLcode Curl_write_plain(struct connectdata *conn,
|
||||
CURLcode Curl_write_plain(struct Curl_easy *data,
|
||||
curl_socket_t sockfd,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
ssize_t *written)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||
|
||||
bytes_written = Curl_send_plain(conn, num, mem, len, &result);
|
||||
|
||||
*written = bytes_written;
|
||||
*written = Curl_send_plain(data, num, mem, len, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
|
||||
ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
|
||||
size_t len, CURLcode *code)
|
||||
{
|
||||
curl_socket_t sockfd = conn->sock[num];
|
||||
struct connectdata *conn;
|
||||
curl_socket_t sockfd;
|
||||
ssize_t nread;
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
conn = data->conn;
|
||||
sockfd = conn->sock[num];
|
||||
/* Check and return data that already received and storied in internal
|
||||
intermediate buffer */
|
||||
nread = get_pre_recved(conn, num, buf, len);
|
||||
@ -439,9 +453,9 @@ ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
|
||||
}
|
||||
else {
|
||||
char buffer[STRERROR_LEN];
|
||||
failf(conn->data, "Recv failure: %s",
|
||||
failf(data, "Recv failure: %s",
|
||||
Curl_strerror(err, buffer, sizeof(buffer)));
|
||||
conn->data->state.os_errno = err;
|
||||
data->state.os_errno = err;
|
||||
*code = CURLE_RECV_ERROR;
|
||||
}
|
||||
}
|
||||
@ -500,12 +514,12 @@ static CURLcode pausewrite(struct Curl_easy *data,
|
||||
* client write callback(s) and takes care of pause requests from the
|
||||
* callbacks.
|
||||
*/
|
||||
static CURLcode chop_write(struct connectdata *conn,
|
||||
static CURLcode chop_write(struct Curl_easy *data,
|
||||
int type,
|
||||
char *optr,
|
||||
size_t olen)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_write_callback writeheader = NULL;
|
||||
curl_write_callback writebody = NULL;
|
||||
char *ptr = optr;
|
||||
@ -595,13 +609,12 @@ static CURLcode chop_write(struct connectdata *conn,
|
||||
local character encoding. This is a problem and should be changed in
|
||||
the future to leave the original data alone.
|
||||
*/
|
||||
CURLcode Curl_client_write(struct connectdata *conn,
|
||||
CURLcode Curl_client_write(struct Curl_easy *data,
|
||||
int type,
|
||||
char *ptr,
|
||||
size_t len)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
struct connectdata *conn = data->conn;
|
||||
if(0 == len)
|
||||
len = strlen(ptr);
|
||||
|
||||
@ -623,7 +636,7 @@ CURLcode Curl_client_write(struct connectdata *conn,
|
||||
#endif /* CURL_DO_LINEEND_CONV */
|
||||
}
|
||||
|
||||
return chop_write(conn, type, ptr, len);
|
||||
return chop_write(data, type, ptr, len);
|
||||
}
|
||||
|
||||
CURLcode Curl_read_plain(curl_socket_t sockfd,
|
||||
@ -658,7 +671,7 @@ CURLcode Curl_read_plain(curl_socket_t sockfd,
|
||||
*
|
||||
* Returns a regular CURLcode value.
|
||||
*/
|
||||
CURLcode Curl_read(struct connectdata *conn, /* connection data */
|
||||
CURLcode Curl_read(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 */
|
||||
@ -668,7 +681,7 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
|
||||
ssize_t nread = 0;
|
||||
size_t bytesfromsocket = 0;
|
||||
char *buffertofill = NULL;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
|
||||
If it is the second socket, we set num to 1. Otherwise to 0. This lets
|
||||
@ -680,7 +693,7 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
|
||||
bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
|
||||
buffertofill = buf;
|
||||
|
||||
nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
|
||||
nread = conn->recv[num](data, num, buffertofill, bytesfromsocket, &result);
|
||||
if(nread < 0)
|
||||
return result;
|
||||
|
||||
|
15
lib/sendf.h
15
lib/sendf.h
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -49,7 +49,7 @@ void Curl_failf(struct Curl_easy *, const char *fmt, ...);
|
||||
#define CLIENTWRITE_HEADER (1<<1)
|
||||
#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
|
||||
|
||||
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
|
||||
CURLcode Curl_client_write(struct Curl_easy *data, int type, char *ptr,
|
||||
size_t len) WARN_UNUSED_RESULT;
|
||||
|
||||
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex);
|
||||
@ -60,23 +60,24 @@ CURLcode Curl_read_plain(curl_socket_t sockfd,
|
||||
size_t bytesfromsocket,
|
||||
ssize_t *n);
|
||||
|
||||
ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
|
||||
ssize_t Curl_recv_plain(struct Curl_easy *data, int num, char *buf,
|
||||
size_t len, CURLcode *code);
|
||||
ssize_t Curl_send_plain(struct connectdata *conn, int num,
|
||||
ssize_t Curl_send_plain(struct Curl_easy *data, int num,
|
||||
const void *mem, size_t len, CURLcode *code);
|
||||
|
||||
/* internal read-function, does plain socket, SSL and krb4 */
|
||||
CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd,
|
||||
CURLcode Curl_read(struct Curl_easy *data, 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,
|
||||
CURLcode Curl_write(struct Curl_easy *data,
|
||||
curl_socket_t sockfd,
|
||||
const void *mem, size_t len,
|
||||
ssize_t *written);
|
||||
|
||||
/* internal write-function, does plain sockets ONLY */
|
||||
CURLcode Curl_write_plain(struct connectdata *conn,
|
||||
CURLcode Curl_write_plain(struct Curl_easy *data,
|
||||
curl_socket_t sockfd,
|
||||
const void *mem, size_t len,
|
||||
ssize_t *written);
|
||||
|
244
lib/smb.c
244
lib/smb.c
@ -5,8 +5,8 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2016 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
|
||||
* Copyright (C) 2016-2020, 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
|
||||
@ -54,16 +54,20 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Local API functions */
|
||||
static CURLcode smb_setup_connection(struct connectdata *conn);
|
||||
static CURLcode smb_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
|
||||
static CURLcode smb_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode smb_request_state(struct connectdata *conn, bool *done);
|
||||
static CURLcode smb_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode smb_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static CURLcode smb_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode smb_connection_state(struct Curl_easy *data, bool *done);
|
||||
static CURLcode smb_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode smb_request_state(struct Curl_easy *data, bool *done);
|
||||
static CURLcode smb_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature);
|
||||
static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
|
||||
static int smb_getsock(struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode smb_parse_url_path(struct connectdata *conn);
|
||||
static CURLcode smb_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
static int smb_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
static CURLcode smb_parse_url_path(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* SMB handler interface
|
||||
@ -183,9 +187,9 @@ struct smb_request {
|
||||
CURLcode result;
|
||||
};
|
||||
|
||||
static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
|
||||
static void conn_state(struct Curl_easy *data, enum smb_conn_state newstate)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
struct smb_conn *smbc = &data->conn->proto.smbc;
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
/* For debug purposes */
|
||||
static const char * const names[] = {
|
||||
@ -198,17 +202,17 @@ static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
|
||||
};
|
||||
|
||||
if(smbc->state != newstate)
|
||||
infof(conn->data, "SMB conn %p state change from %s to %s\n",
|
||||
infof(data, "SMB conn %p state change from %s to %s\n",
|
||||
(void *)smbc, names[smbc->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
smbc->state = newstate;
|
||||
}
|
||||
|
||||
static void request_state(struct connectdata *conn,
|
||||
static void request_state(struct Curl_easy *data,
|
||||
enum smb_req_state newstate)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.p.smb;
|
||||
struct smb_request *req = data->req.p.smb;
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
/* For debug purposes */
|
||||
static const char * const names[] = {
|
||||
@ -224,7 +228,7 @@ static void request_state(struct connectdata *conn,
|
||||
};
|
||||
|
||||
if(req->state != newstate)
|
||||
infof(conn->data, "SMB request %p state change from %s to %s\n",
|
||||
infof(data, "SMB request %p state change from %s to %s\n",
|
||||
(void *)req, names[req->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
@ -233,21 +237,23 @@ static void request_state(struct connectdata *conn,
|
||||
|
||||
/* this should setup things in the connection, not in the easy
|
||||
handle */
|
||||
static CURLcode smb_setup_connection(struct connectdata *conn)
|
||||
static CURLcode smb_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct smb_request *req;
|
||||
|
||||
/* Initialize the request state */
|
||||
conn->data->req.p.smb = req = calloc(1, sizeof(struct smb_request));
|
||||
data->req.p.smb = req = calloc(1, sizeof(struct smb_request));
|
||||
if(!req)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Parse the URL path */
|
||||
return smb_parse_url_path(conn);
|
||||
return smb_parse_url_path(data, conn);
|
||||
}
|
||||
|
||||
static CURLcode smb_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode smb_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
char *slash;
|
||||
|
||||
@ -288,8 +294,9 @@ static CURLcode smb_connect(struct connectdata *conn, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
|
||||
static CURLcode smb_recv_message(struct Curl_easy *data, void **msg)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
char *buf = smbc->recv_buf;
|
||||
ssize_t bytes_read;
|
||||
@ -298,7 +305,7 @@ static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
|
||||
size_t len = MAX_MESSAGE_SIZE - smbc->got;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
|
||||
result = Curl_read(data, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -342,11 +349,12 @@ static void smb_pop_message(struct connectdata *conn)
|
||||
smbc->got = 0;
|
||||
}
|
||||
|
||||
static void smb_format_message(struct connectdata *conn, struct smb_header *h,
|
||||
static void smb_format_message(struct Curl_easy *data, struct smb_header *h,
|
||||
unsigned char cmd, size_t len)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
struct smb_request *req = conn->data->req.p.smb;
|
||||
struct smb_request *req = data->req.p.smb;
|
||||
unsigned int pid;
|
||||
|
||||
memset(h, 0, sizeof(*h));
|
||||
@ -363,14 +371,15 @@ static void smb_format_message(struct connectdata *conn, struct smb_header *h,
|
||||
h->pid = smb_swap16((unsigned short) pid);
|
||||
}
|
||||
|
||||
static CURLcode smb_send(struct connectdata *conn, ssize_t len,
|
||||
static CURLcode smb_send(struct Curl_easy *data, ssize_t len,
|
||||
size_t upload_size)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
ssize_t bytes_written;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_write(conn, FIRSTSOCKET, conn->data->state.ulbuf,
|
||||
result = Curl_write(data, FIRSTSOCKET, data->state.ulbuf,
|
||||
len, &bytes_written);
|
||||
if(result)
|
||||
return result;
|
||||
@ -385,8 +394,9 @@ static CURLcode smb_send(struct connectdata *conn, ssize_t len,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_flush(struct connectdata *conn)
|
||||
static CURLcode smb_flush(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
ssize_t bytes_written;
|
||||
ssize_t len = smbc->send_size - smbc->sent;
|
||||
@ -395,8 +405,8 @@ static CURLcode smb_flush(struct connectdata *conn)
|
||||
if(!smbc->send_size)
|
||||
return CURLE_OK;
|
||||
|
||||
result = Curl_write(conn, FIRSTSOCKET,
|
||||
conn->data->state.ulbuf + smbc->sent,
|
||||
result = Curl_write(data, FIRSTSOCKET,
|
||||
data->state.ulbuf + smbc->sent,
|
||||
len, &bytes_written);
|
||||
if(result)
|
||||
return result;
|
||||
@ -409,29 +419,30 @@ static CURLcode smb_flush(struct connectdata *conn)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
|
||||
static CURLcode smb_send_message(struct Curl_easy *data, unsigned char cmd,
|
||||
const void *msg, size_t msg_len)
|
||||
{
|
||||
CURLcode result = Curl_get_upload_buffer(conn->data);
|
||||
CURLcode result = Curl_get_upload_buffer(data);
|
||||
if(result)
|
||||
return result;
|
||||
smb_format_message(conn, (struct smb_header *)conn->data->state.ulbuf,
|
||||
smb_format_message(data, (struct smb_header *)data->state.ulbuf,
|
||||
cmd, msg_len);
|
||||
memcpy(conn->data->state.ulbuf + sizeof(struct smb_header),
|
||||
memcpy(data->state.ulbuf + sizeof(struct smb_header),
|
||||
msg, msg_len);
|
||||
|
||||
return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
|
||||
return smb_send(data, sizeof(struct smb_header) + msg_len, 0);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_negotiate(struct connectdata *conn)
|
||||
static CURLcode smb_send_negotiate(struct Curl_easy *data)
|
||||
{
|
||||
const char *msg = "\x00\x0c\x00\x02NT LM 0.12";
|
||||
|
||||
return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15);
|
||||
return smb_send_message(data, SMB_COM_NEGOTIATE, msg, 15);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_setup(struct connectdata *conn)
|
||||
static CURLcode smb_send_setup(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
struct smb_setup msg;
|
||||
char *p = msg.bytes;
|
||||
@ -446,10 +457,10 @@ static CURLcode smb_send_setup(struct connectdata *conn)
|
||||
if(byte_count > sizeof(msg.bytes))
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
|
||||
Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
|
||||
Curl_ntlm_core_mk_lm_hash(data, conn->passwd, lm_hash);
|
||||
Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
|
||||
#ifdef USE_NTRESPONSES
|
||||
Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
|
||||
Curl_ntlm_core_mk_nt_hash(data, conn->passwd, nt_hash);
|
||||
Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
|
||||
#else
|
||||
memset(nt, 0, sizeof(nt));
|
||||
@ -476,13 +487,14 @@ static CURLcode smb_send_setup(struct connectdata *conn)
|
||||
byte_count = p - msg.bytes;
|
||||
msg.byte_count = smb_swap16((unsigned short)byte_count);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg,
|
||||
return smb_send_message(data, SMB_COM_SETUP_ANDX, &msg,
|
||||
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_tree_connect(struct connectdata *conn)
|
||||
static CURLcode smb_send_tree_connect(struct Curl_easy *data)
|
||||
{
|
||||
struct smb_tree_connect msg;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
char *p = msg.bytes;
|
||||
|
||||
@ -503,13 +515,13 @@ static CURLcode smb_send_tree_connect(struct connectdata *conn)
|
||||
byte_count = p - msg.bytes;
|
||||
msg.byte_count = smb_swap16((unsigned short)byte_count);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg,
|
||||
return smb_send_message(data, SMB_COM_TREE_CONNECT_ANDX, &msg,
|
||||
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_open(struct connectdata *conn)
|
||||
static CURLcode smb_send_open(struct Curl_easy *data)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.p.smb;
|
||||
struct smb_request *req = data->req.p.smb;
|
||||
struct smb_nt_create msg;
|
||||
size_t byte_count;
|
||||
|
||||
@ -522,7 +534,7 @@ static CURLcode smb_send_open(struct connectdata *conn)
|
||||
byte_count = strlen(req->path);
|
||||
msg.name_length = smb_swap16((unsigned short)byte_count);
|
||||
msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
|
||||
if(conn->data->set.upload) {
|
||||
if(data->set.upload) {
|
||||
msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
|
||||
msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
|
||||
}
|
||||
@ -533,35 +545,35 @@ static CURLcode smb_send_open(struct connectdata *conn)
|
||||
msg.byte_count = smb_swap16((unsigned short) ++byte_count);
|
||||
strcpy(msg.bytes, req->path);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg,
|
||||
return smb_send_message(data, SMB_COM_NT_CREATE_ANDX, &msg,
|
||||
sizeof(msg) - sizeof(msg.bytes) + byte_count);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_close(struct connectdata *conn)
|
||||
static CURLcode smb_send_close(struct Curl_easy *data)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.p.smb;
|
||||
struct smb_request *req = data->req.p.smb;
|
||||
struct smb_close msg;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.word_count = SMB_WC_CLOSE;
|
||||
msg.fid = smb_swap16(req->fid);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg));
|
||||
return smb_send_message(data, SMB_COM_CLOSE, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
|
||||
static CURLcode smb_send_tree_disconnect(struct Curl_easy *data)
|
||||
{
|
||||
struct smb_tree_disconnect msg;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
|
||||
return smb_send_message(data, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
static CURLcode smb_send_read(struct connectdata *conn)
|
||||
static CURLcode smb_send_read(struct Curl_easy *data)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.p.smb;
|
||||
curl_off_t offset = conn->data->req.offset;
|
||||
struct smb_request *req = data->req.p.smb;
|
||||
curl_off_t offset = data->req.offset;
|
||||
struct smb_read msg;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
@ -573,19 +585,19 @@ static CURLcode smb_send_read(struct connectdata *conn)
|
||||
msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
|
||||
msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
|
||||
|
||||
return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg));
|
||||
return smb_send_message(data, SMB_COM_READ_ANDX, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
static CURLcode smb_send_write(struct connectdata *conn)
|
||||
static CURLcode smb_send_write(struct Curl_easy *data)
|
||||
{
|
||||
struct smb_write *msg;
|
||||
struct smb_request *req = conn->data->req.p.smb;
|
||||
curl_off_t offset = conn->data->req.offset;
|
||||
curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
|
||||
CURLcode result = Curl_get_upload_buffer(conn->data);
|
||||
struct smb_request *req = data->req.p.smb;
|
||||
curl_off_t offset = data->req.offset;
|
||||
curl_off_t upload_size = data->req.size - data->req.bytecount;
|
||||
CURLcode result = Curl_get_upload_buffer(data);
|
||||
if(result)
|
||||
return result;
|
||||
msg = (struct smb_write *)conn->data->state.ulbuf;
|
||||
msg = (struct smb_write *)data->state.ulbuf;
|
||||
|
||||
if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
|
||||
upload_size = MAX_PAYLOAD_SIZE - 1;
|
||||
@ -600,24 +612,25 @@ static CURLcode smb_send_write(struct connectdata *conn)
|
||||
msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
|
||||
msg->byte_count = smb_swap16((unsigned short) (upload_size + 1));
|
||||
|
||||
smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
|
||||
smb_format_message(data, &msg->h, SMB_COM_WRITE_ANDX,
|
||||
sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
|
||||
|
||||
return smb_send(conn, sizeof(*msg), (size_t) upload_size);
|
||||
return smb_send(data, sizeof(*msg), (size_t) upload_size);
|
||||
}
|
||||
|
||||
static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
|
||||
static CURLcode smb_send_and_recv(struct Curl_easy *data, void **msg)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
CURLcode result;
|
||||
*msg = NULL; /* if it returns early */
|
||||
|
||||
/* Check if there is data in the transfer buffer */
|
||||
if(!smbc->send_size && smbc->upload_size) {
|
||||
size_t nread = smbc->upload_size > conn->data->set.upload_buffer_size ?
|
||||
conn->data->set.upload_buffer_size :
|
||||
size_t nread = smbc->upload_size > data->set.upload_buffer_size ?
|
||||
data->set.upload_buffer_size :
|
||||
smbc->upload_size;
|
||||
conn->data->req.upload_fromhere = conn->data->state.ulbuf;
|
||||
data->req.upload_fromhere = data->state.ulbuf;
|
||||
result = Curl_fillreadbuffer(conn, nread, &nread);
|
||||
if(result && result != CURLE_AGAIN)
|
||||
return result;
|
||||
@ -631,7 +644,7 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
|
||||
|
||||
/* Check if there is data to send */
|
||||
if(smbc->send_size) {
|
||||
result = smb_flush(conn);
|
||||
result = smb_flush(data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -640,11 +653,12 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
|
||||
if(smbc->send_size || smbc->upload_size)
|
||||
return CURLE_AGAIN;
|
||||
|
||||
return smb_recv_message(conn, msg);
|
||||
return smb_recv_message(data, msg);
|
||||
}
|
||||
|
||||
static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
|
||||
static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
struct smb_negotiate_response *nrsp;
|
||||
struct smb_header *h;
|
||||
@ -663,17 +677,17 @@ static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
|
||||
}
|
||||
#endif
|
||||
|
||||
result = smb_send_negotiate(conn);
|
||||
result = smb_send_negotiate(data);
|
||||
if(result) {
|
||||
connclose(conn, "SMB: failed to send negotiate message");
|
||||
return result;
|
||||
}
|
||||
|
||||
conn_state(conn, SMB_NEGOTIATE);
|
||||
conn_state(data, SMB_NEGOTIATE);
|
||||
}
|
||||
|
||||
/* Send the previous message and check for a response */
|
||||
result = smb_send_and_recv(conn, &msg);
|
||||
result = smb_send_and_recv(data, &msg);
|
||||
if(result && result != CURLE_AGAIN) {
|
||||
connclose(conn, "SMB: failed to communicate");
|
||||
return result;
|
||||
@ -694,12 +708,12 @@ static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
|
||||
nrsp = msg;
|
||||
memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
|
||||
smbc->session_key = smb_swap32(nrsp->session_key);
|
||||
result = smb_send_setup(conn);
|
||||
result = smb_send_setup(data);
|
||||
if(result) {
|
||||
connclose(conn, "SMB: failed to send setup message");
|
||||
return result;
|
||||
}
|
||||
conn_state(conn, SMB_SETUP);
|
||||
conn_state(data, SMB_SETUP);
|
||||
break;
|
||||
|
||||
case SMB_SETUP:
|
||||
@ -708,7 +722,7 @@ static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
smbc->uid = smb_swap16(h->uid);
|
||||
conn_state(conn, SMB_CONNECTED);
|
||||
conn_state(data, SMB_CONNECTED);
|
||||
*done = true;
|
||||
break;
|
||||
|
||||
@ -740,9 +754,10 @@ static void get_posix_time(time_t *out, curl_off_t timestamp)
|
||||
*out = (time_t) timestamp;
|
||||
}
|
||||
|
||||
static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.p.smb;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_request *req = data->req.p.smb;
|
||||
struct smb_header *h;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
enum smb_req_state next_state = SMB_DONE;
|
||||
@ -754,17 +769,17 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
|
||||
/* Start the request */
|
||||
if(req->state == SMB_REQUESTING) {
|
||||
result = smb_send_tree_connect(conn);
|
||||
result = smb_send_tree_connect(data);
|
||||
if(result) {
|
||||
connclose(conn, "SMB: failed to send tree connect message");
|
||||
return result;
|
||||
}
|
||||
|
||||
request_state(conn, SMB_TREE_CONNECT);
|
||||
request_state(data, SMB_TREE_CONNECT);
|
||||
}
|
||||
|
||||
/* Send the previous message and check for a response */
|
||||
result = smb_send_and_recv(conn, &msg);
|
||||
result = smb_send_and_recv(data, &msg);
|
||||
if(result && result != CURLE_AGAIN) {
|
||||
connclose(conn, "SMB: failed to communicate");
|
||||
return result;
|
||||
@ -797,23 +812,23 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
}
|
||||
smb_m = (const struct smb_nt_create_response*) msg;
|
||||
req->fid = smb_swap16(smb_m->fid);
|
||||
conn->data->req.offset = 0;
|
||||
if(conn->data->set.upload) {
|
||||
conn->data->req.size = conn->data->state.infilesize;
|
||||
Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
|
||||
data->req.offset = 0;
|
||||
if(data->set.upload) {
|
||||
data->req.size = data->state.infilesize;
|
||||
Curl_pgrsSetUploadSize(data, data->req.size);
|
||||
next_state = SMB_UPLOAD;
|
||||
}
|
||||
else {
|
||||
smb_m = (const struct smb_nt_create_response*) msg;
|
||||
conn->data->req.size = smb_swap64(smb_m->end_of_file);
|
||||
if(conn->data->req.size < 0) {
|
||||
data->req.size = smb_swap64(smb_m->end_of_file);
|
||||
if(data->req.size < 0) {
|
||||
req->result = CURLE_WEIRD_SERVER_REPLY;
|
||||
next_state = SMB_CLOSE;
|
||||
}
|
||||
else {
|
||||
Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size);
|
||||
if(conn->data->set.get_filetime)
|
||||
get_posix_time(&conn->data->info.filetime, smb_m->last_change_time);
|
||||
Curl_pgrsSetDownloadSize(data, data->req.size);
|
||||
if(data->set.get_filetime)
|
||||
get_posix_time(&data->info.filetime, smb_m->last_change_time);
|
||||
next_state = SMB_DOWNLOAD;
|
||||
}
|
||||
}
|
||||
@ -831,11 +846,11 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
sizeof(struct smb_header) + 13);
|
||||
if(len > 0) {
|
||||
if(off + sizeof(unsigned int) + len > smbc->got) {
|
||||
failf(conn->data, "Invalid input packet");
|
||||
failf(data, "Invalid input packet");
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
else
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
(char *)msg + off + sizeof(unsigned int),
|
||||
len);
|
||||
if(result) {
|
||||
@ -844,9 +859,9 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
break;
|
||||
}
|
||||
}
|
||||
conn->data->req.bytecount += len;
|
||||
conn->data->req.offset += len;
|
||||
Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount);
|
||||
data->req.bytecount += len;
|
||||
data->req.offset += len;
|
||||
Curl_pgrsSetDownloadCounter(data, data->req.bytecount);
|
||||
next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
|
||||
break;
|
||||
|
||||
@ -858,10 +873,10 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
}
|
||||
len = Curl_read16_le(((const unsigned char *) msg) +
|
||||
sizeof(struct smb_header) + 5);
|
||||
conn->data->req.bytecount += len;
|
||||
conn->data->req.offset += len;
|
||||
Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount);
|
||||
if(conn->data->req.bytecount >= conn->data->req.size)
|
||||
data->req.bytecount += len;
|
||||
data->req.offset += len;
|
||||
Curl_pgrsSetUploadCounter(data, data->req.bytecount);
|
||||
if(data->req.bytecount >= data->req.size)
|
||||
next_state = SMB_CLOSE;
|
||||
else
|
||||
next_state = SMB_UPLOAD;
|
||||
@ -885,23 +900,23 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
|
||||
switch(next_state) {
|
||||
case SMB_OPEN:
|
||||
result = smb_send_open(conn);
|
||||
result = smb_send_open(data);
|
||||
break;
|
||||
|
||||
case SMB_DOWNLOAD:
|
||||
result = smb_send_read(conn);
|
||||
result = smb_send_read(data);
|
||||
break;
|
||||
|
||||
case SMB_UPLOAD:
|
||||
result = smb_send_write(conn);
|
||||
result = smb_send_write(data);
|
||||
break;
|
||||
|
||||
case SMB_CLOSE:
|
||||
result = smb_send_close(conn);
|
||||
result = smb_send_close(data);
|
||||
break;
|
||||
|
||||
case SMB_TREE_DISCONNECT:
|
||||
result = smb_send_tree_disconnect(conn);
|
||||
result = smb_send_tree_disconnect(data);
|
||||
break;
|
||||
|
||||
case SMB_DONE:
|
||||
@ -918,37 +933,42 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
request_state(conn, next_state);
|
||||
request_state(data, next_state);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode smb_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode smb_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
(void) premature;
|
||||
Curl_safefree(conn->data->req.p.smb);
|
||||
Curl_safefree(data->req.p.smb);
|
||||
return status;
|
||||
}
|
||||
|
||||
static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
|
||||
static CURLcode smb_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead)
|
||||
{
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
(void) dead;
|
||||
(void) data;
|
||||
Curl_safefree(smbc->share);
|
||||
Curl_safefree(smbc->domain);
|
||||
Curl_safefree(smbc->recv_buf);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int smb_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
static int smb_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
{
|
||||
(void)data;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
static CURLcode smb_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode smb_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
|
||||
*done = FALSE;
|
||||
@ -958,9 +978,9 @@ static CURLcode smb_do(struct connectdata *conn, bool *done)
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
static CURLcode smb_parse_url_path(struct connectdata *conn)
|
||||
static CURLcode smb_parse_url_path(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct smb_request *req = data->req.p.smb;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
char *path;
|
||||
|
365
lib/smtp.c
365
lib/smtp.c
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2009 - 2021, 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
|
||||
@ -91,6 +91,6 @@ extern const struct Curl_handler Curl_handler_smtps;
|
||||
#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
|
||||
#define SMTP_EOB_REPL_LEN 4
|
||||
|
||||
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread);
|
||||
CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread);
|
||||
|
||||
#endif /* HEADER_CURL_SMTP_H */
|
||||
|
12
lib/socks.c
12
lib/socks.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -357,7 +357,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
||||
/* FALLTHROUGH */
|
||||
case CONNECT_REQ_SENDING:
|
||||
/* Send request */
|
||||
result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
|
||||
result = Curl_write_plain(data, sockfd, (char *)sx->outp,
|
||||
sx->outstanding, &written);
|
||||
if(result && (CURLE_AGAIN != result)) {
|
||||
failf(data, "Failed to send SOCKS4 connect request.");
|
||||
@ -561,7 +561,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
/* write the number of authentication methods */
|
||||
socksreq[1] = (unsigned char) (idx - 2);
|
||||
|
||||
result = Curl_write_plain(conn, sockfd, (char *)socksreq, idx, &written);
|
||||
result = Curl_write_plain(data, sockfd, (char *)socksreq, idx, &written);
|
||||
if(result && (CURLE_AGAIN != result)) {
|
||||
failf(data, "Unable to send initial SOCKS5 request.");
|
||||
return CURLPX_SEND_CONNECT;
|
||||
@ -575,7 +575,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
sxstate(conn, CONNECT_SOCKS_READ);
|
||||
goto CONNECT_SOCKS_READ_INIT;
|
||||
case CONNECT_SOCKS_SEND:
|
||||
result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
|
||||
result = Curl_write_plain(data, sockfd, (char *)sx->outp,
|
||||
sx->outstanding, &written);
|
||||
if(result && (CURLE_AGAIN != result)) {
|
||||
failf(data, "Unable to send initial SOCKS5 request.");
|
||||
@ -707,7 +707,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case CONNECT_AUTH_SEND:
|
||||
result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
|
||||
result = Curl_write_plain(data, sockfd, (char *)sx->outp,
|
||||
sx->outstanding, &written);
|
||||
if(result && (CURLE_AGAIN != result)) {
|
||||
failf(data, "Failed to send SOCKS5 sub-negotiation request.");
|
||||
@ -881,7 +881,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
||||
sxstate(conn, CONNECT_REQ_SENDING);
|
||||
/* FALLTHROUGH */
|
||||
case CONNECT_REQ_SENDING:
|
||||
result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
|
||||
result = Curl_write_plain(data, sockfd, (char *)sx->outp,
|
||||
sx->outstanding, &written);
|
||||
if(result && (CURLE_AGAIN != result)) {
|
||||
failf(data, "Failed to send SOCKS5 connect request.");
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@ -201,7 +201,7 @@ 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(conn, sock, (char *)socksreq, 4, &written);
|
||||
code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
|
||||
if(code || (4 != written)) {
|
||||
failf(data, "Failed to send GSS-API authentication request.");
|
||||
gss_release_name(&gss_status, &server);
|
||||
@ -211,7 +211,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)gss_send_token.value,
|
||||
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)) {
|
||||
@ -408,7 +408,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
memcpy(socksreq + 2, &us_length, sizeof(short));
|
||||
}
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
|
||||
code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
|
||||
if(code || (4 != written)) {
|
||||
failf(data, "Failed to send GSS-API encryption request.");
|
||||
gss_release_buffer(&gss_status, &gss_w_token);
|
||||
@ -418,7 +418,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
|
||||
if(data->set.socks5_gssapi_nec) {
|
||||
memcpy(socksreq, &gss_enc, 1);
|
||||
code = Curl_write_plain(conn, sock, socksreq, 1, &written);
|
||||
code = Curl_write_plain(data, sock, socksreq, 1, &written);
|
||||
if(code || ( 1 != written)) {
|
||||
failf(data, "Failed to send GSS-API encryption type.");
|
||||
gss_delete_sec_context(&gss_status, &gss_context, NULL);
|
||||
@ -426,7 +426,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = Curl_write_plain(conn, sock, (char *)gss_w_token.value,
|
||||
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)) {
|
||||
failf(data, "Failed to send GSS-API encryption type.");
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@ -204,7 +204,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
us_length = htons((short)sspi_send_token.cbBuffer);
|
||||
memcpy(socksreq + 2, &us_length, sizeof(short));
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
|
||||
code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
|
||||
if(code || (4 != written)) {
|
||||
failf(data, "Failed to send SSPI authentication request.");
|
||||
free(service_name);
|
||||
@ -217,7 +217,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
|
||||
code = Curl_write_plain(data, sock, (char *)sspi_send_token.pvBuffer,
|
||||
sspi_send_token.cbBuffer, &written);
|
||||
if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
|
||||
failf(data, "Failed to send SSPI authentication token.");
|
||||
@ -466,7 +466,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
memcpy(socksreq + 2, &us_length, sizeof(short));
|
||||
}
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
|
||||
code = Curl_write_plain(data, sock, (char *)socksreq, 4, &written);
|
||||
if(code || (4 != written)) {
|
||||
failf(data, "Failed to send SSPI encryption request.");
|
||||
if(sspi_send_token.pvBuffer)
|
||||
@ -477,7 +477,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
|
||||
if(data->set.socks5_gssapi_nec) {
|
||||
memcpy(socksreq, &gss_enc, 1);
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
|
||||
code = Curl_write_plain(data, sock, (char *)socksreq, 1, &written);
|
||||
if(code || (1 != written)) {
|
||||
failf(data, "Failed to send SSPI encryption type.");
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
@ -485,7 +485,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
|
||||
code = Curl_write_plain(data, sock, (char *)sspi_send_token.pvBuffer,
|
||||
sspi_send_token.cbBuffer, &written);
|
||||
if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
|
||||
failf(data, "Failed to send SSPI encryption type.");
|
||||
|
34
lib/telnet.c
34
lib/telnet.c
@ -111,10 +111,10 @@ static void printsub(struct Curl_easy *data,
|
||||
static void suboption(struct connectdata *);
|
||||
static void sendsuboption(struct connectdata *conn, int option);
|
||||
|
||||
static CURLcode telnet_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode telnet_done(struct connectdata *conn,
|
||||
static CURLcode telnet_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode telnet_done(struct Curl_easy *data,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode send_telnet_data(struct connectdata *conn,
|
||||
static CURLcode send_telnet_data(struct Curl_easy *data,
|
||||
char *buffer, ssize_t nread);
|
||||
|
||||
/* For negotiation compliant to RFC 1143 */
|
||||
@ -995,7 +995,7 @@ static void sendsuboption(struct connectdata *conn, int option)
|
||||
}
|
||||
/* ... then the window size with the send_telnet_data() function
|
||||
to deal with 0xFF cases ... */
|
||||
send_telnet_data(conn, (char *)tn->subbuffer + 3, 4);
|
||||
send_telnet_data(data, (char *)tn->subbuffer + 3, 4);
|
||||
/* ... and the footer */
|
||||
bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer + 7, 2);
|
||||
if(bytes_written < 0) {
|
||||
@ -1021,7 +1021,7 @@ CURLcode telrcv(struct connectdata *conn,
|
||||
|
||||
#define startskipping() \
|
||||
if(startwrite >= 0) { \
|
||||
result = Curl_client_write(conn, \
|
||||
result = Curl_client_write(data, \
|
||||
CLIENTWRITE_BODY, \
|
||||
(char *)&inbuf[startwrite], \
|
||||
in-startwrite); \
|
||||
@ -1171,13 +1171,14 @@ CURLcode telrcv(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Escape and send a telnet data block */
|
||||
static CURLcode send_telnet_data(struct connectdata *conn,
|
||||
static CURLcode send_telnet_data(struct Curl_easy *data,
|
||||
char *buffer, ssize_t nread)
|
||||
{
|
||||
ssize_t escapes, i, outlen;
|
||||
unsigned char *outbuf = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
ssize_t bytes_written, total_written;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
/* Determine size of new buffer after escaping */
|
||||
escapes = 0;
|
||||
@ -1216,7 +1217,7 @@ static CURLcode send_telnet_data(struct connectdata *conn,
|
||||
break;
|
||||
default: /* write! */
|
||||
bytes_written = 0;
|
||||
result = Curl_write(conn, conn->sock[FIRSTSOCKET],
|
||||
result = Curl_write(data, conn->sock[FIRSTSOCKET],
|
||||
outbuf + total_written,
|
||||
outlen - total_written,
|
||||
&bytes_written);
|
||||
@ -1232,9 +1233,10 @@ static CURLcode send_telnet_data(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode telnet_done(struct connectdata *conn,
|
||||
CURLcode status, bool premature)
|
||||
static CURLcode telnet_done(struct Curl_easy *data,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
|
||||
(void)status; /* unused */
|
||||
(void)premature; /* not used */
|
||||
@ -1250,10 +1252,10 @@ static CURLcode telnet_done(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode telnet_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
#ifdef USE_WINSOCK
|
||||
WSAEVENT event_handle;
|
||||
@ -1378,7 +1380,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
}
|
||||
|
||||
result = send_telnet_data(conn, buf, readfile_read);
|
||||
result = send_telnet_data(data, buf, readfile_read);
|
||||
if(result) {
|
||||
keepon = FALSE;
|
||||
break;
|
||||
@ -1396,7 +1398,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
break;
|
||||
}
|
||||
|
||||
result = send_telnet_data(conn, buf, readfile_read);
|
||||
result = send_telnet_data(data, buf, readfile_read);
|
||||
if(result) {
|
||||
keepon = FALSE;
|
||||
break;
|
||||
@ -1418,7 +1420,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
if(events.lNetworkEvents & FD_READ) {
|
||||
/* read data from network */
|
||||
result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread);
|
||||
result = Curl_read(data, sockfd, buf, data->set.buffer_size, &nread);
|
||||
/* read would've blocked. Loop again */
|
||||
if(result == CURLE_AGAIN)
|
||||
break;
|
||||
@ -1498,7 +1500,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
default: /* read! */
|
||||
if(pfd[0].revents & POLLIN) {
|
||||
/* read data from network */
|
||||
result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread);
|
||||
result = Curl_read(data, sockfd, buf, data->set.buffer_size, &nread);
|
||||
/* read would've blocked. Loop again */
|
||||
if(result == CURLE_AGAIN)
|
||||
break;
|
||||
@ -1550,7 +1552,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
if(nread > 0) {
|
||||
result = send_telnet_data(conn, buf, nread);
|
||||
result = send_telnet_data(data, buf, nread);
|
||||
if(result) {
|
||||
keepon = FALSE;
|
||||
break;
|
||||
|
136
lib/tftp.c
136
lib/tftp.c
@ -124,7 +124,7 @@ struct tftp_state_data {
|
||||
tftp_mode_t mode;
|
||||
tftp_error_t error;
|
||||
tftp_event_t event;
|
||||
struct connectdata *conn;
|
||||
struct Curl_easy *data;
|
||||
curl_socket_t sockfd;
|
||||
int retries;
|
||||
int retry_time;
|
||||
@ -148,16 +148,19 @@ struct tftp_state_data {
|
||||
/* Forward declarations */
|
||||
static CURLcode tftp_rx(struct tftp_state_data *state, tftp_event_t event);
|
||||
static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event);
|
||||
static CURLcode tftp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode tftp_disconnect(struct connectdata *conn,
|
||||
static CURLcode tftp_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode tftp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection);
|
||||
static CURLcode tftp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode tftp_done(struct connectdata *conn,
|
||||
static CURLcode tftp_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode tftp_done(struct Curl_easy *data,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode tftp_setup_connection(struct connectdata *conn);
|
||||
static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
|
||||
static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
|
||||
static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks);
|
||||
static CURLcode tftp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static int tftp_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
static CURLcode tftp_translate_code(tftp_error_t error);
|
||||
|
||||
|
||||
@ -206,11 +209,11 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
|
||||
time(&state->start_time);
|
||||
|
||||
/* Compute drop-dead time */
|
||||
timeout_ms = Curl_timeleft(state->conn->data, NULL, start);
|
||||
timeout_ms = Curl_timeleft(state->data, NULL, start);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
failf(state->conn->data, "Connection time-out");
|
||||
failf(state->data, "Connection time-out");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
@ -261,7 +264,7 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
|
||||
if(state->retry_time<1)
|
||||
state->retry_time = 1;
|
||||
|
||||
infof(state->conn->data,
|
||||
infof(state->data,
|
||||
"set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
|
||||
(int)state->state, (long)(state->max_time-state->start_time),
|
||||
state->retry_time, state->retry_max);
|
||||
@ -335,7 +338,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
|
||||
const char *ptr, int len)
|
||||
{
|
||||
const char *tmp = ptr;
|
||||
struct Curl_easy *data = state->conn->data;
|
||||
struct Curl_easy *data = state->data;
|
||||
|
||||
/* if OACK doesn't contain blksize option, the default (512) must be used */
|
||||
state->blksize = TFTP_BLKSIZE_DEFAULT;
|
||||
@ -419,7 +422,7 @@ static CURLcode tftp_connect_for_tx(struct tftp_state_data *state,
|
||||
{
|
||||
CURLcode result;
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
struct Curl_easy *data = state->conn->data;
|
||||
struct Curl_easy *data = state->data;
|
||||
|
||||
infof(data, "%s\n", "Connected for transmit");
|
||||
#endif
|
||||
@ -435,7 +438,7 @@ static CURLcode tftp_connect_for_rx(struct tftp_state_data *state,
|
||||
{
|
||||
CURLcode result;
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
struct Curl_easy *data = state->conn->data;
|
||||
struct Curl_easy *data = state->data;
|
||||
|
||||
infof(data, "%s\n", "Connected for receive");
|
||||
#endif
|
||||
@ -453,7 +456,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||
ssize_t senddata;
|
||||
const char *mode = "octet";
|
||||
char *filename;
|
||||
struct Curl_easy *data = state->conn->data;
|
||||
struct Curl_easy *data = state->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
/* Set ascii mode if -B flag was used */
|
||||
@ -475,7 +478,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||
if(data->set.upload) {
|
||||
/* If we are uploading, send an WRQ */
|
||||
setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
|
||||
state->conn->data->req.upload_fromhere =
|
||||
state->data->req.upload_fromhere =
|
||||
(char *)state->spacket.data + 4;
|
||||
if(data->state.infilesize != -1)
|
||||
Curl_pgrsSetUploadSize(data, data->state.infilesize);
|
||||
@ -487,7 +490,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||
/* As RFC3617 describes the separator slash is not actually part of the
|
||||
file name so we skip the always-present first letter of the path
|
||||
string. */
|
||||
result = Curl_urldecode(data, &state->conn->data->state.up.path[1], 0,
|
||||
result = Curl_urldecode(data, &state->data->state.up.path[1], 0,
|
||||
&filename, NULL, REJECT_ZERO);
|
||||
if(result)
|
||||
return result;
|
||||
@ -551,8 +554,8 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||
not have a size_t argument, like older unixes that want an 'int' */
|
||||
senddata = sendto(state->sockfd, (void *)state->spacket.data,
|
||||
(SEND_TYPE_ARG3)sbytes, 0,
|
||||
state->conn->ip_addr->ai_addr,
|
||||
state->conn->ip_addr->ai_addrlen);
|
||||
data->conn->ip_addr->ai_addr,
|
||||
data->conn->ip_addr->ai_addrlen);
|
||||
if(senddata != (ssize_t)sbytes) {
|
||||
char buffer[STRERROR_LEN];
|
||||
failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
@ -582,7 +585,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||
break;
|
||||
|
||||
default:
|
||||
failf(state->conn->data, "tftp_send_first: internal error");
|
||||
failf(state->data, "tftp_send_first: internal error");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -605,7 +608,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state,
|
||||
{
|
||||
ssize_t sbytes;
|
||||
int rblock;
|
||||
struct Curl_easy *data = state->conn->data;
|
||||
struct Curl_easy *data = state->data;
|
||||
char buffer[STRERROR_LEN];
|
||||
|
||||
switch(event) {
|
||||
@ -725,7 +728,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state,
|
||||
**********************************************************/
|
||||
static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
|
||||
{
|
||||
struct Curl_easy *data = state->conn->data;
|
||||
struct Curl_easy *data = state->data;
|
||||
ssize_t sbytes;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SingleRequest *k = &data->req;
|
||||
@ -794,14 +797,14 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
|
||||
* data block.
|
||||
* */
|
||||
state->sbytes = 0;
|
||||
state->conn->data->req.upload_fromhere = (char *)state->spacket.data + 4;
|
||||
state->data->req.upload_fromhere = (char *)state->spacket.data + 4;
|
||||
do {
|
||||
result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes,
|
||||
result = Curl_fillreadbuffer(data->conn, state->blksize - state->sbytes,
|
||||
&cb);
|
||||
if(result)
|
||||
return result;
|
||||
state->sbytes += (int)cb;
|
||||
state->conn->data->req.upload_fromhere += cb;
|
||||
state->data->req.upload_fromhere += cb;
|
||||
} while(state->sbytes < state->blksize && cb != 0);
|
||||
|
||||
sbytes = sendto(state->sockfd, (void *) state->spacket.data,
|
||||
@ -927,7 +930,7 @@ static CURLcode tftp_state_machine(struct tftp_state_data *state,
|
||||
tftp_event_t event)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = state->conn->data;
|
||||
struct Curl_easy *data = state->data;
|
||||
|
||||
switch(state->state) {
|
||||
case TFTP_STATE_START:
|
||||
@ -962,9 +965,11 @@ static CURLcode tftp_state_machine(struct tftp_state_data *state,
|
||||
* The disconnect callback
|
||||
*
|
||||
**********************************************************/
|
||||
static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
static CURLcode tftp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead_connection)
|
||||
{
|
||||
struct tftp_state_data *state = conn->proto.tftpc;
|
||||
(void) data;
|
||||
(void) dead_connection;
|
||||
|
||||
/* done, free dynamically allocated pkt buffers */
|
||||
@ -984,11 +989,12 @@ static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
* The connect callback
|
||||
*
|
||||
**********************************************************/
|
||||
static CURLcode tftp_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode tftp_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct tftp_state_data *state;
|
||||
int blksize;
|
||||
int need_blksize;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
blksize = TFTP_BLKSIZE_DEFAULT;
|
||||
|
||||
@ -997,8 +1003,8 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* alloc pkt buffers based on specified blksize */
|
||||
if(conn->data->set.tftp_blksize) {
|
||||
blksize = (int)conn->data->set.tftp_blksize;
|
||||
if(data->set.tftp_blksize) {
|
||||
blksize = (int)data->set.tftp_blksize;
|
||||
if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN)
|
||||
return CURLE_TFTP_ILLEGAL;
|
||||
}
|
||||
@ -1026,8 +1032,8 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
|
||||
* little gain for UDP */
|
||||
connclose(conn, "TFTP");
|
||||
|
||||
state->conn = conn;
|
||||
state->sockfd = state->conn->sock[FIRSTSOCKET];
|
||||
state->data = data;
|
||||
state->sockfd = conn->sock[FIRSTSOCKET];
|
||||
state->state = TFTP_STATE_START;
|
||||
state->error = TFTP_ERR_NONE;
|
||||
state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
|
||||
@ -1056,14 +1062,14 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
|
||||
conn->ip_addr->ai_addrlen);
|
||||
if(rc) {
|
||||
char buffer[STRERROR_LEN];
|
||||
failf(conn->data, "bind() failed; %s",
|
||||
failf(data, "bind() failed; %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
conn->bits.bound = TRUE;
|
||||
}
|
||||
|
||||
Curl_pgrsStartNow(conn->data);
|
||||
Curl_pgrsStartNow(data);
|
||||
|
||||
*done = TRUE;
|
||||
|
||||
@ -1077,10 +1083,11 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
|
||||
* The done callback
|
||||
*
|
||||
**********************************************************/
|
||||
static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode tftp_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct tftp_state_data *state = conn->proto.tftpc;
|
||||
|
||||
(void)status; /* unused */
|
||||
@ -1103,8 +1110,10 @@ static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
|
||||
* The getsock callback
|
||||
*
|
||||
**********************************************************/
|
||||
static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
static int tftp_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
{
|
||||
(void)data;
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_READSOCK(0);
|
||||
}
|
||||
@ -1116,12 +1125,12 @@ static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
* Called once select fires and data is ready on the socket
|
||||
*
|
||||
**********************************************************/
|
||||
static CURLcode tftp_receive_packet(struct connectdata *conn)
|
||||
static CURLcode tftp_receive_packet(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_sockaddr_storage fromaddr;
|
||||
curl_socklen_t fromlen;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct tftp_state_data *state = conn->proto.tftpc;
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
||||
@ -1154,7 +1163,7 @@ static CURLcode tftp_receive_packet(struct connectdata *conn)
|
||||
/* Don't pass to the client empty or retransmitted packets */
|
||||
if(state->rbytes > 4 &&
|
||||
(NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
(char *)state->rpacket.data + 4,
|
||||
state->rbytes-4);
|
||||
if(result) {
|
||||
@ -1207,9 +1216,10 @@ static CURLcode tftp_receive_packet(struct connectdata *conn)
|
||||
* Check if timeouts have been reached
|
||||
*
|
||||
**********************************************************/
|
||||
static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
|
||||
static long tftp_state_timeout(struct Curl_easy *data, tftp_event_t *event)
|
||||
{
|
||||
time_t current;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct tftp_state_data *state = conn->proto.tftpc;
|
||||
|
||||
if(event)
|
||||
@ -1217,7 +1227,7 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
|
||||
|
||||
time(¤t);
|
||||
if(current > state->max_time) {
|
||||
DEBUGF(infof(conn->data, "timeout: %ld > %ld\n",
|
||||
DEBUGF(infof(data, "timeout: %ld > %ld\n",
|
||||
(long)current, (long)state->max_time));
|
||||
state->error = TFTP_ERR_TIMEOUT;
|
||||
state->state = TFTP_STATE_FIN;
|
||||
@ -1242,13 +1252,13 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
|
||||
* Handle single RX socket event and return
|
||||
*
|
||||
**********************************************************/
|
||||
static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
|
||||
static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
tftp_event_t event;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
tftp_event_t event;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct tftp_state_data *state = conn->proto.tftpc;
|
||||
long timeout_ms = tftp_state_timeout(conn, &event);
|
||||
long timeout_ms = tftp_state_timeout(data, &event);
|
||||
|
||||
*done = FALSE;
|
||||
|
||||
@ -1277,7 +1287,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
|
||||
state->event = TFTP_EVENT_ERROR;
|
||||
}
|
||||
else if(rc != 0) {
|
||||
result = tftp_receive_packet(conn);
|
||||
result = tftp_receive_packet(data);
|
||||
if(result)
|
||||
return result;
|
||||
result = tftp_state_machine(state, state->event);
|
||||
@ -1301,22 +1311,22 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
|
||||
* Called from multi.c while DOing
|
||||
*
|
||||
**********************************************************/
|
||||
static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
|
||||
static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done)
|
||||
{
|
||||
CURLcode result;
|
||||
result = tftp_multi_statemach(conn, dophase_done);
|
||||
result = tftp_multi_statemach(data, dophase_done);
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
else if(!result) {
|
||||
/* The multi code doesn't have this logic for the DOING state so we
|
||||
provide it for TFTP since it may do the entire transfer in this
|
||||
state. */
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
if(Curl_pgrsUpdate(data->conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else
|
||||
result = Curl_speedcheck(conn->data, Curl_now());
|
||||
result = Curl_speedcheck(data, Curl_now());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1328,9 +1338,10 @@ static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
|
||||
* Entry point for transfer from tftp_do, sarts state mach
|
||||
*
|
||||
**********************************************************/
|
||||
static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
|
||||
static CURLcode tftp_perform(struct Curl_easy *data, bool *dophase_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct tftp_state_data *state = conn->proto.tftpc;
|
||||
|
||||
*dophase_done = FALSE;
|
||||
@ -1340,10 +1351,10 @@ static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
|
||||
if((state->state == TFTP_STATE_FIN) || result)
|
||||
return result;
|
||||
|
||||
tftp_multi_statemach(conn, dophase_done);
|
||||
tftp_multi_statemach(data, dophase_done);
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1359,15 +1370,16 @@ static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
static CURLcode tftp_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode tftp_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct tftp_state_data *state;
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
*done = FALSE;
|
||||
|
||||
if(!conn->proto.tftpc) {
|
||||
result = tftp_connect(conn, done);
|
||||
result = tftp_connect(data, done);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -1376,7 +1388,7 @@ static CURLcode tftp_do(struct connectdata *conn, bool *done)
|
||||
if(!state)
|
||||
return CURLE_TFTP_ILLEGAL;
|
||||
|
||||
result = tftp_perform(conn, done);
|
||||
result = tftp_perform(data, done);
|
||||
|
||||
/* If tftp_perform() returned an error, use that for return code. If it
|
||||
was OK, see if tftp_translate_code() has an error. */
|
||||
@ -1387,9 +1399,9 @@ static CURLcode tftp_do(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode tftp_setup_connection(struct connectdata *conn)
|
||||
static CURLcode tftp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *type;
|
||||
|
||||
conn->transport = TRNSPRT_UDP;
|
||||
|
@ -93,12 +93,11 @@
|
||||
*
|
||||
* Returns a pointer to the first matching header or NULL if none matched.
|
||||
*/
|
||||
char *Curl_checkheaders(const struct connectdata *conn,
|
||||
char *Curl_checkheaders(const struct Curl_easy *data,
|
||||
const char *thisheader)
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
for(head = data->set.headers; head; head = head->next) {
|
||||
if(strncasecompare(head->data, thisheader, thislen) &&
|
||||
@ -599,7 +598,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
|
||||
if(bytestoread) {
|
||||
/* receive data from the network! */
|
||||
result = Curl_read(conn, conn->sockfd, buf, bytestoread, &nread);
|
||||
result = Curl_read(data, conn->sockfd, buf, bytestoread, &nread);
|
||||
|
||||
/* read would've blocked */
|
||||
if(CURLE_AGAIN == result)
|
||||
@ -814,11 +813,11 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
|
||||
/* Don't let excess data pollute body writes */
|
||||
if(k->maxdownload == -1 || (curl_off_t)headlen <= k->maxdownload)
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
Curl_dyn_ptr(&data->state.headerb),
|
||||
headlen);
|
||||
else
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
Curl_dyn_ptr(&data->state.headerb),
|
||||
(size_t)k->maxdownload);
|
||||
|
||||
@ -835,10 +834,10 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
if(!k->ignorebody) {
|
||||
#ifndef CURL_DISABLE_POP3
|
||||
if(conn->handler->protocol & PROTO_FAMILY_POP3)
|
||||
result = Curl_pop3_write(conn, k->str, nread);
|
||||
result = Curl_pop3_write(data, k->str, nread);
|
||||
else
|
||||
#endif /* CURL_DISABLE_POP3 */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
|
||||
nread);
|
||||
}
|
||||
}
|
||||
@ -904,13 +903,14 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_done_sending(struct connectdata *conn,
|
||||
CURLcode Curl_done_sending(struct Curl_easy *data,
|
||||
struct SingleRequest *k)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
k->keepon &= ~KEEP_SEND; /* we're done writing */
|
||||
|
||||
/* These functions should be moved into the handler struct! */
|
||||
Curl_http2_done_sending(conn);
|
||||
Curl_http2_done_sending(data, conn);
|
||||
Curl_quic_done_sending(conn);
|
||||
|
||||
if(conn->bits.rewindaftersend) {
|
||||
@ -1017,7 +1017,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
|
||||
break;
|
||||
}
|
||||
if(nread <= 0) {
|
||||
result = Curl_done_sending(conn, k);
|
||||
result = Curl_done_sending(data, k);
|
||||
if(result)
|
||||
return result;
|
||||
break;
|
||||
@ -1079,7 +1079,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
|
||||
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
|
||||
result = Curl_smtp_escape_eob(conn, nread);
|
||||
result = Curl_smtp_escape_eob(data, nread);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -1091,7 +1091,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
/* write to socket (send away data) */
|
||||
result = Curl_write(conn,
|
||||
result = Curl_write(data,
|
||||
conn->writesockfd, /* socket to send to */
|
||||
k->upload_fromhere, /* buffer pointer */
|
||||
k->upload_present, /* buffer size */
|
||||
@ -1148,7 +1148,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
|
||||
k->upload_present = 0; /* no more bytes left */
|
||||
|
||||
if(k->upload_done) {
|
||||
result = Curl_done_sending(conn, k);
|
||||
result = Curl_done_sending(data, k);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -1336,15 +1336,15 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
* keeps track of. This function will only be called for connections that are
|
||||
* in the proper state to have this information available.
|
||||
*/
|
||||
int Curl_single_getsock(const struct connectdata *conn,
|
||||
int Curl_single_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
{
|
||||
const struct Curl_easy *data = conn->data;
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
unsigned sockindex = 0;
|
||||
|
||||
if(conn->handler->perform_getsock)
|
||||
return conn->handler->perform_getsock(conn, sock);
|
||||
return conn->handler->perform_getsock(data, conn, sock);
|
||||
|
||||
/* don't include HOLD and PAUSE connections */
|
||||
if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
|
||||
|
@ -23,7 +23,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#define Curl_headersep(x) ((((x)==':') || ((x)==';')))
|
||||
char *Curl_checkheaders(const struct connectdata *conn,
|
||||
char *Curl_checkheaders(const struct Curl_easy *data,
|
||||
const char *thisheader);
|
||||
|
||||
void Curl_init_CONNECT(struct Curl_easy *data);
|
||||
@ -45,8 +45,8 @@ CURLcode Curl_follow(struct Curl_easy *data, char *newurl,
|
||||
CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
struct Curl_easy *data, bool *done,
|
||||
bool *comeback);
|
||||
int Curl_single_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
int Curl_single_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
CURLcode Curl_readrewind(struct connectdata *conn);
|
||||
CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
|
||||
size_t *nreadp);
|
||||
@ -54,7 +54,7 @@ CURLcode Curl_retry_request(struct connectdata *conn, char **url);
|
||||
bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
|
||||
CURLcode Curl_get_upload_buffer(struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_done_sending(struct connectdata *conn,
|
||||
CURLcode Curl_done_sending(struct Curl_easy *data,
|
||||
struct SingleRequest *k);
|
||||
|
||||
/* This sets up a forthcoming transfer */
|
||||
|
99
lib/url.c
99
lib/url.c
@ -364,6 +364,9 @@ CURLcode Curl_close(struct Curl_easy **datap)
|
||||
|
||||
Curl_expire_clear(data); /* shut off timers */
|
||||
|
||||
/* Detach connection if any is left. This should not be normal, but can be
|
||||
the case for example with CONNECT_ONLY + recv/send (test 556) */
|
||||
Curl_detach_connnection(data);
|
||||
m = data->multi;
|
||||
if(m)
|
||||
/* This handle is still part of a multi handle, take care of this first
|
||||
@ -709,11 +712,11 @@ static void conn_reset_all_postponed_data(struct connectdata *conn)
|
||||
#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
|
||||
|
||||
|
||||
static void conn_shutdown(struct connectdata *conn)
|
||||
static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
DEBUGASSERT(conn);
|
||||
infof(conn->data, "Closing connection %ld\n", conn->connection_id);
|
||||
DEBUGASSERT(conn->data);
|
||||
DEBUGASSERT(data);
|
||||
infof(data, "Closing connection %ld\n", conn->connection_id);
|
||||
|
||||
/* possible left-overs from the async name resolvers */
|
||||
Curl_resolver_cancel(conn);
|
||||
@ -725,13 +728,13 @@ static void conn_shutdown(struct connectdata *conn)
|
||||
|
||||
/* close possibly still open sockets */
|
||||
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
|
||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||
Curl_closesocket(data, conn, conn->sock[SECONDARYSOCKET]);
|
||||
if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
|
||||
Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
|
||||
Curl_closesocket(data, conn, conn->sock[FIRSTSOCKET]);
|
||||
if(CURL_SOCKET_BAD != conn->tempsock[0])
|
||||
Curl_closesocket(conn, conn->tempsock[0]);
|
||||
Curl_closesocket(data, conn, conn->tempsock[0]);
|
||||
if(CURL_SOCKET_BAD != conn->tempsock[1])
|
||||
Curl_closesocket(conn, conn->tempsock[1]);
|
||||
Curl_closesocket(data, conn, conn->tempsock[1]);
|
||||
}
|
||||
|
||||
static void conn_free(struct connectdata *conn)
|
||||
@ -834,11 +837,18 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
|
||||
/* treat the connection as dead in CONNECT_ONLY situations */
|
||||
dead_connection = TRUE;
|
||||
|
||||
if(conn->handler->disconnect)
|
||||
/* This is set if protocol-specific cleanups should be made */
|
||||
conn->handler->disconnect(conn, dead_connection);
|
||||
if(conn->handler->disconnect) {
|
||||
/* During disconnect, the connection and the transfer is already
|
||||
disassociated, but the SSH backends (and more?) still need the
|
||||
transfer's connection pointer to identify the used connection */
|
||||
data->conn = conn;
|
||||
|
||||
conn_shutdown(conn);
|
||||
/* This is set if protocol-specific cleanups should be made */
|
||||
conn->handler->disconnect(data, conn, dead_connection);
|
||||
data->conn = NULL; /* forget it again */
|
||||
}
|
||||
|
||||
conn_shutdown(data, conn);
|
||||
conn_free(conn);
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -961,23 +971,29 @@ static bool conn_maxage(struct Curl_easy *data,
|
||||
static bool extract_if_dead(struct connectdata *conn,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
if(!CONN_INUSE(conn) && !conn->data) {
|
||||
if(!CONN_INUSE(conn)) {
|
||||
/* The check for a dead socket makes sense only if the connection isn't in
|
||||
use */
|
||||
bool dead;
|
||||
struct curltime now = Curl_now();
|
||||
if(conn_maxage(data, conn, now)) {
|
||||
/* avoid check if already too old */
|
||||
dead = TRUE;
|
||||
}
|
||||
else if(conn->handler->connection_check) {
|
||||
/* The protocol has a special method for checking the state of the
|
||||
connection. Use it to check if the connection is dead. */
|
||||
unsigned int state;
|
||||
struct Curl_easy *olddata = conn->data;
|
||||
conn->data = data; /* use this transfer for now */
|
||||
state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD);
|
||||
conn->data = olddata;
|
||||
|
||||
/* briefly attach the connection to this transfer for the purpose of
|
||||
checking it */
|
||||
Curl_attach_connnection(data, conn);
|
||||
conn->data = data; /* find the way back if necessary */
|
||||
state = conn->handler->connection_check(data, conn, CONNCHECK_ISDEAD);
|
||||
dead = (state & CONNRESULT_DEAD);
|
||||
/* detach the connection again */
|
||||
Curl_detach_connnection(data);
|
||||
conn->data = NULL; /* clear it again */
|
||||
}
|
||||
else {
|
||||
/* Use the general method for determining the death of a connection */
|
||||
@ -1002,10 +1018,11 @@ struct prunedead {
|
||||
* Wrapper to use extract_if_dead() function in Curl_conncache_foreach()
|
||||
*
|
||||
*/
|
||||
static int call_extract_if_dead(struct connectdata *conn, void *param)
|
||||
static int call_extract_if_dead(struct Curl_easy *data,
|
||||
struct connectdata *conn, void *param)
|
||||
{
|
||||
struct prunedead *p = (struct prunedead *)param;
|
||||
if(extract_if_dead(conn, p->data)) {
|
||||
if(extract_if_dead(conn, data)) {
|
||||
/* stop the iteration here, pass back the connection that was extracted */
|
||||
p->extracted = conn;
|
||||
return 1;
|
||||
@ -1015,14 +1032,16 @@ static int call_extract_if_dead(struct connectdata *conn, void *param)
|
||||
|
||||
/*
|
||||
* This function scans the connection cache for half-open/dead connections,
|
||||
* closes and removes them.
|
||||
* The cleanup is done at most once per second.
|
||||
* closes and removes them. The cleanup is done at most once per second.
|
||||
*
|
||||
* When called, this transfer has no connection attached.
|
||||
*/
|
||||
static void prune_dead_connections(struct Curl_easy *data)
|
||||
{
|
||||
struct curltime now = Curl_now();
|
||||
timediff_t elapsed;
|
||||
|
||||
DEBUGASSERT(!data->conn); /* no connection */
|
||||
CONNCACHE_LOCK(data);
|
||||
elapsed =
|
||||
Curl_timediff(now, data->state.conn_cache->last_cleanup);
|
||||
@ -1463,9 +1482,10 @@ ConnectionExists(struct Curl_easy *data,
|
||||
* verboseconnect() displays verbose information after a connect
|
||||
*/
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
void Curl_verboseconnect(struct connectdata *conn)
|
||||
void Curl_verboseconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(conn->data->set.verbose)
|
||||
if(data->set.verbose)
|
||||
infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
|
||||
@ -2084,7 +2104,8 @@ static CURLcode setup_range(struct Curl_easy *data)
|
||||
*
|
||||
* This MUST get called after proxy magic has been figured out.
|
||||
*/
|
||||
static CURLcode setup_connection_internals(struct connectdata *conn)
|
||||
static CURLcode setup_connection_internals(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
const struct Curl_handler *p;
|
||||
CURLcode result;
|
||||
@ -2093,7 +2114,7 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
|
||||
p = conn->handler;
|
||||
|
||||
if(p->setup_connection) {
|
||||
result = (*p->setup_connection)(conn);
|
||||
result = (*p->setup_connection)(data, conn);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@ -3337,7 +3358,8 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
||||
* previously existing one. All relevant data is copied over and old_conn is
|
||||
* ready for freeing once this function returns.
|
||||
*/
|
||||
static void reuse_conn(struct connectdata *old_conn,
|
||||
static void reuse_conn(struct Curl_easy *data,
|
||||
struct connectdata *old_conn,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
@ -3352,7 +3374,7 @@ static void reuse_conn(struct connectdata *old_conn,
|
||||
allocated in vain and is targeted for destruction */
|
||||
Curl_free_primary_ssl_config(&old_conn->ssl_config);
|
||||
|
||||
conn->data = old_conn->data;
|
||||
conn->data = data;
|
||||
|
||||
/* get the user+password information from the old_conn struct since it may
|
||||
* be new for this request even when we re-use an existing connection */
|
||||
@ -3406,7 +3428,7 @@ static void reuse_conn(struct connectdata *old_conn,
|
||||
old_conn->hostname_resolve = NULL;
|
||||
|
||||
/* persist connection info in session handle */
|
||||
Curl_persistconninfo(conn);
|
||||
Curl_persistconninfo(data, conn);
|
||||
|
||||
conn_reset_all_postponed_data(old_conn); /* free buffers */
|
||||
|
||||
@ -3600,7 +3622,7 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
* Setup internals depending on protocol. Needs to be done after
|
||||
* we figured out what/if proxy to use.
|
||||
*************************************************************/
|
||||
result = setup_connection_internals(conn);
|
||||
result = setup_connection_internals(data, conn);
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
@ -3620,8 +3642,8 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
/* this is supposed to be the connect function so we better at least check
|
||||
that the file is present here! */
|
||||
DEBUGASSERT(conn->handler->connect_it);
|
||||
Curl_persistconninfo(conn);
|
||||
result = conn->handler->connect_it(conn, &done);
|
||||
Curl_persistconninfo(data, conn);
|
||||
result = conn->handler->connect_it(data, &done);
|
||||
|
||||
/* Setup a "faked" transfer that'll do nothing */
|
||||
if(!result) {
|
||||
@ -3639,7 +3661,7 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
if(result) {
|
||||
DEBUGASSERT(conn->handler->done);
|
||||
/* we ignore the return code for the protocol-specific DONE */
|
||||
(void)conn->handler->done(conn, result, FALSE);
|
||||
(void)conn->handler->done(data, result, FALSE);
|
||||
goto out;
|
||||
}
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, -1);
|
||||
@ -3752,12 +3774,11 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
|
||||
if(reuse) {
|
||||
/*
|
||||
* We already have a connection for this, we got the former connection
|
||||
* in the conn_temp variable and thus we need to cleanup the one we
|
||||
* just allocated before we can move along and use the previously
|
||||
* existing one.
|
||||
* We already have a connection for this, we got the former connection in
|
||||
* the conn_temp variable and thus we need to cleanup the one we just
|
||||
* allocated before we can move along and use the previously existing one.
|
||||
*/
|
||||
reuse_conn(conn, conn_temp);
|
||||
reuse_conn(data, conn, conn_temp);
|
||||
#ifdef USE_SSL
|
||||
free(conn->ssl_extra);
|
||||
#endif
|
||||
@ -3958,7 +3979,7 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
|
||||
|
||||
if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
|
||||
conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
|
||||
result = Curl_connecthost(conn, conn->dns_entry);
|
||||
result = Curl_connecthost(data, conn, conn->dns_entry);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -3969,8 +3990,8 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
|
||||
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
|
||||
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
|
||||
*protocol_done = TRUE;
|
||||
Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
|
||||
Curl_verboseconnect(conn);
|
||||
Curl_updateconninfo(data, conn, conn->sock[FIRSTSOCKET]);
|
||||
Curl_verboseconnect(data, conn);
|
||||
}
|
||||
|
||||
conn->now = Curl_now(); /* time this *after* the connect is done, we set
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -72,9 +72,9 @@ void Curl_free_idnconverted_hostname(struct hostname *host);
|
||||
specified */
|
||||
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
#define Curl_verboseconnect(x) Curl_nop_stmt
|
||||
#define Curl_verboseconnect(x,y) Curl_nop_stmt
|
||||
#else
|
||||
void Curl_verboseconnect(struct connectdata *conn);
|
||||
void Curl_verboseconnect(struct Curl_easy *data, struct connectdata *conn);
|
||||
#endif
|
||||
|
||||
#ifdef CURL_DISABLE_PROXY
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -105,14 +105,14 @@
|
||||
#include "dynbuf.h"
|
||||
|
||||
/* return the count of bytes sent, or -1 on error */
|
||||
typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
|
||||
typedef ssize_t (Curl_send)(struct Curl_easy *data, /* transfer */
|
||||
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 */
|
||||
typedef ssize_t (Curl_recv)(struct Curl_easy *data, /* transfer */
|
||||
int sockindex, /* socketindex */
|
||||
char *buf, /* store data here */
|
||||
size_t len, /* max amount to read */
|
||||
@ -535,12 +535,6 @@ struct Curl_async {
|
||||
#define FIRSTSOCKET 0
|
||||
#define SECONDARYSOCKET 1
|
||||
|
||||
/* These function pointer types are here only to allow easier typecasting
|
||||
within the source when we need to cast between data pointers (such as NULL)
|
||||
and function pointers. */
|
||||
typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *);
|
||||
typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
|
||||
|
||||
enum expect100 {
|
||||
EXP100_SEND_DATA, /* enough waiting, just send the body now */
|
||||
EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */
|
||||
@ -697,18 +691,20 @@ struct SingleRequest {
|
||||
struct Curl_handler {
|
||||
const char *scheme; /* URL scheme name. */
|
||||
|
||||
/* Complement to setup_connection_internals(). */
|
||||
CURLcode (*setup_connection)(struct connectdata *);
|
||||
/* Complement to setup_connection_internals(). This is done before the
|
||||
transfer "owns" the connection. */
|
||||
CURLcode (*setup_connection)(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
/* These two functions MUST be set to be protocol dependent */
|
||||
CURLcode (*do_it)(struct connectdata *, bool *done);
|
||||
Curl_done_func done;
|
||||
CURLcode (*do_it)(struct Curl_easy *data, bool *done);
|
||||
CURLcode (*done)(struct Curl_easy *, CURLcode, bool);
|
||||
|
||||
/* If the curl_do() function is better made in two halves, this
|
||||
* curl_do_more() function will be called afterwards, if set. For example
|
||||
* for doing the FTP stuff after the PASV/PORT command.
|
||||
*/
|
||||
Curl_do_more_func do_more;
|
||||
CURLcode (*do_more)(struct Curl_easy *, int *);
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* after the connect() and everything is done, as a step in the connection.
|
||||
@ -716,39 +712,41 @@ struct Curl_handler {
|
||||
* function completes before return. If it doesn't complete, the caller
|
||||
* should call the curl_connecting() function until it is.
|
||||
*/
|
||||
CURLcode (*connect_it)(struct connectdata *, bool *done);
|
||||
CURLcode (*connect_it)(struct Curl_easy *data, bool *done);
|
||||
|
||||
/* See above. */
|
||||
CURLcode (*connecting)(struct connectdata *, bool *done);
|
||||
CURLcode (*doing)(struct connectdata *, bool *done);
|
||||
CURLcode (*connecting)(struct Curl_easy *data, bool *done);
|
||||
CURLcode (*doing)(struct Curl_easy *data, bool *done);
|
||||
|
||||
/* Called from the multi interface during the PROTOCONNECT phase, and it
|
||||
should then return a proper fd set */
|
||||
int (*proto_getsock)(struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
int (*proto_getsock)(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
|
||||
/* Called from the multi interface during the DOING phase, and it should
|
||||
then return a proper fd set */
|
||||
int (*doing_getsock)(struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
int (*doing_getsock)(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
|
||||
/* Called from the multi interface during the DO_MORE phase, and it should
|
||||
then return a proper fd set */
|
||||
int (*domore_getsock)(struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
int (*domore_getsock)(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
|
||||
/* Called from the multi interface during the DO_DONE, PERFORM and
|
||||
WAITPERFORM phases, and it should then return a proper fd set. Not setting
|
||||
this will make libcurl use the generic default one. */
|
||||
int (*perform_getsock)(const struct connectdata *conn,
|
||||
curl_socket_t *socks);
|
||||
int (*perform_getsock)(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* by the curl_disconnect(), as a step in the disconnection. If the handler
|
||||
* is called because the connection has been considered dead, dead_connection
|
||||
* is set to TRUE.
|
||||
* is called because the connection has been considered dead,
|
||||
* dead_connection is set to TRUE. The connection is already disassociated
|
||||
* from the transfer here.
|
||||
*/
|
||||
CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
|
||||
CURLcode (*disconnect)(struct Curl_easy *, struct connectdata *,
|
||||
bool dead_connection);
|
||||
|
||||
/* If used, this function gets called from transfer.c:readwrite_data() to
|
||||
allow the protocol to do extra reads/writes */
|
||||
@ -758,7 +756,8 @@ struct Curl_handler {
|
||||
/* This function can perform various checks on the connection. See
|
||||
CONNCHECK_* for more information about the checks that can be performed,
|
||||
and CONNRESULT_* for the results that can be returned. */
|
||||
unsigned int (*connection_check)(struct connectdata *conn,
|
||||
unsigned int (*connection_check)(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
unsigned int checks_to_perform);
|
||||
|
||||
long defport; /* Default port. */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -90,7 +90,7 @@ struct h3out {
|
||||
static CURLcode ng_process_ingress(struct connectdata *conn,
|
||||
curl_socket_t sockfd,
|
||||
struct quicsocket *qs);
|
||||
static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
static CURLcode ng_flush_egress(struct Curl_easy *data, int sockfd,
|
||||
struct quicsocket *qs);
|
||||
static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
|
||||
size_t datalen, void *user_data,
|
||||
@ -843,9 +843,10 @@ int Curl_quic_ver(char *p, size_t len)
|
||||
ng2->version_str, ht3->version_str);
|
||||
}
|
||||
|
||||
static int ng_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
static int ng_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
struct SingleRequest *k = &conn->data->req;
|
||||
struct SingleRequest *k = &data->req;
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
@ -861,12 +862,6 @@ static int ng_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static int ng_perform_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
return ng_getsock((struct connectdata *)conn, socks);
|
||||
}
|
||||
|
||||
static void qs_disconnect(struct quicsocket *qs)
|
||||
{
|
||||
int i;
|
||||
@ -904,18 +899,22 @@ void Curl_quic_disconnect(struct connectdata *conn,
|
||||
qs_disconnect(&conn->hequic[tempindex]);
|
||||
}
|
||||
|
||||
static CURLcode ng_disconnect(struct connectdata *conn,
|
||||
static CURLcode ng_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
(void)dead_connection;
|
||||
(void)data;
|
||||
Curl_quic_disconnect(conn, 0);
|
||||
Curl_quic_disconnect(conn, 1);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static unsigned int ng_conncheck(struct connectdata *conn,
|
||||
static unsigned int ng_conncheck(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
unsigned int checks_to_perform)
|
||||
{
|
||||
(void)data;
|
||||
(void)conn;
|
||||
(void)checks_to_perform;
|
||||
return CONNRESULT_NONE;
|
||||
@ -933,7 +932,7 @@ static const struct Curl_handler Curl_handler_http3 = {
|
||||
ng_getsock, /* proto_getsock */
|
||||
ng_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ng_perform_getsock, /* perform_getsock */
|
||||
ng_getsock, /* perform_getsock */
|
||||
ng_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ng_conncheck, /* connection_check */
|
||||
@ -1235,14 +1234,15 @@ static size_t drain_overflow_buffer(struct HTTP *stream)
|
||||
}
|
||||
|
||||
/* incoming data frames on the h3 stream */
|
||||
static ssize_t ngh3_stream_recv(struct connectdata *conn,
|
||||
static ssize_t ngh3_stream_recv(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
char *buf,
|
||||
size_t buffersize,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
struct quicsocket *qs = conn->quic;
|
||||
|
||||
if(!stream->memlen) {
|
||||
@ -1261,7 +1261,7 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
|
||||
*curlcode = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
if(ng_flush_egress(conn, sockfd, qs)) {
|
||||
if(ng_flush_egress(data, sockfd, qs)) {
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
@ -1277,7 +1277,7 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
|
||||
/* extend the stream window with the data we're consuming and send out
|
||||
any additional packets to tell the server that we can receive more */
|
||||
extend_stream_window(qs->qconn, stream);
|
||||
if(ng_flush_egress(conn, sockfd, qs)) {
|
||||
if(ng_flush_egress(data, sockfd, qs)) {
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
@ -1289,7 +1289,7 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
infof(conn->data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n");
|
||||
infof(data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n");
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
@ -1382,10 +1382,11 @@ static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
|
||||
field list. */
|
||||
#define AUTHORITY_DST_IDX 3
|
||||
|
||||
static CURLcode http_request(struct connectdata *conn, const void *mem,
|
||||
static CURLcode http_request(struct Curl_easy *data, const void *mem,
|
||||
size_t len)
|
||||
{
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
size_t nheader;
|
||||
size_t i;
|
||||
size_t authority_idx;
|
||||
@ -1393,7 +1394,6 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
|
||||
char *end, *line_end;
|
||||
struct quicsocket *qs = conn->quic;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
nghttp3_nv *nva = NULL;
|
||||
int64_t stream3_id;
|
||||
int rc;
|
||||
@ -1401,7 +1401,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
|
||||
|
||||
rc = ngtcp2_conn_open_bidi_stream(qs->qconn, &stream3_id, NULL);
|
||||
if(rc) {
|
||||
failf(conn->data, "can get bidi streams");
|
||||
failf(data, "can get bidi streams");
|
||||
result = CURLE_SEND_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
@ -1587,8 +1587,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
|
||||
stream->h3out = h3out;
|
||||
|
||||
rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id,
|
||||
nva, nheader, &data_reader,
|
||||
conn->data);
|
||||
nva, nheader, &data_reader, data);
|
||||
if(rc) {
|
||||
result = CURLE_SEND_ERROR;
|
||||
goto fail;
|
||||
@ -1598,9 +1597,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
|
||||
default:
|
||||
stream->upload_left = 0; /* nothing left to send */
|
||||
rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id,
|
||||
nva, nheader,
|
||||
NULL, /* no body! */
|
||||
conn->data);
|
||||
nva, nheader, NULL, data);
|
||||
if(rc) {
|
||||
result = CURLE_SEND_ERROR;
|
||||
goto fail;
|
||||
@ -1619,19 +1616,20 @@ fail:
|
||||
free(nva);
|
||||
return result;
|
||||
}
|
||||
static ssize_t ngh3_stream_send(struct connectdata *conn,
|
||||
static ssize_t ngh3_stream_send(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
ssize_t sent;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct quicsocket *qs = conn->quic;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
|
||||
if(!stream->h3req) {
|
||||
CURLcode result = http_request(conn, mem, len);
|
||||
CURLcode result = http_request(data, mem, len);
|
||||
if(result) {
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
@ -1639,7 +1637,7 @@ static ssize_t ngh3_stream_send(struct connectdata *conn,
|
||||
sent = len;
|
||||
}
|
||||
else {
|
||||
H3BUGF(infof(conn->data, "ngh3_stream_send() wants to send %zd bytes\n",
|
||||
H3BUGF(infof(data, "ngh3_stream_send() wants to send %zd bytes\n",
|
||||
len));
|
||||
if(!stream->upload_len) {
|
||||
stream->upload_mem = mem;
|
||||
@ -1653,7 +1651,7 @@ static ssize_t ngh3_stream_send(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
if(ng_flush_egress(conn, sockfd, qs)) {
|
||||
if(ng_flush_egress(data, sockfd, qs)) {
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
@ -1689,7 +1687,7 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn,
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
result = ng_flush_egress(conn, sockfd, qs);
|
||||
result = ng_flush_egress(conn->data, sockfd, qs);
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
@ -1749,7 +1747,8 @@ static CURLcode ng_process_ingress(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
static CURLcode ng_flush_egress(struct Curl_easy *data,
|
||||
int sockfd,
|
||||
struct quicsocket *qs)
|
||||
{
|
||||
int rv;
|
||||
@ -1783,7 +1782,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
|
||||
rv = ngtcp2_conn_handle_expiry(qs->qconn, ts);
|
||||
if(rv != 0) {
|
||||
failf(conn->data, "ngtcp2_conn_handle_expiry returned error: %s",
|
||||
failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
|
||||
ngtcp2_strerror(rv));
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
@ -1796,7 +1795,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
veccnt = nghttp3_conn_writev_stream(qs->h3conn, &stream_id, &fin, vec,
|
||||
sizeof(vec) / sizeof(vec[0]));
|
||||
if(veccnt < 0) {
|
||||
failf(conn->data, "nghttp3_conn_writev_stream returned error: %s",
|
||||
failf(data, "nghttp3_conn_writev_stream returned error: %s",
|
||||
nghttp3_strerror((int)veccnt));
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
@ -1817,7 +1816,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
assert(ndatalen == -1);
|
||||
rv = nghttp3_conn_block_stream(qs->h3conn, stream_id);
|
||||
if(rv != 0) {
|
||||
failf(conn->data,
|
||||
failf(data,
|
||||
"nghttp3_conn_block_stream returned error: %s\n",
|
||||
nghttp3_strerror(rv));
|
||||
return CURLE_SEND_ERROR;
|
||||
@ -1829,7 +1828,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id,
|
||||
ndatalen);
|
||||
if(rv != 0) {
|
||||
failf(conn->data,
|
||||
failf(data,
|
||||
"nghttp3_conn_add_write_offset returned error: %s\n",
|
||||
nghttp3_strerror(rv));
|
||||
return CURLE_SEND_ERROR;
|
||||
@ -1838,7 +1837,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
}
|
||||
else {
|
||||
assert(ndatalen == -1);
|
||||
failf(conn->data, "ngtcp2_conn_writev_stream returned error: %s",
|
||||
failf(data, "ngtcp2_conn_writev_stream returned error: %s",
|
||||
ngtcp2_strerror((int)outlen));
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
@ -1852,7 +1851,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, NULL,
|
||||
out, pktlen, ts);
|
||||
if(outlen < 0) {
|
||||
failf(conn->data, "ngtcp2_conn_write_pkt returned error: %s",
|
||||
failf(data, "ngtcp2_conn_write_pkt returned error: %s",
|
||||
ngtcp2_strerror((int)outlen));
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
@ -1871,7 +1870,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
break;
|
||||
}
|
||||
else {
|
||||
failf(conn->data, "send() returned %zd (errno %d)", sent,
|
||||
failf(data, "send() returned %zd (errno %d)", sent,
|
||||
SOCKERRNO);
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
@ -1886,7 +1885,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
else {
|
||||
timeout = expiry - ts;
|
||||
}
|
||||
Curl_expire(conn->data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
|
||||
Curl_expire(data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -65,9 +65,10 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
|
||||
static Curl_recv h3_stream_recv;
|
||||
static Curl_send h3_stream_send;
|
||||
|
||||
static int quiche_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
static int quiche_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks)
|
||||
{
|
||||
struct SingleRequest *k = &conn->data->req;
|
||||
struct SingleRequest *k = &data->req;
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
@ -83,12 +84,6 @@ static int quiche_getsock(struct connectdata *conn, curl_socket_t *socks)
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static int quiche_perform_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
return quiche_getsock((struct connectdata *)conn, socks);
|
||||
}
|
||||
|
||||
static CURLcode qs_disconnect(struct connectdata *conn,
|
||||
struct quicsocket *qs)
|
||||
{
|
||||
@ -111,10 +106,12 @@ static CURLcode qs_disconnect(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode quiche_disconnect(struct connectdata *conn,
|
||||
static CURLcode quiche_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
struct quicsocket *qs = conn->quic;
|
||||
(void)data;
|
||||
(void)dead_connection;
|
||||
return qs_disconnect(conn, qs);
|
||||
}
|
||||
@ -126,19 +123,21 @@ void Curl_quic_disconnect(struct connectdata *conn,
|
||||
qs_disconnect(conn, &conn->hequic[tempindex]);
|
||||
}
|
||||
|
||||
static unsigned int quiche_conncheck(struct connectdata *conn,
|
||||
static unsigned int quiche_conncheck(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
unsigned int checks_to_perform)
|
||||
{
|
||||
(void)data;
|
||||
(void)conn;
|
||||
(void)checks_to_perform;
|
||||
return CONNRESULT_NONE;
|
||||
}
|
||||
|
||||
static CURLcode quiche_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode quiche_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
stream->h3req = FALSE; /* not sent */
|
||||
return Curl_http(conn, done);
|
||||
return Curl_http(data, done);
|
||||
}
|
||||
|
||||
static const struct Curl_handler Curl_handler_http3 = {
|
||||
@ -153,7 +152,7 @@ static const struct Curl_handler Curl_handler_http3 = {
|
||||
quiche_getsock, /* proto_getsock */
|
||||
quiche_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
quiche_perform_getsock, /* perform_getsock */
|
||||
quiche_getsock, /* perform_getsock */
|
||||
quiche_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
quiche_conncheck, /* connection_check */
|
||||
@ -256,7 +255,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||
Curl_persistconninfo(conn);
|
||||
Curl_persistconninfo(data, conn);
|
||||
|
||||
/* for connection reuse purposes: */
|
||||
conn->ssl[FIRSTSOCKET].state = ssl_connection_complete;
|
||||
@ -453,7 +452,7 @@ static int cb_each_header(uint8_t *name, size_t name_len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t h3_stream_recv(struct connectdata *conn,
|
||||
static ssize_t h3_stream_recv(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
char *buf,
|
||||
size_t buffersize,
|
||||
@ -461,12 +460,12 @@ static ssize_t h3_stream_recv(struct connectdata *conn,
|
||||
{
|
||||
ssize_t recvd = -1;
|
||||
ssize_t rcode;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct quicsocket *qs = conn->quic;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
quiche_h3_event *ev;
|
||||
int rc;
|
||||
struct h3h1header headers;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
headers.dest = buf;
|
||||
headers.destlen = buffersize;
|
||||
@ -546,16 +545,17 @@ static ssize_t h3_stream_recv(struct connectdata *conn,
|
||||
return recvd;
|
||||
}
|
||||
|
||||
static ssize_t h3_stream_send(struct connectdata *conn,
|
||||
static ssize_t h3_stream_send(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
ssize_t sent;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct quicsocket *qs = conn->quic;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
struct HTTP *stream = conn->data->req.p.http;
|
||||
struct HTTP *stream = data->req.p.http;
|
||||
|
||||
if(!stream->h3req) {
|
||||
CURLcode result = http_request(conn, mem, len);
|
||||
|
@ -107,34 +107,37 @@
|
||||
#endif
|
||||
|
||||
/* Local functions: */
|
||||
static CURLcode myssh_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode myssh_multi_statemach(struct connectdata *conn,
|
||||
static CURLcode myssh_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode myssh_multi_statemach(struct Curl_easy *data,
|
||||
bool *done);
|
||||
static CURLcode myssh_do_it(struct connectdata *conn, bool *done);
|
||||
static CURLcode myssh_do_it(struct Curl_easy *data, bool *done);
|
||||
|
||||
static CURLcode scp_done(struct connectdata *conn,
|
||||
static CURLcode scp_done(struct Curl_easy *data,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done);
|
||||
static CURLcode scp_disconnect(struct connectdata *conn,
|
||||
static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static CURLcode scp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection);
|
||||
|
||||
static CURLcode sftp_done(struct connectdata *conn,
|
||||
static CURLcode sftp_done(struct Curl_easy *data,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode sftp_doing(struct connectdata *conn,
|
||||
static CURLcode sftp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done);
|
||||
static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
|
||||
static CURLcode sftp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead);
|
||||
static
|
||||
CURLcode sftp_perform(struct connectdata *conn,
|
||||
CURLcode sftp_perform(struct Curl_easy *data,
|
||||
bool *connected,
|
||||
bool *dophase_done);
|
||||
|
||||
static void sftp_quote(struct connectdata *conn);
|
||||
static void sftp_quote_stat(struct connectdata *conn);
|
||||
static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock);
|
||||
static int myssh_perform_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static int myssh_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *sock);
|
||||
|
||||
static CURLcode myssh_setup_connection(struct connectdata *conn);
|
||||
static CURLcode myssh_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* SCP protocol handler.
|
||||
@ -152,7 +155,7 @@ const struct Curl_handler Curl_handler_scp = {
|
||||
myssh_getsock, /* proto_getsock */
|
||||
myssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
myssh_perform_getsock, /* perform_getsock */
|
||||
myssh_getsock, /* perform_getsock */
|
||||
scp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
@ -178,7 +181,7 @@ const struct Curl_handler Curl_handler_sftp = {
|
||||
myssh_getsock, /* proto_getsock */
|
||||
myssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
myssh_perform_getsock, /* perform_getsock */
|
||||
myssh_getsock, /* perform_getsock */
|
||||
sftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
@ -660,10 +663,10 @@ restart:
|
||||
* to will be set to TRUE if the libssh function returns SSH_AGAIN
|
||||
* meaning it wants to be called again when the socket is ready
|
||||
*/
|
||||
static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct SSHPROTO *protop = data->req.p.ssh;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
@ -950,7 +953,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(sshc->homedir == NULL) {
|
||||
MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
|
||||
}
|
||||
conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
|
||||
data->state.most_recent_ftp_entrypath = sshc->homedir;
|
||||
|
||||
/* This is the last step in the SFTP connect phase. Do note that while
|
||||
we get the homedir here, we get the "workingpath" in the DO action
|
||||
@ -1150,7 +1153,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
break;
|
||||
}
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
if(result) {
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
@ -1419,7 +1422,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->actualcode = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
tmpLine, sshc->readdir_len + 1);
|
||||
free(tmpLine);
|
||||
|
||||
@ -1540,7 +1543,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->readdir_currLen,
|
||||
sshc->readdir_totalLen -
|
||||
sshc->readdir_currLen, "\n");
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
sshc->readdir_line,
|
||||
sshc->readdir_currLen);
|
||||
|
||||
@ -1618,14 +1621,14 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
|
||||
return CURLE_BAD_DOWNLOAD_RESUME;
|
||||
}
|
||||
if(conn->data->state.use_range) {
|
||||
if(data->state.use_range) {
|
||||
curl_off_t from, to;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
CURLofft to_t;
|
||||
CURLofft from_t;
|
||||
|
||||
from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
|
||||
from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
|
||||
if(from_t == CURL_OFFT_FLOW) {
|
||||
return CURLE_RANGE_ERROR;
|
||||
}
|
||||
@ -1772,7 +1775,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
|
||||
SSH_STRING_FREE_CHAR(sshc->homedir);
|
||||
conn->data->state.most_recent_ftp_entrypath = NULL;
|
||||
data->state.most_recent_ftp_entrypath = NULL;
|
||||
|
||||
state(conn, SSH_SESSION_DISCONNECT);
|
||||
break;
|
||||
@ -1808,7 +1811,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
if(!sshc->scp_session) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(conn->data, "%s", err_msg);
|
||||
failf(data, "%s", err_msg);
|
||||
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
|
||||
}
|
||||
|
||||
@ -1819,7 +1822,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
rc = ssh_scp_init(sshc->scp_session);
|
||||
if(rc != SSH_OK) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(conn->data, "%s", err_msg);
|
||||
failf(data, "%s", err_msg);
|
||||
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
|
||||
}
|
||||
|
||||
@ -1828,7 +1831,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
(int)data->set.new_file_perms);
|
||||
if(rc != SSH_OK) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(conn->data, "%s", err_msg);
|
||||
failf(data, "%s", err_msg);
|
||||
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
|
||||
}
|
||||
|
||||
@ -1856,7 +1859,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
rc = ssh_scp_init(sshc->scp_session);
|
||||
if(rc != SSH_OK) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(conn->data, "%s", err_msg);
|
||||
failf(data, "%s", err_msg);
|
||||
MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
|
||||
}
|
||||
state(conn, SSH_SCP_DOWNLOAD);
|
||||
@ -1868,7 +1871,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
rc = ssh_scp_pull_request(sshc->scp_session);
|
||||
if(rc != SSH_SCP_REQUEST_NEWFILE) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(conn->data, "%s", err_msg);
|
||||
failf(data, "%s", err_msg);
|
||||
MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
@ -1938,7 +1941,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
ssh_disconnect(sshc->ssh_session);
|
||||
|
||||
SSH_STRING_FREE_CHAR(sshc->homedir);
|
||||
conn->data->state.most_recent_ftp_entrypath = NULL;
|
||||
data->state.most_recent_ftp_entrypath = NULL;
|
||||
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
/* FALLTHROUGH */
|
||||
@ -2015,10 +2018,12 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
/* called by the multi interface to figure out what socket(s) to wait for and
|
||||
for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
|
||||
static int myssh_perform_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
static int myssh_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
{
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
(void)data;
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(conn->waitfor & KEEP_RECV)
|
||||
@ -2030,16 +2035,6 @@ static int myssh_perform_getsock(const struct connectdata *conn,
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/* Generic function called by the multi interface to figure out what socket(s)
|
||||
to wait for and for what actions during the DOING and PROTOCONNECT states*/
|
||||
static int myssh_getsock(struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
{
|
||||
/* if we know the direction we can use the generic *_getsock() function even
|
||||
for the protocol_connect and doing states */
|
||||
return myssh_perform_getsock(conn, sock);
|
||||
}
|
||||
|
||||
static void myssh_block2waitfor(struct connectdata *conn, bool block)
|
||||
{
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
@ -2061,13 +2056,14 @@ static void myssh_block2waitfor(struct connectdata *conn, bool block)
|
||||
}
|
||||
|
||||
/* called repeatedly until done from multi.c */
|
||||
static CURLcode myssh_multi_statemach(struct connectdata *conn,
|
||||
static CURLcode myssh_multi_statemach(struct Curl_easy *data,
|
||||
bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
bool block; /* we store the status and use that to provide a ssh_getsock()
|
||||
implementation */
|
||||
CURLcode result = myssh_statemach_act(conn, &block);
|
||||
CURLcode result = myssh_statemach_act(data, &block);
|
||||
|
||||
*done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
|
||||
myssh_block2waitfor(conn, block);
|
||||
@ -2075,19 +2071,19 @@ static CURLcode myssh_multi_statemach(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode myssh_block_statemach(struct connectdata *conn,
|
||||
static CURLcode myssh_block_statemach(struct Curl_easy *data,
|
||||
bool disconnect)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
while((sshc->state != SSH_STOP) && !result) {
|
||||
bool block;
|
||||
timediff_t left = 1000;
|
||||
struct curltime now = Curl_now();
|
||||
|
||||
result = myssh_statemach_act(conn, &block);
|
||||
result = myssh_statemach_act(data, &block);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@ -2121,11 +2117,13 @@ static CURLcode myssh_block_statemach(struct connectdata *conn,
|
||||
/*
|
||||
* SSH setup connection
|
||||
*/
|
||||
static CURLcode myssh_setup_connection(struct connectdata *conn)
|
||||
static CURLcode myssh_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct SSHPROTO *ssh;
|
||||
(void)conn;
|
||||
|
||||
conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
|
||||
data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
|
||||
if(!ssh)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@ -2139,17 +2137,17 @@ 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.
|
||||
*/
|
||||
static CURLcode myssh_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct ssh_conn *ssh;
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
struct Curl_easy *data = conn->data;
|
||||
int rc;
|
||||
|
||||
/* initialize per-handle data if not already */
|
||||
if(!data->req.p.ssh)
|
||||
myssh_setup_connection(conn);
|
||||
myssh_setup_connection(data, conn);
|
||||
|
||||
/* We default to persistent connections. We set this already in this connect
|
||||
function to make the re-use checks properly be able to check this bit. */
|
||||
@ -2244,20 +2242,20 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
state(conn, SSH_INIT);
|
||||
|
||||
result = myssh_multi_statemach(conn, done);
|
||||
result = myssh_multi_statemach(data, done);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done)
|
||||
static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
result = myssh_multi_statemach(conn, dophase_done);
|
||||
result = myssh_multi_statemach(data, dophase_done);
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2272,34 +2270,35 @@ static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done)
|
||||
*/
|
||||
|
||||
static
|
||||
CURLcode scp_perform(struct connectdata *conn,
|
||||
CURLcode scp_perform(struct Curl_easy *data,
|
||||
bool *connected, bool *dophase_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
|
||||
*dophase_done = FALSE; /* not done yet */
|
||||
|
||||
/* start the first command in the DO phase */
|
||||
state(conn, SSH_SCP_TRANS_INIT);
|
||||
|
||||
result = myssh_multi_statemach(conn, dophase_done);
|
||||
result = myssh_multi_statemach(data, dophase_done);
|
||||
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode myssh_do_it(struct connectdata *conn, bool *done)
|
||||
static CURLcode myssh_do_it(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
bool connected = 0;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
@ -2316,9 +2315,9 @@ static CURLcode myssh_do_it(struct connectdata *conn, bool *done)
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
|
||||
if(conn->handler->protocol & CURLPROTO_SCP)
|
||||
result = scp_perform(conn, &connected, done);
|
||||
result = scp_perform(data, &connected, done);
|
||||
else
|
||||
result = sftp_perform(conn, &connected, done);
|
||||
result = sftp_perform(data, &connected, done);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -2326,7 +2325,8 @@ static CURLcode myssh_do_it(struct connectdata *conn, bool *done)
|
||||
/* BLOCKING, but the function is using the state machine so the only reason
|
||||
this is still blocking is that the multi interface code has no support for
|
||||
disconnecting operations that takes a while */
|
||||
static CURLcode scp_disconnect(struct connectdata *conn,
|
||||
static CURLcode scp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -2338,7 +2338,7 @@ static CURLcode scp_disconnect(struct connectdata *conn,
|
||||
|
||||
state(conn, SSH_SESSION_DISCONNECT);
|
||||
|
||||
result = myssh_block_statemach(conn, TRUE);
|
||||
result = myssh_block_statemach(data, TRUE);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -2346,44 +2346,45 @@ static CURLcode scp_disconnect(struct connectdata *conn,
|
||||
|
||||
/* generic done function for both SCP and SFTP called from their specific
|
||||
done functions */
|
||||
static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
|
||||
static CURLcode myssh_done(struct Curl_easy *data, CURLcode status)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SSHPROTO *protop = conn->data->req.p.ssh;
|
||||
struct SSHPROTO *protop = data->req.p.ssh;
|
||||
|
||||
if(!status) {
|
||||
/* run the state-machine */
|
||||
result = myssh_block_statemach(conn, FALSE);
|
||||
result = myssh_block_statemach(data, FALSE);
|
||||
}
|
||||
else
|
||||
result = status;
|
||||
|
||||
if(protop)
|
||||
Curl_safefree(protop->path);
|
||||
if(Curl_pgrsDone(conn))
|
||||
if(Curl_pgrsDone(data->conn))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
conn->data->req.keepon = 0; /* clear all bits */
|
||||
data->req.keepon = 0; /* clear all bits */
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode scp_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode scp_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
(void) premature; /* not used */
|
||||
|
||||
if(!status)
|
||||
state(conn, SSH_SCP_DONE);
|
||||
state(data->conn, SSH_SCP_DONE);
|
||||
|
||||
return myssh_done(conn, status);
|
||||
return myssh_done(data, status);
|
||||
|
||||
}
|
||||
|
||||
static ssize_t scp_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t scp_send(struct Curl_easy *data, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
int rc;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void) sockindex; /* we only support SCP on the fixed known primary socket */
|
||||
(void) err;
|
||||
|
||||
@ -2409,10 +2410,11 @@ static ssize_t scp_send(struct connectdata *conn, int sockindex,
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t scp_recv(struct connectdata *conn, int sockindex,
|
||||
static ssize_t scp_recv(struct Curl_easy *data, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void) err;
|
||||
(void) sockindex; /* we only support SCP on the fixed known primary socket */
|
||||
|
||||
@ -2448,13 +2450,14 @@ static ssize_t scp_recv(struct connectdata *conn, int sockindex,
|
||||
*/
|
||||
|
||||
static
|
||||
CURLcode sftp_perform(struct connectdata *conn,
|
||||
CURLcode sftp_perform(struct Curl_easy *data,
|
||||
bool *connected,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
|
||||
*dophase_done = FALSE; /* not done yet */
|
||||
|
||||
@ -2462,24 +2465,24 @@ CURLcode sftp_perform(struct connectdata *conn,
|
||||
state(conn, SSH_SFTP_QUOTE_INIT);
|
||||
|
||||
/* run the state-machine */
|
||||
result = myssh_multi_statemach(conn, dophase_done);
|
||||
result = myssh_multi_statemach(data, dophase_done);
|
||||
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
static CURLcode sftp_doing(struct connectdata *conn,
|
||||
static CURLcode sftp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = myssh_multi_statemach(conn, dophase_done);
|
||||
CURLcode result = myssh_multi_statemach(data, dophase_done);
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2487,46 +2490,50 @@ static CURLcode sftp_doing(struct connectdata *conn,
|
||||
/* BLOCKING, but the function is using the state machine so the only reason
|
||||
this is still blocking is that the multi interface code has no support for
|
||||
disconnecting operations that takes a while */
|
||||
static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
static CURLcode sftp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
(void) dead_connection;
|
||||
|
||||
DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
|
||||
DEBUGF(infof(data, "SSH DISCONNECT starts now\n"));
|
||||
|
||||
if(conn->proto.sshc.ssh_session) {
|
||||
/* only if there's a session still around to use! */
|
||||
state(conn, SSH_SFTP_SHUTDOWN);
|
||||
result = myssh_block_statemach(conn, TRUE);
|
||||
result = myssh_block_statemach(data, TRUE);
|
||||
}
|
||||
|
||||
DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
|
||||
DEBUGF(infof(data, "SSH DISCONNECT is done\n"));
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
static CURLcode sftp_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
|
||||
if(!status) {
|
||||
/* Post quote commands are executed after the SFTP_CLOSE state to avoid
|
||||
errors that could happen due to open file handles during POSTQUOTE
|
||||
operation */
|
||||
if(!premature && conn->data->set.postquote && !conn->bits.retry)
|
||||
if(!premature && data->set.postquote && !conn->bits.retry)
|
||||
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
}
|
||||
return myssh_done(conn, status);
|
||||
return myssh_done(data, status);
|
||||
}
|
||||
|
||||
/* return number of sent bytes */
|
||||
static ssize_t sftp_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
ssize_t nwrite;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)sockindex;
|
||||
|
||||
nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
|
||||
@ -2552,10 +2559,11 @@ static ssize_t sftp_send(struct connectdata *conn, int sockindex,
|
||||
* Return number of received (decrypted) bytes
|
||||
* or <0 on error
|
||||
*/
|
||||
static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
|
||||
static ssize_t sftp_recv(struct Curl_easy *data, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)sockindex;
|
||||
|
||||
DEBUGASSERT(len < CURL_MAX_READ_SIZE);
|
||||
@ -2563,8 +2571,8 @@ static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
|
||||
switch(conn->proto.sshc.sftp_recv_state) {
|
||||
case 0:
|
||||
conn->proto.sshc.sftp_file_index =
|
||||
sftp_async_read_begin(conn->proto.sshc.sftp_file,
|
||||
(uint32_t)len);
|
||||
sftp_async_read_begin(conn->proto.sshc.sftp_file,
|
||||
(uint32_t)len);
|
||||
if(conn->proto.sshc.sftp_file_index < 0) {
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
@ -2638,7 +2646,7 @@ static void sftp_quote(struct connectdata *conn)
|
||||
/* this sends an FTP-like "header" to the header callback so that the
|
||||
current directory can be read very similar to how it is read when
|
||||
using ordinary FTP. */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
if(result) {
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
|
@ -104,29 +104,23 @@ static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
|
||||
static LIBSSH2_FREE_FUNC(my_libssh2_free);
|
||||
|
||||
static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn);
|
||||
static CURLcode ssh_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
|
||||
static CURLcode ssh_do(struct connectdata *conn, bool *done);
|
||||
|
||||
static CURLcode scp_done(struct connectdata *conn,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode scp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
|
||||
|
||||
static CURLcode sftp_done(struct connectdata *conn,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode sftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
|
||||
static
|
||||
CURLcode sftp_perform(struct connectdata *conn,
|
||||
bool *connected,
|
||||
bool *dophase_done);
|
||||
static int ssh_getsock(struct connectdata *conn, curl_socket_t *sock);
|
||||
static int ssh_perform_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static CURLcode ssh_setup_connection(struct connectdata *conn);
|
||||
static CURLcode ssh_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static CURLcode ssh_do(struct Curl_easy *data, bool *done);
|
||||
static CURLcode scp_done(struct Curl_easy *data, CURLcode c, bool premature);
|
||||
static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static CURLcode scp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead_connection);
|
||||
static CURLcode sftp_done(struct Curl_easy *data, CURLcode, bool premature);
|
||||
static CURLcode sftp_doing(struct Curl_easy *data, bool *dophase_done);
|
||||
static CURLcode sftp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead);
|
||||
static CURLcode sftp_perform(struct Curl_easy *data, bool *connected,
|
||||
bool *dophase_done);
|
||||
static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static CURLcode ssh_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* SCP protocol handler.
|
||||
@ -144,7 +138,7 @@ const struct Curl_handler Curl_handler_scp = {
|
||||
ssh_getsock, /* proto_getsock */
|
||||
ssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ssh_perform_getsock, /* perform_getsock */
|
||||
ssh_getsock, /* perform_getsock */
|
||||
scp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
@ -172,7 +166,7 @@ const struct Curl_handler Curl_handler_sftp = {
|
||||
ssh_getsock, /* proto_getsock */
|
||||
ssh_getsock, /* doing_getsock */
|
||||
ZERO_NULL, /* domore_getsock */
|
||||
ssh_perform_getsock, /* perform_getsock */
|
||||
ssh_getsock, /* perform_getsock */
|
||||
sftp_disconnect, /* disconnect */
|
||||
ZERO_NULL, /* readwrite */
|
||||
ZERO_NULL, /* connection_check */
|
||||
@ -794,10 +788,10 @@ static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn)
|
||||
* meaning it wants to be called again when the socket is ready
|
||||
*/
|
||||
|
||||
static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct SSHPROTO *sftp_scp = data->req.p.ssh;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
@ -1196,7 +1190,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
*/
|
||||
infof(data, "Authentication complete\n");
|
||||
|
||||
Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
|
||||
Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */
|
||||
|
||||
conn->sockfd = sock;
|
||||
conn->writesockfd = CURL_SOCKET_BAD;
|
||||
@ -1253,7 +1247,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->actualcode = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
|
||||
data->state.most_recent_ftp_entrypath = sshc->homedir;
|
||||
}
|
||||
else {
|
||||
/* Return the error type */
|
||||
@ -1349,7 +1343,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
/* this sends an FTP-like "header" to the header callback so that the
|
||||
current directory can be read very similar to how it is read when
|
||||
using ordinary FTP. */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
if(result) {
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
@ -1802,7 +1796,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
break;
|
||||
}
|
||||
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
if(result) {
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
@ -2151,11 +2145,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->readdir_filename[readdir_len] = '\0';
|
||||
|
||||
if(data->set.ftp_list_only) {
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
sshc->readdir_filename,
|
||||
readdir_len);
|
||||
if(!result)
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
(char *)"\n", 1);
|
||||
if(result) {
|
||||
state(conn, SSH_STOP);
|
||||
@ -2243,7 +2237,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
case SSH_SFTP_READDIR_BOTTOM:
|
||||
result = Curl_dyn_addn(&sshc->readdir, "\n", 1);
|
||||
if(!result)
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY,
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY,
|
||||
Curl_dyn_ptr(&sshc->readdir),
|
||||
Curl_dyn_len(&sshc->readdir));
|
||||
|
||||
@ -2335,14 +2329,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
|
||||
return CURLE_BAD_DOWNLOAD_RESUME;
|
||||
}
|
||||
if(conn->data->state.use_range) {
|
||||
if(data->state.use_range) {
|
||||
curl_off_t from, to;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
CURLofft to_t;
|
||||
CURLofft from_t;
|
||||
|
||||
from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
|
||||
from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
|
||||
if(from_t == CURL_OFFT_FLOW)
|
||||
return CURLE_RANGE_ERROR;
|
||||
while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
|
||||
@ -2503,7 +2497,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
|
||||
Curl_safefree(sshc->homedir);
|
||||
conn->data->state.most_recent_ftp_entrypath = NULL;
|
||||
data->state.most_recent_ftp_entrypath = NULL;
|
||||
|
||||
state(conn, SSH_SESSION_DISCONNECT);
|
||||
break;
|
||||
@ -2552,7 +2546,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0));
|
||||
failf(conn->data, "%s", err_msg);
|
||||
failf(data, "%s", err_msg);
|
||||
state(conn, SSH_SCP_CHANNEL_FREE);
|
||||
sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
|
||||
/* Map generic errors to upload failed */
|
||||
@ -2627,7 +2621,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0));
|
||||
failf(conn->data, "%s", err_msg);
|
||||
failf(data, "%s", err_msg);
|
||||
state(conn, SSH_SCP_CHANNEL_FREE);
|
||||
sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
|
||||
break;
|
||||
@ -2768,7 +2762,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
|
||||
Curl_safefree(sshc->homedir);
|
||||
conn->data->state.most_recent_ftp_entrypath = NULL;
|
||||
data->state.most_recent_ftp_entrypath = NULL;
|
||||
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
break;
|
||||
@ -2877,10 +2871,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
/* called by the multi interface to figure out what socket(s) to wait for and
|
||||
for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
|
||||
static int ssh_perform_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
static int ssh_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
{
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
(void)data;
|
||||
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
@ -2893,16 +2889,6 @@ static int ssh_perform_getsock(const struct connectdata *conn,
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/* Generic function called by the multi interface to figure out what socket(s)
|
||||
to wait for and for what actions during the DOING and PROTOCONNECT states*/
|
||||
static int ssh_getsock(struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
{
|
||||
/* if we know the direction we can use the generic *_getsock() function even
|
||||
for the protocol_connect and doing states */
|
||||
return ssh_perform_getsock(conn, sock);
|
||||
}
|
||||
|
||||
/*
|
||||
* When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
|
||||
* function is used to figure out in what direction and stores this info so
|
||||
@ -2929,14 +2915,15 @@ static void ssh_block2waitfor(struct connectdata *conn, bool block)
|
||||
}
|
||||
|
||||
/* called repeatedly until done from multi.c */
|
||||
static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
|
||||
static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
CURLcode result = CURLE_OK;
|
||||
bool block; /* we store the status and use that to provide a ssh_getsock()
|
||||
implementation */
|
||||
do {
|
||||
result = ssh_statemach_act(conn, &block);
|
||||
result = ssh_statemach_act(data, &block);
|
||||
*done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
|
||||
/* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
|
||||
try again */
|
||||
@ -2946,19 +2933,19 @@ static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode ssh_block_statemach(struct connectdata *conn,
|
||||
static CURLcode ssh_block_statemach(struct Curl_easy *data,
|
||||
bool duringconnect)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
while((sshc->state != SSH_STOP) && !result) {
|
||||
bool block;
|
||||
timediff_t left = 1000;
|
||||
struct curltime now = Curl_now();
|
||||
|
||||
result = ssh_statemach_act(conn, &block);
|
||||
result = ssh_statemach_act(data, &block);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@ -2996,11 +2983,13 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
|
||||
/*
|
||||
* SSH setup and connection
|
||||
*/
|
||||
static CURLcode ssh_setup_connection(struct connectdata *conn)
|
||||
static CURLcode ssh_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct SSHPROTO *ssh;
|
||||
(void)conn;
|
||||
|
||||
conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
|
||||
data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
|
||||
if(!ssh)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@ -3024,7 +3013,7 @@ static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer,
|
||||
/* swap in the TLS reader function for this call only, and then swap back
|
||||
the SSH one again */
|
||||
conn->recv[0] = ssh->tls_recv;
|
||||
result = Curl_read(conn, sock, buffer, length, &nread);
|
||||
result = Curl_read(conn->data, sock, buffer, length, &nread);
|
||||
conn->recv[0] = backup;
|
||||
if(result == CURLE_AGAIN)
|
||||
return -EAGAIN; /* magic return code for libssh2 */
|
||||
@ -3047,7 +3036,7 @@ static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer,
|
||||
/* swap in the TLS writer function for this call only, and then swap back
|
||||
the SSH one again */
|
||||
conn->send[0] = ssh->tls_send;
|
||||
result = Curl_write(conn, sock, buffer, length, &nwrite);
|
||||
result = Curl_write(conn->data, sock, buffer, length, &nwrite);
|
||||
conn->send[0] = backup;
|
||||
if(result == CURLE_AGAIN)
|
||||
return -EAGAIN; /* magic return code for libssh2 */
|
||||
@ -3062,18 +3051,18 @@ static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer,
|
||||
* Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
|
||||
* do protocol-specific actions at connect-time.
|
||||
*/
|
||||
static CURLcode ssh_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
#ifdef CURL_LIBSSH2_DEBUG
|
||||
curl_socket_t sock;
|
||||
#endif
|
||||
struct ssh_conn *ssh;
|
||||
CURLcode result;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
/* initialize per-handle data if not already */
|
||||
if(!data->req.p.ssh)
|
||||
ssh_setup_connection(conn);
|
||||
ssh_setup_connection(data, conn);
|
||||
|
||||
/* We default to persistent connections. We set this already in this connect
|
||||
function to make the re-use checks properly be able to check this bit. */
|
||||
@ -3187,7 +3176,7 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
state(conn, SSH_INIT);
|
||||
|
||||
result = ssh_multi_statemach(conn, done);
|
||||
result = ssh_multi_statemach(data, done);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -3202,13 +3191,14 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
|
||||
*/
|
||||
|
||||
static
|
||||
CURLcode scp_perform(struct connectdata *conn,
|
||||
bool *connected,
|
||||
bool *dophase_done)
|
||||
CURLcode scp_perform(struct Curl_easy *data,
|
||||
bool *connected,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
|
||||
*dophase_done = FALSE; /* not done yet */
|
||||
|
||||
@ -3216,7 +3206,7 @@ CURLcode scp_perform(struct connectdata *conn,
|
||||
state(conn, SSH_SCP_TRANS_INIT);
|
||||
|
||||
/* run the state-machine */
|
||||
result = ssh_multi_statemach(conn, dophase_done);
|
||||
result = ssh_multi_statemach(data, dophase_done);
|
||||
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
@ -3228,14 +3218,14 @@ CURLcode scp_perform(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
static CURLcode scp_doing(struct connectdata *conn,
|
||||
bool *dophase_done)
|
||||
static CURLcode scp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result;
|
||||
result = ssh_multi_statemach(conn, dophase_done);
|
||||
result = ssh_multi_statemach(data, dophase_done);
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -3245,11 +3235,11 @@ static CURLcode scp_doing(struct connectdata *conn,
|
||||
* separate ones but this way means less duplicated code.
|
||||
*/
|
||||
|
||||
static CURLcode ssh_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode ssh_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
bool connected = 0;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
@ -3266,9 +3256,9 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done)
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
|
||||
if(conn->handler->protocol & CURLPROTO_SCP)
|
||||
result = scp_perform(conn, &connected, done);
|
||||
result = scp_perform(data, &connected, done);
|
||||
else
|
||||
result = sftp_perform(conn, &connected, done);
|
||||
result = sftp_perform(data, &connected, done);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -3276,7 +3266,9 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done)
|
||||
/* BLOCKING, but the function is using the state machine so the only reason
|
||||
this is still blocking is that the multi interface code has no support for
|
||||
disconnecting operations that takes a while */
|
||||
static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
static CURLcode scp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct ssh_conn *ssh = &conn->proto.sshc;
|
||||
@ -3287,7 +3279,7 @@ static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
|
||||
state(conn, SSH_SESSION_DISCONNECT);
|
||||
|
||||
result = ssh_block_statemach(conn, FALSE);
|
||||
result = ssh_block_statemach(data, FALSE);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -3295,44 +3287,45 @@ static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
|
||||
/* generic done function for both SCP and SFTP called from their specific
|
||||
done functions */
|
||||
static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
|
||||
static CURLcode ssh_done(struct Curl_easy *data, CURLcode status)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SSHPROTO *sftp_scp = conn->data->req.p.ssh;
|
||||
struct SSHPROTO *sftp_scp = data->req.p.ssh;
|
||||
|
||||
if(!status) {
|
||||
/* run the state-machine */
|
||||
result = ssh_block_statemach(conn, FALSE);
|
||||
result = ssh_block_statemach(data, FALSE);
|
||||
}
|
||||
else
|
||||
result = status;
|
||||
|
||||
if(sftp_scp)
|
||||
Curl_safefree(sftp_scp->path);
|
||||
if(Curl_pgrsDone(conn))
|
||||
if(Curl_pgrsDone(data->conn))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
conn->data->req.keepon = 0; /* clear all bits */
|
||||
data->req.keepon = 0; /* clear all bits */
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode scp_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode scp_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
(void)premature; /* not used */
|
||||
|
||||
if(!status)
|
||||
state(conn, SSH_SCP_DONE);
|
||||
state(data->conn, SSH_SCP_DONE);
|
||||
|
||||
return ssh_done(conn, status);
|
||||
return ssh_done(data, status);
|
||||
|
||||
}
|
||||
|
||||
static ssize_t scp_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t scp_send(struct Curl_easy *data, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
ssize_t nwrite;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)sockindex; /* we only support SCP on the fixed known primary socket */
|
||||
|
||||
/* libssh2_channel_write() returns int! */
|
||||
@ -3353,10 +3346,11 @@ static ssize_t scp_send(struct connectdata *conn, int sockindex,
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
static ssize_t scp_recv(struct connectdata *conn, int sockindex,
|
||||
static ssize_t scp_recv(struct Curl_easy *data, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)sockindex; /* we only support SCP on the fixed known primary socket */
|
||||
|
||||
/* libssh2_channel_read() returns int */
|
||||
@ -3386,39 +3380,39 @@ static ssize_t scp_recv(struct connectdata *conn, int sockindex,
|
||||
*/
|
||||
|
||||
static
|
||||
CURLcode sftp_perform(struct connectdata *conn,
|
||||
CURLcode sftp_perform(struct Curl_easy *data,
|
||||
bool *connected,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
|
||||
*dophase_done = FALSE; /* not done yet */
|
||||
|
||||
/* start the first command in the DO phase */
|
||||
state(conn, SSH_SFTP_QUOTE_INIT);
|
||||
state(data->conn, SSH_SFTP_QUOTE_INIT);
|
||||
|
||||
/* run the state-machine */
|
||||
result = ssh_multi_statemach(conn, dophase_done);
|
||||
result = ssh_multi_statemach(data, dophase_done);
|
||||
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
*connected = data->conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
static CURLcode sftp_doing(struct connectdata *conn,
|
||||
static CURLcode sftp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = ssh_multi_statemach(conn, dophase_done);
|
||||
CURLcode result = ssh_multi_statemach(data, dophase_done);
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -3426,28 +3420,30 @@ static CURLcode sftp_doing(struct connectdata *conn,
|
||||
/* BLOCKING, but the function is using the state machine so the only reason
|
||||
this is still blocking is that the multi interface code has no support for
|
||||
disconnecting operations that takes a while */
|
||||
static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
static CURLcode sftp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead_connection)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
(void) dead_connection;
|
||||
|
||||
DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
|
||||
DEBUGF(infof(data, "SSH DISCONNECT starts now\n"));
|
||||
|
||||
if(conn->proto.sshc.ssh_session) {
|
||||
/* only if there's a session still around to use! */
|
||||
state(conn, SSH_SFTP_SHUTDOWN);
|
||||
result = ssh_block_statemach(conn, FALSE);
|
||||
result = ssh_block_statemach(data, FALSE);
|
||||
}
|
||||
|
||||
DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
|
||||
DEBUGF(infof(data, "SSH DISCONNECT is done\n"));
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
|
||||
static CURLcode sftp_done(struct Curl_easy *data, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
|
||||
if(!status) {
|
||||
@ -3458,16 +3454,15 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
|
||||
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
}
|
||||
return ssh_done(conn, status);
|
||||
return ssh_done(data, status);
|
||||
}
|
||||
|
||||
/* return number of sent bytes */
|
||||
static ssize_t sftp_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t sftp_send(struct Curl_easy *data, 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
|
||||
support libssh2 0.15*/
|
||||
ssize_t nwrite;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)sockindex;
|
||||
|
||||
nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
|
||||
@ -3490,10 +3485,11 @@ static ssize_t sftp_send(struct connectdata *conn, int sockindex,
|
||||
* Return number of received (decrypted) bytes
|
||||
* or <0 on error
|
||||
*/
|
||||
static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
|
||||
static ssize_t sftp_recv(struct Curl_easy *data, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)sockindex;
|
||||
|
||||
nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
|
||||
|
@ -45,27 +45,28 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static CURLcode wssh_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done);
|
||||
static CURLcode wssh_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode wssh_connect(struct Curl_easy *data, bool *done);
|
||||
static CURLcode wssh_multi_statemach(struct Curl_easy *data, bool *done);
|
||||
static CURLcode wssh_do(struct Curl_easy *data, bool *done);
|
||||
#if 0
|
||||
static CURLcode wscp_done(struct connectdata *conn,
|
||||
static CURLcode wscp_done(struct Curl_easy *data,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode wscp_doing(struct connectdata *conn,
|
||||
static CURLcode wscp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done);
|
||||
static CURLcode wscp_disconnect(struct connectdata *conn,
|
||||
static CURLcode wscp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool dead_connection);
|
||||
#endif
|
||||
static CURLcode wsftp_done(struct connectdata *conn,
|
||||
static CURLcode wsftp_done(struct Curl_easy *data,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode wsftp_doing(struct connectdata *conn,
|
||||
static CURLcode wsftp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done);
|
||||
static CURLcode wsftp_disconnect(struct connectdata *conn, bool dead);
|
||||
static CURLcode wsftp_disconnect(struct Curl_easy *data, bool dead);
|
||||
static int wssh_getsock(struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static int wssh_perform_getsock(const struct connectdata *conn,
|
||||
static int wssh_perform_getsock(struct connectdata *conn,
|
||||
curl_socket_t *sock);
|
||||
static CURLcode wssh_setup_connection(struct connectdata *conn);
|
||||
static CURLcode wssh_setup_connection(struct Curl_easy *data);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
@ -118,6 +119,7 @@ const struct Curl_handler Curl_handler_sftp = {
|
||||
ZERO_NULL, /* connection_check */
|
||||
PORT_SSH, /* defport */
|
||||
CURLPROTO_SFTP, /* protocol */
|
||||
CURLPROTO_SFTP, /* family */
|
||||
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
|
||||
| PROTOPT_NOURLQUERY /* flags */
|
||||
};
|
||||
@ -318,11 +320,11 @@ static ssize_t wsftp_recv(struct connectdata *conn, int sockindex,
|
||||
/*
|
||||
* SSH setup and connection
|
||||
*/
|
||||
static CURLcode wssh_setup_connection(struct connectdata *conn)
|
||||
static CURLcode wssh_setup_connection(struct Curl_easy *data)
|
||||
{
|
||||
struct SSHPROTO *ssh;
|
||||
|
||||
conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
|
||||
data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
|
||||
if(!ssh)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@ -348,16 +350,16 @@ static int userauth(byte authtype,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CURLcode wssh_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode wssh_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
int rc;
|
||||
|
||||
/* initialize per-handle data if not already */
|
||||
if(!data->req.p.ssh)
|
||||
wssh_setup_connection(conn);
|
||||
wssh_setup_connection(data);
|
||||
|
||||
/* We default to persistent connections. We set this already in this connect
|
||||
function to make the re-use checks properly be able to check this bit. */
|
||||
@ -410,7 +412,7 @@ static CURLcode wssh_connect(struct connectdata *conn, bool *done)
|
||||
else
|
||||
state(conn, SSH_SFTP_INIT);
|
||||
|
||||
return wssh_multi_statemach(conn, done);
|
||||
return wssh_multi_statemach(data, done);
|
||||
error:
|
||||
wolfSSH_free(sshc->ssh_session);
|
||||
wolfSSH_CTX_free(sshc->ctx);
|
||||
@ -424,11 +426,11 @@ static CURLcode wssh_connect(struct connectdata *conn, bool *done)
|
||||
* wants to be called again when the socket is ready
|
||||
*/
|
||||
|
||||
static CURLcode wssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct SSHPROTO *sftp_scp = data->req.p.ssh;
|
||||
WS_SFTPNAME *name;
|
||||
int rc = 0;
|
||||
@ -762,7 +764,7 @@ static CURLcode wssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
/* We cannot seek with wolfSSH so resuming and range requests are not
|
||||
possible */
|
||||
if(conn->data->state.use_range || data->state.resume_from) {
|
||||
if(data->state.use_range || data->state.resume_from) {
|
||||
infof(data, "wolfSSH cannot do range/seek on SFTP\n");
|
||||
return CURLE_BAD_DOWNLOAD_RESUME;
|
||||
}
|
||||
@ -887,19 +889,20 @@ static CURLcode wssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
|
||||
/* called repeatedly until done from multi.c */
|
||||
static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done)
|
||||
static CURLcode wssh_multi_statemach(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
CURLcode result = CURLE_OK;
|
||||
bool block; /* we store the status and use that to provide a ssh_getsock()
|
||||
implementation */
|
||||
do {
|
||||
result = wssh_statemach_act(conn, &block);
|
||||
result = wssh_statemach_act(data, &block);
|
||||
*done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
|
||||
/* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
|
||||
try again */
|
||||
if(*done) {
|
||||
DEBUGF(infof(conn->data, "wssh_statemach_act says DONE\n"));
|
||||
DEBUGF(infof(data, "wssh_statemach_act says DONE\n"));
|
||||
}
|
||||
} while(!result && !*done && !block);
|
||||
|
||||
@ -907,24 +910,25 @@ static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
static
|
||||
CURLcode wscp_perform(struct connectdata *conn,
|
||||
CURLcode wscp_perform(struct Curl_easy *data,
|
||||
bool *connected,
|
||||
bool *dophase_done)
|
||||
{
|
||||
(void)conn;
|
||||
(void)data;
|
||||
(void)connected;
|
||||
(void)dophase_done;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static
|
||||
CURLcode wsftp_perform(struct connectdata *conn,
|
||||
CURLcode wsftp_perform(struct Curl_easy *data,
|
||||
bool *connected,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||
DEBUGF(infof(data, "DO phase starts\n"));
|
||||
|
||||
*dophase_done = FALSE; /* not done yet */
|
||||
|
||||
@ -932,12 +936,12 @@ CURLcode wsftp_perform(struct connectdata *conn,
|
||||
state(conn, SSH_SFTP_QUOTE_INIT);
|
||||
|
||||
/* run the state-machine */
|
||||
result = wssh_multi_statemach(conn, dophase_done);
|
||||
result = wssh_multi_statemach(data, dophase_done);
|
||||
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -946,11 +950,11 @@ CURLcode wsftp_perform(struct connectdata *conn,
|
||||
/*
|
||||
* The DO function is generic for both protocols.
|
||||
*/
|
||||
static CURLcode wssh_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode wssh_do(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
bool connected = 0;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
@ -965,26 +969,26 @@ static CURLcode wssh_do(struct connectdata *conn, bool *done)
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
|
||||
if(conn->handler->protocol & CURLPROTO_SCP)
|
||||
result = wscp_perform(conn, &connected, done);
|
||||
result = wscp_perform(data, &connected, done);
|
||||
else
|
||||
result = wsftp_perform(conn, &connected, done);
|
||||
result = wsftp_perform(data, &connected, done);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode wssh_block_statemach(struct connectdata *conn,
|
||||
static CURLcode wssh_block_statemach(struct Curl_easy *data,
|
||||
bool disconnect)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
while((sshc->state != SSH_STOP) && !result) {
|
||||
bool block;
|
||||
timediff_t left = 1000;
|
||||
struct curltime now = Curl_now();
|
||||
|
||||
result = wssh_statemach_act(conn, &block);
|
||||
result = wssh_statemach_act(data, &block);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
@ -1024,14 +1028,15 @@ static CURLcode wssh_block_statemach(struct connectdata *conn,
|
||||
|
||||
/* generic done function for both SCP and SFTP called from their specific
|
||||
done functions */
|
||||
static CURLcode wssh_done(struct connectdata *conn, CURLcode status)
|
||||
static CURLcode wssh_done(struct Curl_easy *data, CURLcode status)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SSHPROTO *sftp_scp = conn->data->req.p.ssh;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct SSHPROTO *sftp_scp = data->req.p.ssh;
|
||||
|
||||
if(!status) {
|
||||
/* run the state-machine */
|
||||
result = wssh_block_statemach(conn, FALSE);
|
||||
result = wssh_block_statemach(data, FALSE);
|
||||
}
|
||||
else
|
||||
result = status;
|
||||
@ -1041,12 +1046,12 @@ static CURLcode wssh_done(struct connectdata *conn, CURLcode status)
|
||||
if(Curl_pgrsDone(conn))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
conn->data->req.keepon = 0; /* clear all bits */
|
||||
data->req.keepon = 0; /* clear all bits */
|
||||
return result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static CURLcode wscp_done(struct connectdata *conn,
|
||||
static CURLcode wscp_done(struct Curl_easy *data,
|
||||
CURLcode code, bool premature)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -1057,7 +1062,7 @@ static CURLcode wscp_done(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode wscp_doing(struct connectdata *conn,
|
||||
static CURLcode wscp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -1067,9 +1072,11 @@ static CURLcode wscp_doing(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode wscp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
static CURLcode wscp_disconnect(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool dead_connection)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
(void)data;
|
||||
(void)conn;
|
||||
(void)dead_connection;
|
||||
|
||||
@ -1077,40 +1084,41 @@ static CURLcode wscp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode wsftp_done(struct connectdata *conn,
|
||||
static CURLcode wsftp_done(struct Curl_easy *data,
|
||||
CURLcode code, bool premature)
|
||||
{
|
||||
(void)premature;
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
state(data->conn, SSH_SFTP_CLOSE);
|
||||
|
||||
return wssh_done(conn, code);
|
||||
return wssh_done(data, code);
|
||||
}
|
||||
|
||||
static CURLcode wsftp_doing(struct connectdata *conn,
|
||||
static CURLcode wsftp_doing(struct Curl_easy *data,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result = wssh_multi_statemach(conn, dophase_done);
|
||||
CURLcode result = wssh_multi_statemach(data, dophase_done);
|
||||
|
||||
if(*dophase_done) {
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
DEBUGF(infof(data, "DO phase is complete\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode wsftp_disconnect(struct connectdata *conn, bool dead)
|
||||
static CURLcode wsftp_disconnect(struct Curl_easy *data, bool dead)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)dead;
|
||||
|
||||
DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
|
||||
DEBUGF(infof(data, "SSH DISCONNECT starts now\n"));
|
||||
|
||||
if(conn->proto.sshc.ssh_session) {
|
||||
/* only if there's a session still around to use! */
|
||||
state(conn, SSH_SFTP_SHUTDOWN);
|
||||
result = wssh_block_statemach(conn, TRUE);
|
||||
result = wssh_block_statemach(data, TRUE);
|
||||
}
|
||||
|
||||
DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
|
||||
DEBUGF(infof(data, "SSH DISCONNECT is done\n"));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1120,7 +1128,7 @@ static int wssh_getsock(struct connectdata *conn,
|
||||
return wssh_perform_getsock(conn, sock);
|
||||
}
|
||||
|
||||
static int wssh_perform_getsock(const struct connectdata *conn,
|
||||
static int wssh_perform_getsock(struct connectdata *conn,
|
||||
curl_socket_t *sock)
|
||||
{
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
|
@ -552,7 +552,7 @@ static CURLcode bearssl_connect_step3(struct connectdata *conn, int sockindex)
|
||||
conn->negnpn = CURL_HTTP_VERSION_1_1;
|
||||
else
|
||||
infof(data, "ALPN, unrecognized protocol %s\n", protocol);
|
||||
Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
|
||||
}
|
||||
else
|
||||
@ -585,10 +585,10 @@ static CURLcode bearssl_connect_step3(struct connectdata *conn, int sockindex)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static ssize_t bearssl_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t bearssl_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t len, CURLcode *err)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
unsigned char *app;
|
||||
@ -618,9 +618,10 @@ static ssize_t bearssl_send(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t bearssl_recv(struct connectdata *conn, int sockindex,
|
||||
static ssize_t bearssl_recv(struct Curl_easy *data, int sockindex,
|
||||
char *buf, size_t len, CURLcode *err)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
unsigned char *app;
|
||||
|
148
lib/vtls/gskit.c
148
lib/vtls/gskit.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -301,10 +301,9 @@ static CURLcode set_callback(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
|
||||
static CURLcode set_ciphers(struct connectdata *conn,
|
||||
static CURLcode set_ciphers(struct Curl_easy *data,
|
||||
gsk_handle h, unsigned int *protoflags)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
|
||||
const char *clp;
|
||||
const struct gskit_cipher *ctp;
|
||||
@ -435,7 +434,7 @@ static CURLcode set_ciphers(struct connectdata *conn,
|
||||
}
|
||||
|
||||
|
||||
static int Curl_gskit_init(void)
|
||||
static int gskit_init(void)
|
||||
{
|
||||
/* No initialisation needed. */
|
||||
|
||||
@ -443,7 +442,7 @@ static int Curl_gskit_init(void)
|
||||
}
|
||||
|
||||
|
||||
static void Curl_gskit_cleanup(void)
|
||||
static void gskit_cleanup(void)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
@ -587,11 +586,11 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
|
||||
static void close_one(struct ssl_connect_data *connssl,
|
||||
static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
|
||||
struct connectdata *conn, int sockindex)
|
||||
{
|
||||
if(BACKEND->handle) {
|
||||
gskit_status(conn->data, gsk_secure_soc_close(&BACKEND->handle),
|
||||
gskit_status(data, gsk_secure_soc_close(&BACKEND->handle),
|
||||
"gsk_secure_soc_close()", 0);
|
||||
/* Last chance to drain output. */
|
||||
while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
|
||||
@ -611,11 +610,11 @@ static void close_one(struct ssl_connect_data *connssl,
|
||||
}
|
||||
|
||||
|
||||
static ssize_t gskit_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *curlcode)
|
||||
static ssize_t real_gskit_send(struct Curl_easy *data,
|
||||
struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode cc = CURLE_SEND_ERROR;
|
||||
int written;
|
||||
|
||||
@ -635,12 +634,18 @@ static ssize_t gskit_send(struct connectdata *conn, int sockindex,
|
||||
return (ssize_t) written; /* number of bytes */
|
||||
}
|
||||
|
||||
static ssize_t gskit_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *curlcode)
|
||||
{
|
||||
return real_gskit_send(conn->data, conn, sockindex, mem, len, curlcode);
|
||||
}
|
||||
|
||||
static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
||||
size_t buffersize, CURLcode *curlcode)
|
||||
|
||||
static ssize_t real_gskit_recv(struct Curl_easy *data,
|
||||
struct connectdata *conn, int num, char *buf,
|
||||
size_t buffersize, CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
struct Curl_easy *data = conn->data;
|
||||
int nread;
|
||||
CURLcode cc = CURLE_RECV_ERROR;
|
||||
|
||||
@ -663,10 +668,15 @@ static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
||||
return (ssize_t) nread;
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn)
|
||||
static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
||||
size_t buffersize, CURLcode *curlcode)
|
||||
{
|
||||
return real_gskit_recv(conn->data, conn, num, buf, buffersize, curlcode);
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
set_ssl_version_min_max(unsigned int *protoflags, struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
long ssl_version = SSL_CONN_CONFIG(version);
|
||||
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||
long i = ssl_version;
|
||||
@ -696,9 +706,9 @@ set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
static CURLcode gskit_connect_step1(struct Curl_easy *data,
|
||||
struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
gsk_handle envir;
|
||||
CURLcode result;
|
||||
@ -798,7 +808,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
result = set_ssl_version_min_max(&protoflags, conn);
|
||||
result = set_ssl_version_min_max(&protoflags, data);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
break;
|
||||
@ -832,7 +842,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0?
|
||||
BACKEND->localfd: conn->sock[sockindex]);
|
||||
if(!result)
|
||||
result = set_ciphers(conn, BACKEND->handle, &protoflags);
|
||||
result = set_ciphers(data, BACKEND->handle, &protoflags);
|
||||
if(!protoflags) {
|
||||
failf(data, "No SSL protocol/cipher combination enabled");
|
||||
result = CURLE_SSL_CIPHER;
|
||||
@ -915,15 +925,15 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* Error: rollback. */
|
||||
close_one(connssl, conn, sockindex);
|
||||
close_one(connssl, data, conn, sockindex);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
|
||||
static CURLcode gskit_connect_step2(struct Curl_easy *data,
|
||||
struct connectdata *conn, int sockindex,
|
||||
bool nonblocking)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
Qso_OverlappedIO_t cstat;
|
||||
struct timeval stmv;
|
||||
@ -971,9 +981,9 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
|
||||
static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
|
||||
static CURLcode gskit_connect_step3(struct Curl_easy *data,
|
||||
struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
const gsk_cert_data_elem *cdev;
|
||||
int cdec;
|
||||
@ -1016,7 +1026,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* Verify host. */
|
||||
result = Curl_verifyhost(conn, cert, certend);
|
||||
result = Curl_verifyhost(data, conn, cert, certend);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -1031,7 +1041,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
|
||||
return result;
|
||||
|
||||
if(cert) {
|
||||
result = Curl_extract_certinfo(conn, 0, cert, certend);
|
||||
result = Curl_extract_certinfo(data, 0, cert, certend);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -1059,10 +1069,10 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
|
||||
static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
|
||||
static CURLcode gskit_connect_common(struct Curl_easy *data,
|
||||
struct connectdata *conn, int sockindex,
|
||||
bool nonblocking, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
timediff_t timeout_ms;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -1082,7 +1092,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else
|
||||
result = gskit_connect_step1(conn, sockindex);
|
||||
result = gskit_connect_step1(data, conn, sockindex);
|
||||
}
|
||||
|
||||
/* Handle handshake pipelining. */
|
||||
@ -1101,7 +1111,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else
|
||||
result = gskit_connect_step2(conn, sockindex, nonblocking);
|
||||
result = gskit_connect_step2(data, conn, sockindex, nonblocking);
|
||||
}
|
||||
|
||||
/* Handle handshake pipelining. */
|
||||
@ -1111,10 +1121,10 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
|
||||
|
||||
/* Step 3: gather certificate info, verify host. */
|
||||
if(!result && connssl->connecting_state == ssl_connect_3)
|
||||
result = gskit_connect_step3(conn, sockindex);
|
||||
result = gskit_connect_step3(data, conn, sockindex);
|
||||
|
||||
if(result)
|
||||
close_one(connssl, conn, sockindex);
|
||||
close_one(connssl, data, conn, sockindex);
|
||||
else if(connssl->connecting_state == ssl_connect_done) {
|
||||
connssl->state = ssl_connection_complete;
|
||||
connssl->connecting_state = ssl_connect_1;
|
||||
@ -1127,25 +1137,33 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
|
||||
static CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
|
||||
static CURLcode real_gskit_connect_nonblocking(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
result = gskit_connect_common(conn, sockindex, TRUE, done);
|
||||
result = gskit_connect_common(data, conn, sockindex, TRUE, done);
|
||||
if(*done || result)
|
||||
conn->ssl[sockindex].connecting_state = ssl_connect_1;
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode gskit_connect_nonblocking(struct connectdata *conn,
|
||||
int sockindex, bool *done)
|
||||
{
|
||||
return real_gskit_connect_nonblocking(conn->data, conn, sockindex, done);
|
||||
}
|
||||
|
||||
static CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
|
||||
|
||||
static CURLcode real_gskit_connect(struct Curl_easy *data,
|
||||
struct connectdata *conn, int sockindex)
|
||||
{
|
||||
CURLcode result;
|
||||
bool done;
|
||||
|
||||
conn->ssl[sockindex].connecting_state = ssl_connect_1;
|
||||
result = gskit_connect_common(conn, sockindex, FALSE, &done);
|
||||
result = gskit_connect_common(data, conn, sockindex, FALSE, &done);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -1154,18 +1172,29 @@ static CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
static void Curl_gskit_close(struct connectdata *conn, int sockindex)
|
||||
static CURLcode gskit_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
close_one(&conn->ssl[sockindex], conn, sockindex);
|
||||
close_one(&conn->proxy_ssl[sockindex], conn, sockindex);
|
||||
return real_gskit_connect(conn->data, conn, sockindex);
|
||||
}
|
||||
|
||||
|
||||
static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||
static void real_gskit_close(struct Curl_easy *data, struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
close_one(&conn->ssl[sockindex], data, conn, sockindex);
|
||||
close_one(&conn->proxy_ssl[sockindex], data, conn, sockindex);
|
||||
}
|
||||
|
||||
static void gskit_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
real_gskit_close(conn->data, conn, sockindex);
|
||||
}
|
||||
|
||||
|
||||
static int real_gskit_shutdown(struct Curl_easy *data,
|
||||
struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct Curl_easy *data = conn->data;
|
||||
int what;
|
||||
int rc;
|
||||
char buf[120];
|
||||
@ -1178,7 +1207,7 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
close_one(connssl, conn, sockindex);
|
||||
close_one(connssl, data, conn, sockindex);
|
||||
rc = 0;
|
||||
what = SOCKET_READABLE(conn->sock[sockindex],
|
||||
SSL_SHUTDOWN_TIMEOUT);
|
||||
@ -1218,14 +1247,19 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
return real_gskit_shutdown(conn->data, conn, sockindex);
|
||||
}
|
||||
|
||||
static size_t Curl_gskit_version(char *buffer, size_t size)
|
||||
|
||||
static size_t gskit_version(char *buffer, size_t size)
|
||||
{
|
||||
return msnprintf(buffer, size, "GSKit");
|
||||
}
|
||||
|
||||
|
||||
static int Curl_gskit_check_cxn(struct connectdata *cxn)
|
||||
static int gskit_check_cxn(struct connectdata *cxn)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &cxn->ssl[FIRSTSOCKET];
|
||||
int err;
|
||||
@ -1247,8 +1281,8 @@ static int Curl_gskit_check_cxn(struct connectdata *cxn)
|
||||
return -1; /* connection status unknown */
|
||||
}
|
||||
|
||||
static void *Curl_gskit_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
static void *gskit_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return BACKEND->handle;
|
||||
@ -1262,18 +1296,18 @@ const struct Curl_ssl Curl_ssl_gskit = {
|
||||
|
||||
sizeof(struct ssl_backend_data),
|
||||
|
||||
Curl_gskit_init, /* init */
|
||||
Curl_gskit_cleanup, /* cleanup */
|
||||
Curl_gskit_version, /* version */
|
||||
Curl_gskit_check_cxn, /* check_cxn */
|
||||
Curl_gskit_shutdown, /* shutdown */
|
||||
gskit_init, /* init */
|
||||
gskit_cleanup, /* cleanup */
|
||||
gskit_version, /* version */
|
||||
gskit_check_cxn, /* check_cxn */
|
||||
gskit_shutdown, /* shutdown */
|
||||
Curl_none_data_pending, /* data_pending */
|
||||
Curl_none_random, /* random */
|
||||
Curl_none_cert_status_request, /* cert_status_request */
|
||||
Curl_gskit_connect, /* connect */
|
||||
Curl_gskit_connect_nonblocking, /* connect_nonblocking */
|
||||
Curl_gskit_get_internals, /* get_internals */
|
||||
Curl_gskit_close, /* close_one */
|
||||
gskit_connect, /* connect */
|
||||
gskit_connect_nonblocking, /* connect_nonblocking */
|
||||
gskit_get_internals, /* get_internals */
|
||||
gskit_close, /* close_one */
|
||||
Curl_none_close_all, /* close_all */
|
||||
/* No session handling for GSKit */
|
||||
Curl_none_session_free, /* session_free */
|
||||
|
@ -885,7 +885,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
const char *beg = (const char *) chainp[i].data;
|
||||
const char *end = beg + chainp[i].size;
|
||||
|
||||
result = Curl_extract_certinfo(conn, i, beg, end);
|
||||
result = Curl_extract_certinfo(data, i, beg, end);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@ -1263,7 +1263,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
else
|
||||
infof(data, "ALPN, server did not agree to a protocol\n");
|
||||
|
||||
Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
|
||||
}
|
||||
|
||||
@ -1399,12 +1399,13 @@ static bool gtls_data_pending(const struct connectdata *conn,
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t gtls_send(struct connectdata *conn,
|
||||
static ssize_t gtls_send(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
ssize_t rc = gnutls_record_send(backend->session, mem, len);
|
||||
@ -1526,12 +1527,13 @@ static int gtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
|
||||
static ssize_t gtls_recv(struct Curl_easy *data, /* connection data */
|
||||
int num, /* socketindex */
|
||||
char *buf, /* store read data here */
|
||||
size_t buffersize, /* max amount to read */
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
ssize_t ret;
|
||||
|
@ -5,8 +5,8 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -701,7 +701,7 @@ mbed_connect_step2(struct connectdata *conn,
|
||||
else {
|
||||
infof(data, "ALPN, server did not agree to a protocol\n");
|
||||
}
|
||||
Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
|
||||
}
|
||||
#endif
|
||||
@ -763,16 +763,16 @@ mbed_connect_step3(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static ssize_t mbed_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t mbed_send(struct Curl_easy *data, int sockindex,
|
||||
const void *mem, size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
int ret = -1;
|
||||
|
||||
ret = mbedtls_ssl_write(&backend->ssl,
|
||||
(unsigned char *)mem, len);
|
||||
ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len);
|
||||
|
||||
if(ret < 0) {
|
||||
*curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ?
|
||||
@ -804,16 +804,16 @@ static void mbedtls_close(struct connectdata *conn, int sockindex)
|
||||
#endif /* THREADING_SUPPORT */
|
||||
}
|
||||
|
||||
static ssize_t mbed_recv(struct connectdata *conn, int num,
|
||||
static ssize_t mbed_recv(struct Curl_easy *data, int num,
|
||||
char *buf, size_t buffersize,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
int ret = -1;
|
||||
ssize_t len = -1;
|
||||
|
||||
memset(buf, 0, buffersize);
|
||||
ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
|
||||
buffersize);
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -378,9 +378,10 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
mesalink_send(struct connectdata *conn, int sockindex, const void *mem,
|
||||
mesalink_send(struct Curl_easy *data, int sockindex, const void *mem,
|
||||
size_t len, CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
char error_buffer[MESALINK_MAX_ERROR_SZ];
|
||||
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
|
||||
@ -395,7 +396,7 @@ mesalink_send(struct connectdata *conn, int sockindex, const void *mem,
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1;
|
||||
default:
|
||||
failf(conn->data,
|
||||
failf(data,
|
||||
"SSL write: %s, errno %d",
|
||||
ERR_error_string_n(err, error_buffer, sizeof(error_buffer)),
|
||||
SOCKERRNO);
|
||||
@ -423,9 +424,10 @@ Curl_mesalink_close(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
mesalink_recv(struct connectdata *conn, int num, char *buf, size_t buffersize,
|
||||
mesalink_recv(struct Curl_easy *data, int num, char *buf, size_t buffersize,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
char error_buffer[MESALINK_MAX_ERROR_SZ];
|
||||
int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
|
||||
@ -444,7 +446,7 @@ mesalink_recv(struct connectdata *conn, int num, char *buf, size_t buffersize,
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1;
|
||||
default:
|
||||
failf(conn->data,
|
||||
failf(data,
|
||||
"SSL read: %s, errno %d",
|
||||
ERR_error_string_n(err, error_buffer, sizeof(error_buffer)),
|
||||
SOCKERRNO);
|
||||
|
@ -814,6 +814,7 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
|
||||
static void HandshakeCallback(PRFileDesc *sock, void *arg)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata*) arg;
|
||||
struct Curl_easy *data = conn->data;
|
||||
unsigned int buflenmax = 50;
|
||||
unsigned char buf[50];
|
||||
unsigned int buflen;
|
||||
@ -833,15 +834,15 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
|
||||
#endif
|
||||
case SSL_NEXT_PROTO_NO_SUPPORT:
|
||||
case SSL_NEXT_PROTO_NO_OVERLAP:
|
||||
infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n");
|
||||
infof(data, "ALPN/NPN, server did not agree to a protocol\n");
|
||||
return;
|
||||
#ifdef SSL_ENABLE_ALPN
|
||||
case SSL_NEXT_PROTO_SELECTED:
|
||||
infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf);
|
||||
infof(data, "ALPN, server accepted to use %.*s\n", buflen, buf);
|
||||
break;
|
||||
#endif
|
||||
case SSL_NEXT_PROTO_NEGOTIATED:
|
||||
infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf);
|
||||
infof(data, "NPN, server accepted to use %.*s\n", buflen, buf);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -856,7 +857,7 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
|
||||
!memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
|
||||
conn->negnpn = CURL_HTTP_VERSION_1_1;
|
||||
}
|
||||
Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
Curl_multiuse_state(conn->data, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
|
||||
}
|
||||
}
|
||||
@ -952,6 +953,7 @@ static void display_cert_info(struct Curl_easy *data,
|
||||
static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
SSLChannelInfo channel;
|
||||
SSLCipherSuiteInfo suite;
|
||||
CERTCertificate *cert;
|
||||
@ -965,16 +967,16 @@ static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
|
||||
channel.cipherSuite) {
|
||||
if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
|
||||
&suite, sizeof(suite)) == SECSuccess) {
|
||||
infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName);
|
||||
infof(data, "SSL connection using %s\n", suite.cipherSuiteName);
|
||||
}
|
||||
}
|
||||
|
||||
cert = SSL_PeerCertificate(sock);
|
||||
if(cert) {
|
||||
infof(conn->data, "Server certificate:\n");
|
||||
infof(data, "Server certificate:\n");
|
||||
|
||||
if(!conn->data->set.ssl.certinfo) {
|
||||
display_cert_info(conn->data, cert);
|
||||
if(!data->set.ssl.certinfo) {
|
||||
display_cert_info(data, cert);
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
else {
|
||||
@ -995,10 +997,10 @@ static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
|
||||
}
|
||||
}
|
||||
|
||||
result = Curl_ssl_init_certinfo(conn->data, i);
|
||||
result = Curl_ssl_init_certinfo(data, i);
|
||||
if(!result) {
|
||||
for(i = 0; cert; cert = cert2) {
|
||||
result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
|
||||
result = Curl_extract_certinfo(data, i++, (char *)cert->derCert.data,
|
||||
(char *)cert->derCert.data +
|
||||
cert->derCert.len);
|
||||
if(result)
|
||||
@ -2260,19 +2262,20 @@ static CURLcode nss_connect_nonblocking(struct connectdata *conn,
|
||||
return nss_connect_common(conn, sockindex, done);
|
||||
}
|
||||
|
||||
static ssize_t nss_send(struct connectdata *conn, /* connection data */
|
||||
static ssize_t nss_send(struct Curl_easy *data, /* transfer */
|
||||
int sockindex, /* socketindex */
|
||||
const void *mem, /* send this data */
|
||||
size_t len, /* amount to write */
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
ssize_t rc;
|
||||
|
||||
/* The SelectClientCert() hook uses this for infof() and failf() but the
|
||||
handle stored in nss_setup_connect() could have already been freed. */
|
||||
backend->data = conn->data;
|
||||
backend->data = data;
|
||||
|
||||
rc = PR_Send(backend->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
|
||||
if(rc < 0) {
|
||||
@ -2282,7 +2285,7 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */
|
||||
else {
|
||||
/* print the error number and error string */
|
||||
const char *err_name = nss_error_to_name(err);
|
||||
infof(conn->data, "SSL write: error %d (%s)\n", err, err_name);
|
||||
infof(data, "SSL write: error %d (%s)\n", err, err_name);
|
||||
|
||||
/* print a human-readable message describing the error if available */
|
||||
nss_print_error_message(conn->data, err);
|
||||
@ -2298,19 +2301,20 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */
|
||||
return rc; /* number of bytes */
|
||||
}
|
||||
|
||||
static ssize_t nss_recv(struct connectdata *conn, /* connection data */
|
||||
static ssize_t nss_recv(struct Curl_easy *data, /* transfer */
|
||||
int sockindex, /* socketindex */
|
||||
char *buf, /* store read data here */
|
||||
size_t buffersize, /* max amount to read */
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
ssize_t nread;
|
||||
|
||||
/* The SelectClientCert() hook uses this for infof() and failf() but the
|
||||
handle stored in nss_setup_connect() could have already been freed. */
|
||||
backend->data = conn->data;
|
||||
backend->data = data;
|
||||
|
||||
nread = PR_Recv(backend->handle, buf, (int)buffersize, 0,
|
||||
PR_INTERVAL_NO_WAIT);
|
||||
@ -2323,7 +2327,7 @@ static ssize_t nss_recv(struct connectdata *conn, /* connection data */
|
||||
else {
|
||||
/* print the error number and error string */
|
||||
const char *err_name = nss_error_to_name(err);
|
||||
infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name);
|
||||
infof(data, "SSL read: errno %d (%s)\n", err, err_name);
|
||||
|
||||
/* print a human-readable message describing the error if available */
|
||||
nss_print_error_message(conn->data, err);
|
||||
|
@ -1433,7 +1433,7 @@ static int ossl_shutdown(struct connectdata *conn, int sockindex)
|
||||
default:
|
||||
/* openssl/ssl.h says "look at error stack/return value/errno" */
|
||||
sslerror = ERR_get_error();
|
||||
failf(conn->data, OSSL_PACKAGE " SSL_read on shutdown: %s, errno %d",
|
||||
failf(data, OSSL_PACKAGE " SSL_read on shutdown: %s, errno %d",
|
||||
(sslerror ?
|
||||
ossl_strerror(sslerror, buf, sizeof(buf)) :
|
||||
SSL_ERROR_to_str(err)),
|
||||
@ -2206,15 +2206,15 @@ select_next_proto_cb(SSL *ssl,
|
||||
const unsigned char *in, unsigned int inlen,
|
||||
void *arg)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata*) arg;
|
||||
|
||||
struct Curl_easy *data = (struct Curl_easy *)arg;
|
||||
struct connectdata *conn = data->conn;
|
||||
(void)ssl;
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(conn->data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
!select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
|
||||
NGHTTP2_PROTO_VERSION_ID_LEN)) {
|
||||
infof(conn->data, "NPN, negotiated HTTP2 (%s)\n",
|
||||
infof(data, "NPN, negotiated HTTP2 (%s)\n",
|
||||
NGHTTP2_PROTO_VERSION_ID);
|
||||
conn->negnpn = CURL_HTTP_VERSION_2;
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
@ -2223,12 +2223,12 @@ select_next_proto_cb(SSL *ssl,
|
||||
|
||||
if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1,
|
||||
ALPN_HTTP_1_1_LENGTH)) {
|
||||
infof(conn->data, "NPN, negotiated HTTP1.1\n");
|
||||
infof(data, "NPN, negotiated HTTP1.1\n");
|
||||
conn->negnpn = CURL_HTTP_VERSION_1_1;
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
infof(conn->data, "NPN, no overlap, use HTTP1.1\n");
|
||||
infof(data, "NPN, no overlap, use HTTP1.1\n");
|
||||
*out = (unsigned char *)ALPN_HTTP_1_1;
|
||||
*outlen = ALPN_HTTP_1_1_LENGTH;
|
||||
conn->negnpn = CURL_HTTP_VERSION_1_1;
|
||||
@ -2729,7 +2729,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
|
||||
#ifdef HAS_NPN
|
||||
if(conn->bits.tls_enable_npn)
|
||||
SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, conn);
|
||||
SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, data);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
@ -3385,7 +3385,7 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
else
|
||||
infof(data, "ALPN, server did not agree to a protocol\n");
|
||||
|
||||
Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
|
||||
}
|
||||
#endif
|
||||
@ -4130,7 +4130,7 @@ static bool ossl_data_pending(const struct connectdata *conn,
|
||||
|
||||
static size_t ossl_version(char *buffer, size_t size);
|
||||
|
||||
static ssize_t ossl_send(struct connectdata *conn,
|
||||
static ssize_t ossl_send(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
@ -4143,6 +4143,7 @@ static ssize_t ossl_send(struct connectdata *conn,
|
||||
unsigned long sslerror;
|
||||
int memlen;
|
||||
int rc;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
|
||||
@ -4174,7 +4175,7 @@ static ssize_t ossl_send(struct connectdata *conn,
|
||||
strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer));
|
||||
error_buffer[sizeof(error_buffer) - 1] = '\0';
|
||||
}
|
||||
failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d",
|
||||
failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
|
||||
error_buffer, sockerr);
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
@ -4192,17 +4193,16 @@ static ssize_t ossl_send(struct connectdata *conn,
|
||||
) {
|
||||
char ver[120];
|
||||
ossl_version(ver, 120);
|
||||
failf(conn->data, "Error: %s does not support double SSL tunneling.",
|
||||
ver);
|
||||
failf(data, "Error: %s does not support double SSL tunneling.", ver);
|
||||
}
|
||||
else
|
||||
failf(conn->data, "SSL_write() error: %s",
|
||||
failf(data, "SSL_write() error: %s",
|
||||
ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
/* a true error */
|
||||
failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d",
|
||||
failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
|
||||
SSL_ERROR_to_str(err), SOCKERRNO);
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
@ -4211,7 +4211,7 @@ static ssize_t ossl_send(struct connectdata *conn,
|
||||
return (ssize_t)rc; /* number of bytes */
|
||||
}
|
||||
|
||||
static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
|
||||
static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
|
||||
int num, /* socketindex */
|
||||
char *buf, /* store read data here */
|
||||
size_t buffersize, /* max amount to read */
|
||||
@ -4221,6 +4221,7 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
|
||||
unsigned long sslerror;
|
||||
ssize_t nread;
|
||||
int buffsize;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
|
||||
|
@ -5,9 +5,9 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
|
||||
* Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
|
||||
* Copyright (C) 2012 - 2020, 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
|
||||
@ -956,7 +956,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
"sending %lu bytes...\n", outbuf.cbBuffer));
|
||||
|
||||
/* send initial handshake data which is now stored in output buffer */
|
||||
result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
|
||||
result = Curl_write_plain(data, conn->sock[sockindex], outbuf.pvBuffer,
|
||||
outbuf.cbBuffer, &written);
|
||||
s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
|
||||
if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
|
||||
@ -1153,7 +1153,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
"sending %lu bytes...\n", outbuf[i].cbBuffer));
|
||||
|
||||
/* send handshake token to server */
|
||||
result = Curl_write_plain(conn, conn->sock[sockindex],
|
||||
result = Curl_write_plain(data, conn->sock[sockindex],
|
||||
outbuf[i].pvBuffer, outbuf[i].cbBuffer,
|
||||
&written);
|
||||
if((result != CURLE_OK) ||
|
||||
@ -1305,7 +1305,7 @@ cert_counter_callback(const CERT_CONTEXT *ccert_context, void *certs_count)
|
||||
|
||||
struct Adder_args
|
||||
{
|
||||
struct connectdata *conn;
|
||||
struct Curl_easy *data;
|
||||
CURLcode result;
|
||||
int idx;
|
||||
int certs_count;
|
||||
@ -1320,7 +1320,8 @@ add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, void *raw_arg)
|
||||
const char *beg = (const char *) ccert_context->pbCertEncoded;
|
||||
const char *end = beg + ccert_context->cbCertEncoded;
|
||||
int insert_index = (args->certs_count - 1) - args->idx;
|
||||
args->result = Curl_extract_certinfo(args->conn, insert_index, beg, end);
|
||||
args->result = Curl_extract_certinfo(args->data, insert_index,
|
||||
beg, end);
|
||||
args->idx++;
|
||||
}
|
||||
return args->result == CURLE_OK;
|
||||
@ -1400,7 +1401,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
else
|
||||
infof(data, "ALPN, server did not agree to a protocol\n");
|
||||
Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
|
||||
}
|
||||
#endif
|
||||
@ -1458,7 +1459,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
result = Curl_ssl_init_certinfo(data, certs_count);
|
||||
if(!result) {
|
||||
struct Adder_args args;
|
||||
args.conn = conn;
|
||||
args.data = data;
|
||||
args.idx = 0;
|
||||
args.certs_count = certs_count;
|
||||
traverse_cert_store(ccert_context, add_cert_to_certinfo, &args);
|
||||
@ -1597,12 +1598,13 @@ schannel_connect_common(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
schannel_send(struct connectdata *conn, int sockindex,
|
||||
schannel_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t len, CURLcode *err)
|
||||
{
|
||||
ssize_t written = -1;
|
||||
size_t data_len = 0;
|
||||
unsigned char *data = NULL;
|
||||
unsigned char *ptr = NULL;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
SecBuffer outbuf[4];
|
||||
SecBufferDesc outbuf_desc;
|
||||
@ -1629,19 +1631,19 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
/* calculate the complete message length and allocate a buffer for it */
|
||||
data_len = BACKEND->stream_sizes.cbHeader + len +
|
||||
BACKEND->stream_sizes.cbTrailer;
|
||||
data = (unsigned char *) malloc(data_len);
|
||||
if(data == NULL) {
|
||||
ptr = (unsigned char *) malloc(data_len);
|
||||
if(!ptr) {
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* setup output buffers (header, data, trailer, empty) */
|
||||
InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
|
||||
data, BACKEND->stream_sizes.cbHeader);
|
||||
ptr, BACKEND->stream_sizes.cbHeader);
|
||||
InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
|
||||
data + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
|
||||
ptr + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
|
||||
InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
|
||||
data + BACKEND->stream_sizes.cbHeader + len,
|
||||
ptr + BACKEND->stream_sizes.cbHeader + len,
|
||||
BACKEND->stream_sizes.cbTrailer);
|
||||
InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
|
||||
InitSecBufferDesc(&outbuf_desc, outbuf, 4);
|
||||
@ -1680,10 +1682,10 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
while(len > (size_t)written) {
|
||||
ssize_t this_write = 0;
|
||||
int what;
|
||||
timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
|
||||
timediff_t timeout_ms = Curl_timeleft(data, NULL, FALSE);
|
||||
if(timeout_ms < 0) {
|
||||
/* we already got the timeout */
|
||||
failf(conn->data, "schannel: timed out sending data "
|
||||
failf(data, "schannel: timed out sending data "
|
||||
"(bytes sent: %zd)", written);
|
||||
*err = CURLE_OPERATION_TIMEDOUT;
|
||||
written = -1;
|
||||
@ -1694,13 +1696,13 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
what = SOCKET_WRITABLE(conn->sock[sockindex], timeout_ms);
|
||||
if(what < 0) {
|
||||
/* fatal error */
|
||||
failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||
*err = CURLE_SEND_ERROR;
|
||||
written = -1;
|
||||
break;
|
||||
}
|
||||
else if(0 == what) {
|
||||
failf(conn->data, "schannel: timed out sending data "
|
||||
failf(data, "schannel: timed out sending data "
|
||||
"(bytes sent: %zd)", written);
|
||||
*err = CURLE_OPERATION_TIMEDOUT;
|
||||
written = -1;
|
||||
@ -1708,7 +1710,7 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
/* socket is writable */
|
||||
|
||||
result = Curl_write_plain(conn, conn->sock[sockindex], data + written,
|
||||
result = Curl_write_plain(data, conn->sock[sockindex], ptr + written,
|
||||
len - written, &this_write);
|
||||
if(result == CURLE_AGAIN)
|
||||
continue;
|
||||
@ -1728,7 +1730,7 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
*err = CURLE_SEND_ERROR;
|
||||
}
|
||||
|
||||
Curl_safefree(data);
|
||||
Curl_safefree(ptr);
|
||||
|
||||
if(len == (size_t)written)
|
||||
/* Encrypted message including header, data and trailer entirely sent.
|
||||
@ -1739,12 +1741,12 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
schannel_recv(struct connectdata *conn, int sockindex,
|
||||
schannel_recv(struct Curl_easy *data, int sockindex,
|
||||
char *buf, size_t len, CURLcode *err)
|
||||
{
|
||||
size_t size = 0;
|
||||
ssize_t nread = -1;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
unsigned char *reallocated_buffer;
|
||||
size_t reallocated_length;
|
||||
@ -2181,7 +2183,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
||||
if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
|
||||
/* send close message which is in output buffer */
|
||||
ssize_t written;
|
||||
result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
|
||||
result = Curl_write_plain(data, conn->sock[sockindex], outbuf.pvBuffer,
|
||||
outbuf.cbBuffer, &written);
|
||||
|
||||
s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
|
||||
|
@ -5,8 +5,8 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
|
||||
* Copyright (C) 2012 - 2020, 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
|
||||
@ -2693,7 +2693,7 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex)
|
||||
else
|
||||
infof(data, "ALPN, server did not agree to a protocol\n");
|
||||
|
||||
Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
|
||||
|
||||
/* chosenProtocol is a reference to the string within alpnArr
|
||||
@ -3157,13 +3157,13 @@ static bool Curl_sectransp_false_start(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static ssize_t sectransp_send(struct connectdata *conn,
|
||||
static ssize_t sectransp_send(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
/*struct Curl_easy *data = conn->data;*/
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
size_t processed = 0UL;
|
||||
@ -3215,7 +3215,7 @@ static ssize_t sectransp_send(struct connectdata *conn,
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1L;
|
||||
default:
|
||||
failf(conn->data, "SSLWrite() returned error %d", err);
|
||||
failf(data, "SSLWrite() returned error %d", err);
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1L;
|
||||
}
|
||||
@ -3224,13 +3224,13 @@ static ssize_t sectransp_send(struct connectdata *conn,
|
||||
return (ssize_t)processed;
|
||||
}
|
||||
|
||||
static ssize_t sectransp_recv(struct connectdata *conn,
|
||||
static ssize_t sectransp_recv(struct Curl_easy *data,
|
||||
int num,
|
||||
char *buf,
|
||||
size_t buffersize,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
/*struct Curl_easy *data = conn->data;*/
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
size_t processed = 0UL;
|
||||
@ -3269,7 +3269,7 @@ static ssize_t sectransp_recv(struct connectdata *conn,
|
||||
}
|
||||
goto again;
|
||||
default:
|
||||
failf(conn->data, "SSLRead() return error %d", err);
|
||||
failf(data, "SSLRead() return error %d", err);
|
||||
*curlcode = CURLE_RECV_ERROR;
|
||||
return -1L;
|
||||
break;
|
||||
|
@ -735,7 +735,7 @@ wolfssl_connect_step2(struct connectdata *conn,
|
||||
else
|
||||
infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len,
|
||||
protocol);
|
||||
Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
|
||||
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
|
||||
}
|
||||
else if(rc == SSL_ALPN_NOT_FOUND)
|
||||
@ -807,12 +807,13 @@ wolfssl_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
|
||||
|
||||
static ssize_t wolfssl_send(struct connectdata *conn,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
static ssize_t wolfssl_send(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
|
||||
@ -829,7 +830,7 @@ static ssize_t wolfssl_send(struct connectdata *conn,
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1;
|
||||
default:
|
||||
failf(conn->data, "SSL write: %s, errno %d",
|
||||
failf(data, "SSL write: %s, errno %d",
|
||||
ERR_error_string(err, error_buffer),
|
||||
SOCKERRNO);
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
@ -855,12 +856,13 @@ static void wolfssl_close(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t wolfssl_recv(struct connectdata *conn,
|
||||
static ssize_t wolfssl_recv(struct Curl_easy *data,
|
||||
int num,
|
||||
char *buf,
|
||||
size_t buffersize,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
|
||||
@ -879,9 +881,8 @@ static ssize_t wolfssl_recv(struct connectdata *conn,
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1;
|
||||
default:
|
||||
failf(conn->data, "SSL read: %s, errno %d",
|
||||
ERR_error_string(err, error_buffer),
|
||||
SOCKERRNO);
|
||||
failf(data, "SSL read: %s, errno %d",
|
||||
ERR_error_string(err, error_buffer), SOCKERRNO);
|
||||
*curlcode = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -945,13 +945,12 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
|
||||
}
|
||||
}
|
||||
|
||||
CURLcode Curl_extract_certinfo(struct connectdata *conn,
|
||||
CURLcode Curl_extract_certinfo(struct Curl_easy *data,
|
||||
int certnum,
|
||||
const char *beg,
|
||||
const char *end)
|
||||
{
|
||||
struct Curl_X509certificate cert;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct Curl_asn1Element param;
|
||||
const char *ccp;
|
||||
char *cp1;
|
||||
@ -1132,10 +1131,9 @@ static const char *checkOID(const char *beg, const char *end,
|
||||
return matched? ccp: NULL;
|
||||
}
|
||||
|
||||
CURLcode Curl_verifyhost(struct connectdata *conn,
|
||||
CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
|
||||
const char *beg, const char *end)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct Curl_X509certificate cert;
|
||||
struct Curl_asn1Element dn;
|
||||
struct Curl_asn1Element elem;
|
||||
|
@ -8,7 +8,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2021, 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
|
||||
@ -125,9 +125,9 @@ const char *Curl_ASN1tostr(struct Curl_asn1Element *elem, int type);
|
||||
const char *Curl_DNtostr(struct Curl_asn1Element *dn);
|
||||
int Curl_parseX509(struct Curl_X509certificate *cert,
|
||||
const char *beg, const char *end);
|
||||
CURLcode Curl_extract_certinfo(struct connectdata *conn, int certnum,
|
||||
CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum,
|
||||
const char *beg, const char *end);
|
||||
CURLcode Curl_verifyhost(struct connectdata *conn,
|
||||
CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
|
||||
const char *beg, const char *end);
|
||||
#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */
|
||||
#endif /* HEADER_CURL_X509ASN1_H */
|
||||
|
@ -29,6 +29,7 @@ imap://%HOSTIP:%IMAPPORT/660
|
||||
<verify>
|
||||
<protocol>
|
||||
A001 CAPABILITY
|
||||
A002 LOGOUT
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2021, 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
|
||||
@ -346,7 +346,6 @@ static unsigned char cert[] = {
|
||||
UNITTEST_START
|
||||
{
|
||||
CURLcode result;
|
||||
struct connectdata conn;
|
||||
const char *beg = (const char *)&cert[0];
|
||||
const char *end = (const char *)&cert[sizeof(cert)];
|
||||
struct Curl_easy *data = curl_easy_init();
|
||||
@ -355,11 +354,7 @@ UNITTEST_START
|
||||
if(!data)
|
||||
return 2;
|
||||
|
||||
memset(&conn, 0, sizeof(struct connectdata));
|
||||
/* this is a lot of assuming, but we expect the parsing function to only
|
||||
really need the easy handle pointer */
|
||||
conn.data = data;
|
||||
result = Curl_extract_certinfo(&conn, 0, beg, end);
|
||||
result = Curl_extract_certinfo(data, 0, beg, end);
|
||||
|
||||
fail_unless(result == CURLE_OK, "Curl_extract_certinfo returned error");
|
||||
|
||||
@ -369,7 +364,7 @@ UNITTEST_START
|
||||
for(i = 0; i < 45; i++) {
|
||||
char backup = cert[i];
|
||||
cert[i] = (unsigned char) (byte & 0xff);
|
||||
(void) Curl_extract_certinfo(&conn, 0, beg, end);
|
||||
(void) Curl_extract_certinfo(data, 0, beg, end);
|
||||
cert[i] = backup;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user