pop3: Added support for non-blocking SSL upgrade

Added support for asynchronous SSL upgrade when using the
multi-interface.
This commit is contained in:
Steve Holme 2013-01-08 11:31:48 +00:00
parent 7a6d8b1b1a
commit 4ffb8a6398
2 changed files with 37 additions and 7 deletions

View File

@ -103,6 +103,7 @@ static int pop3_getsock(struct connectdata *conn,
int numsocks); int numsocks);
static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done); static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
static CURLcode pop3_setup_connection(struct connectdata *conn); static CURLcode pop3_setup_connection(struct connectdata *conn);
static CURLcode pop3_state_upgrade_tls(struct connectdata *conn);
/* /*
* POP3 protocol handler. * POP3 protocol handler.
@ -227,7 +228,7 @@ static int pop3_endofresp(struct pingpong *pp, int *resp)
return FALSE; return FALSE;
} }
/* Are we processing servergreet responses */ /* Are we processing servergreet responses? */
if(pop3c->state == POP3_SERVERGREET) { if(pop3c->state == POP3_SERVERGREET) {
/* Look for the APOP timestamp */ /* Look for the APOP timestamp */
if(len >= 3 && line[len - 3] == '>') { if(len >= 3 && line[len - 3] == '>') {
@ -345,6 +346,7 @@ static void state(struct connectdata *conn, pop3state newstate)
"STOP", "STOP",
"SERVERGREET", "SERVERGREET",
"STARTTLS", "STARTTLS",
"UPGRADETLS",
"CAPA", "CAPA",
"AUTH_PLAIN", "AUTH_PLAIN",
"AUTH_LOGIN", "AUTH_LOGIN",
@ -568,13 +570,33 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
result = pop3_state_capa(conn); result = pop3_state_capa(conn);
} }
else { else {
/* Curl_ssl_connect is BLOCKING */ if(data->state.used_interface == Curl_if_multi) {
state(conn, POP3_UPGRADETLS);
result = pop3_state_upgrade_tls(conn);
}
else {
result = Curl_ssl_connect(conn, FIRSTSOCKET); result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(CURLE_OK == result) { if(CURLE_OK == result) {
pop3_to_pop3s(conn); pop3_to_pop3s(conn);
result = pop3_state_capa(conn); result = pop3_state_capa(conn);
} }
} }
}
return result;
}
static CURLcode pop3_state_upgrade_tls(struct connectdata *conn)
{
struct pop3_conn *pop3c = &conn->proto.pop3c;
CURLcode result;
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);
if(pop3c->ssldone) {
pop3_to_pop3s(conn);
result = pop3_state_capa(conn);
}
return result; return result;
} }
@ -1114,6 +1136,10 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
struct pingpong *pp = &pop3c->pp; struct pingpong *pp = &pop3c->pp;
size_t nread = 0; size_t nread = 0;
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
if(pop3c->state == POP3_UPGRADETLS)
return pop3_state_upgrade_tls(conn);
/* Flush any data that needs to be sent */ /* Flush any data that needs to be sent */
if(pp->sendleft) if(pp->sendleft)
return Curl_pp_flushsend(pp); return Curl_pp_flushsend(pp);

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2009 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2009 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -30,6 +30,8 @@ typedef enum {
POP3_SERVERGREET, /* waiting for the initial greeting immediately after POP3_SERVERGREET, /* waiting for the initial greeting immediately after
a connect */ a connect */
POP3_STARTTLS, POP3_STARTTLS,
POP3_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS
(multi mode only) */
POP3_CAPA, POP3_CAPA,
POP3_AUTH_PLAIN, POP3_AUTH_PLAIN,
POP3_AUTH_LOGIN, POP3_AUTH_LOGIN,
@ -63,6 +65,8 @@ struct pop3_conn {
unsigned int authused; /* SASL auth mechanism used for the connection */ unsigned int authused; /* SASL auth mechanism used for the connection */
char *apoptimestamp; /* APOP timestamp from the server greeting */ char *apoptimestamp; /* APOP timestamp from the server greeting */
pop3state state; /* Always use pop3.c:state() to change state! */ pop3state state; /* Always use pop3.c:state() to change state! */
bool ssldone; /* Is connect() over SSL done? Only relevant in
multi mode */
}; };
extern const struct Curl_handler Curl_handler_pop3; extern const struct Curl_handler Curl_handler_pop3;