SMTP-multi: non-blocking connect
authorBen Noordhuis <info@bnoordhuis.nl>
Wed, 16 Feb 2011 21:28:01 +0000 (22:28 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 15 Mar 2011 19:10:02 +0000 (20:10 +0100)
Use Curl_ssl_connect_nonblocking() when upgrading the connection to
TLS/SSL while using the multi interface.

lib/smtp.c
lib/smtp.h

index 8d24a628be9af0fad31ab8a2a1194954ff52e8e5..3b2179677cc06eb5df0aa07034361ff57df3fe3d 100644 (file)
@@ -115,6 +115,7 @@ static int smtp_getsock(struct connectdata *conn,
 static CURLcode smtp_doing(struct connectdata *conn,
                            bool *dophase_done);
 static CURLcode smtp_setup_connection(struct connectdata * conn);
+static CURLcode smtp_state_upgrade_tls(struct connectdata *conn);
 
 
 /*
@@ -290,6 +291,7 @@ static void state(struct connectdata *conn,
     "EHLO",
     "HELO",
     "STARTTLS",
+    "UPGRADETLS",
     "AUTHPLAIN",
     "AUTHLOGIN",
     "AUTHPASSWD",
@@ -481,16 +483,36 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
       result = smtp_authenticate(conn);
   }
   else {
-    /* Curl_ssl_connect is BLOCKING */
-    result = Curl_ssl_connect(conn, FIRSTSOCKET);
-    if(CURLE_OK == result) {
-      smtp_to_smtps(conn);
-      result = smtp_state_ehlo(conn);
+    if(data->state.used_interface == Curl_if_multi) {
+      state(conn, SMTP_UPGRADETLS);
+      return smtp_state_upgrade_tls(conn);
+    }
+    else {
+      result = Curl_ssl_connect(conn, FIRSTSOCKET);
+      if(CURLE_OK == result) {
+        smtp_to_smtps(conn);
+        result = smtp_state_ehlo(conn);
+      }
     }
   }
   return result;
 }
 
+static CURLcode smtp_state_upgrade_tls(struct connectdata *conn)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  CURLcode result;
+
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone);
+
+  if(smtpc->ssldone) {
+    smtp_to_smtps(conn);
+    result = smtp_state_ehlo(conn);
+  }
+
+  return result;
+}
+
 /* for EHLO responses */
 static CURLcode smtp_state_ehlo_resp(struct connectdata *conn,
                                      int smtpcode,
@@ -910,6 +932,9 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
   struct pingpong *pp = &smtpc->pp;
   size_t nread = 0;
 
+  if(smtpc->state == SMTP_UPGRADETLS)
+    return smtp_state_upgrade_tls(conn);
+
   if(pp->sendleft)
     /* we have a piece of a command still left to send */
     return Curl_pp_flushsend(pp);
index e9050f868680d31121d1a8fc81320c954820153f..0f527142cc46c3a7c436c2adb0d84b1a66374c20 100644 (file)
@@ -34,6 +34,7 @@ typedef enum {
   SMTP_EHLO,
   SMTP_HELO,
   SMTP_STARTTLS,
+  SMTP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS (multi mode only) */
   SMTP_AUTHPLAIN,
   SMTP_AUTHLOGIN,
   SMTP_AUTHPASSWD,