mirror of
https://github.com/moparisthebest/curl
synced 2024-11-11 12:05:06 -05:00
SSH: add protocol lock direction
Some protocols have to call the underlying functions without regard to what exact state the socket signals. For example even if the socket says "readable", the send function might need to be called while uploading, or vice versa. This is the case for libssh2 based protocols: SCP and SFTP and we now introduce a define to set those protocols and we make the multi interface code aware of this concept. This is another fix to make test 582 run properly.
This commit is contained in:
parent
60406ff7f8
commit
3eac14b43c
28
lib/multi.c
28
lib/multi.c
@ -2105,35 +2105,41 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||||||
and just move on. */
|
and just move on. */
|
||||||
;
|
;
|
||||||
else {
|
else {
|
||||||
|
struct connectdata *conn;
|
||||||
data = entry->easy;
|
data = entry->easy;
|
||||||
|
|
||||||
if(data->magic != CURLEASY_MAGIC_NUMBER)
|
if(data->magic != CURLEASY_MAGIC_NUMBER)
|
||||||
/* bad bad bad bad bad bad bad */
|
/* bad bad bad bad bad bad bad */
|
||||||
return CURLM_INTERNAL_ERROR;
|
return CURLM_INTERNAL_ERROR;
|
||||||
|
|
||||||
|
/* note that this can possibly be NULL at this point */
|
||||||
|
conn = data->set.one_easy->easy_conn;
|
||||||
|
|
||||||
/* If the pipeline is enabled, take the handle which is in the head of
|
/* If the pipeline is enabled, take the handle which is in the head of
|
||||||
the pipeline. If we should write into the socket, take the send_pipe
|
the pipeline. If we should write into the socket, take the send_pipe
|
||||||
head. If we should read from the socket, take the recv_pipe head. */
|
head. If we should read from the socket, take the recv_pipe head. */
|
||||||
if(data->set.one_easy->easy_conn) {
|
if(conn) {
|
||||||
if ((ev_bitmask & CURL_POLL_OUT) &&
|
if ((ev_bitmask & CURL_POLL_OUT) &&
|
||||||
data->set.one_easy->easy_conn->send_pipe &&
|
conn->send_pipe &&
|
||||||
data->set.one_easy->easy_conn->send_pipe->head)
|
conn->send_pipe->head)
|
||||||
data = data->set.one_easy->easy_conn->send_pipe->head->ptr;
|
data = conn->send_pipe->head->ptr;
|
||||||
else if ((ev_bitmask & CURL_POLL_IN) &&
|
else if ((ev_bitmask & CURL_POLL_IN) &&
|
||||||
data->set.one_easy->easy_conn->recv_pipe &&
|
conn->recv_pipe &&
|
||||||
data->set.one_easy->easy_conn->recv_pipe->head)
|
conn->recv_pipe->head)
|
||||||
data = data->set.one_easy->easy_conn->recv_pipe->head->ptr;
|
data = conn->recv_pipe->head->ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->set.one_easy->easy_conn) /* set socket event bitmask */
|
if(conn && !(conn->handler->protocol & PROT_LOCKEDBITS))
|
||||||
data->set.one_easy->easy_conn->cselect_bits = ev_bitmask;
|
/* set socket event bitmask if they're not locked */
|
||||||
|
conn->cselect_bits = ev_bitmask;
|
||||||
|
|
||||||
do
|
do
|
||||||
result = multi_runsingle(multi, now, data->set.one_easy);
|
result = multi_runsingle(multi, now, data->set.one_easy);
|
||||||
while (CURLM_CALL_MULTI_PERFORM == result);
|
while (CURLM_CALL_MULTI_PERFORM == result);
|
||||||
|
|
||||||
if(data->set.one_easy->easy_conn)
|
if(conn && !(conn->handler->protocol & PROT_LOCKEDBITS))
|
||||||
data->set.one_easy->easy_conn->cselect_bits = 0;
|
/* clear the bitmask only if not locked */
|
||||||
|
conn->cselect_bits = 0;
|
||||||
|
|
||||||
if(CURLM_OK >= result)
|
if(CURLM_OK >= result)
|
||||||
/* get the socket(s) and check if the state has been changed since
|
/* get the socket(s) and check if the state has been changed since
|
||||||
|
15
lib/ssh.c
15
lib/ssh.c
@ -2028,8 +2028,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
|||||||
/* not set by Curl_setup_transfer to preserve keepon bits */
|
/* not set by Curl_setup_transfer to preserve keepon bits */
|
||||||
conn->writesockfd = conn->sockfd;
|
conn->writesockfd = conn->sockfd;
|
||||||
|
|
||||||
/* FIXME: here should be explained why we need it to start the
|
/* we want to use the _receiving_ function even when the socket turns
|
||||||
* download */
|
out writableable as the underlying libssh2 recv function will deal
|
||||||
|
with both accordingly */
|
||||||
conn->cselect_bits = CURL_CSELECT_IN;
|
conn->cselect_bits = CURL_CSELECT_IN;
|
||||||
}
|
}
|
||||||
if(result) {
|
if(result) {
|
||||||
@ -2161,6 +2162,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
|||||||
sshc->actualcode = result;
|
sshc->actualcode = result;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* we want to use the _sending_ function even when the socket turns
|
||||||
|
out readable as the underlying libssh2 scp send function will deal
|
||||||
|
with both accordingly */
|
||||||
|
conn->cselect_bits = CURL_CSELECT_OUT;
|
||||||
|
|
||||||
state(conn, SSH_STOP);
|
state(conn, SSH_STOP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2207,8 +2213,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
|||||||
/* not set by Curl_setup_transfer to preserve keepon bits */
|
/* not set by Curl_setup_transfer to preserve keepon bits */
|
||||||
conn->writesockfd = conn->sockfd;
|
conn->writesockfd = conn->sockfd;
|
||||||
|
|
||||||
/* FIXME: here should be explained why we need it to start the
|
/* we want to use the _receiving_ function even when the socket turns
|
||||||
* download */
|
out writableable as the underlying libssh2 recv function will deal
|
||||||
|
with both accordingly */
|
||||||
conn->cselect_bits = CURL_CSELECT_IN;
|
conn->cselect_bits = CURL_CSELECT_IN;
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
|
@ -775,6 +775,12 @@ struct connectdata {
|
|||||||
PROT_SFTP | PROT_SCP)
|
PROT_SFTP | PROT_SCP)
|
||||||
#define PROT_DUALCHANNEL PROT_FTP /* these protocols use two connections */
|
#define PROT_DUALCHANNEL PROT_FTP /* these protocols use two connections */
|
||||||
|
|
||||||
|
/* some protocols will have to call the underlying functions without regard to
|
||||||
|
what exact state the socket signals. IE even if the socket says "readable",
|
||||||
|
the send function might need to be called while uploading, or vice versa.
|
||||||
|
*/
|
||||||
|
#define PROT_LOCKEDBITS (PROT_SCP | PROT_SFTP)
|
||||||
|
|
||||||
/* 'dns_entry' is the particular host we use. This points to an entry in the
|
/* 'dns_entry' is the particular host we use. This points to an entry in the
|
||||||
DNS cache and it will not get pruned while locked. It gets unlocked in
|
DNS cache and it will not get pruned while locked. It gets unlocked in
|
||||||
Curl_done(). This entry will be NULL if the connection is re-used as then
|
Curl_done(). This entry will be NULL if the connection is re-used as then
|
||||||
|
Loading…
Reference in New Issue
Block a user