libev migration; relaying implementation
authorWilfried Goesgens <dothebart@citadel.org>
Sun, 23 Jan 2011 19:21:20 +0000 (20:21 +0100)
committerWilfried Goesgens <dothebart@citadel.org>
Sun, 23 Jan 2011 19:21:20 +0000 (20:21 +0100)
  - move translation of DNS-results up into the SMTP-Client
  - use an own callback for connecting to IP-based relays
  - add assertions to callbacks being NULL, since after callin a NULL-callback the last stackframe is NIL and Void, and we can't see where we went off into misery.

citadel/event_client.c
citadel/event_client.h
citadel/modules/c-ares-dns/serv_c-ares-dns.c
citadel/modules/smtp/serv_smtpeventclient.c
citadel/modules/smtp/serv_smtpqueue.c
citadel/modules/smtp/smtpqueue.h

index 6316a1c4ce809d9447116e25526a9dd90413996a..4dca578f7232122e63c0ab301d7cd5b6e1cfc5c8 100644 (file)
@@ -46,6 +46,8 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <assert.h>
+
 #include <libcitadel.h>
 #include "citadel.h"
 #include "server.h"
@@ -135,7 +137,7 @@ void ShutDownCLient(AsyncIO *IO)
                IO->SendBuf.fd = 0;
                IO->RecvBuf.fd = 0;
        }
-
+       assert(IO->Terminate);
        IO->Terminate(IO);
        
 }
@@ -144,7 +146,7 @@ void ShutDownCLient(AsyncIO *IO)
 eReadState HandleInbound(AsyncIO *IO)
 {
        eReadState Finished = eBufferNotEmpty;
-               
+       
        while ((Finished == eBufferNotEmpty) && (IO->NextState == eReadMessage)){
                if (IO->RecvBuf.nBlobBytesWanted != 0) { 
                                
@@ -171,6 +173,7 @@ eReadState HandleInbound(AsyncIO *IO)
                }
                        
                if (Finished != eMustReadMore) {
+                       assert(IO->ReadDone);
                        ev_io_stop(event_base, &IO->recv_event);
                        IO->NextState = IO->ReadDone(IO);
                        Finished = StrBufCheckBuffer(&IO->RecvBuf);
@@ -181,6 +184,7 @@ eReadState HandleInbound(AsyncIO *IO)
        if ((IO->NextState == eSendReply) ||
            (IO->NextState == eSendMore))
        {
+               assert(IO->SendDone);
                IO->NextState = IO->SendDone(IO);
                ev_io_start(event_base, &IO->send_event);
        }
@@ -231,6 +235,7 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
                case eSendReply:
                        break;
                case eSendMore:
+                       assert(IO->SendDone);
                        IO->NextState = IO->SendDone(IO);
 
                        if ((IO->NextState == eTerminateConnection) ||
@@ -254,8 +259,10 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
                        break;
                }
        }
-       else if (rc < 0)
+       else if (rc < 0) {
+               assert(IO->Timeout);
                IO->Timeout(IO);
+       }
        /* else : must write more. */
 }
 static void
@@ -283,6 +290,7 @@ IO_Timout_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
        AsyncIO *IO = watcher->data;
 
        ev_timer_stop (event_base, &IO->rw_timeout);
+       assert(IO->Timeout);
        IO->Timeout(IO);
 }
 static void
@@ -292,6 +300,7 @@ IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
 
        ev_timer_stop (event_base, &IO->conn_fail);
        ev_io_stop(loop, &IO->conn_event);
+       assert(IO->ConnFail);
        IO->ConnFail(IO);
 }
 static void
@@ -313,6 +322,7 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
        if (nbytes > 0) {
                HandleInbound(IO);
        } else if (nbytes == 0) {
+               assert(IO->Timeout);
                IO->Timeout(IO); /* this is a timeout... */
                return;
        } else if (nbytes == -1) {
@@ -323,7 +333,7 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
 
 
 
-int event_connect_socket(AsyncIO *IO, double conn_timeout, double first_rw_timeout)
+eNextState event_connect_socket(AsyncIO *IO, double conn_timeout, double first_rw_timeout)
 {
        int fdflags; 
        int rc = -1;
@@ -338,7 +348,7 @@ int event_connect_socket(AsyncIO *IO, double conn_timeout, double first_rw_timeo
                CtdlLogPrintf(CTDL_ERR, "EVENT: socket() failed: %s\n", strerror(errno));
                StrBufPrintf(IO->ErrMsg, "Failed to create socket: %s", strerror(errno));
 //             freeaddrinfo(res);
-               return -1;
+               return eAbort;
        }
        fdflags = fcntl(IO->sock, F_GETFL);
        if (fdflags < 0) {
@@ -346,7 +356,7 @@ int event_connect_socket(AsyncIO *IO, double conn_timeout, double first_rw_timeo
                              "EVENT: unable to get socket flags! %s \n",
                              strerror(errno));
                StrBufPrintf(IO->ErrMsg, "Failed to get socket flags: %s", strerror(errno));
-               return -1;
+               return eAbort;
        }
        fdflags = fdflags | O_NONBLOCK;
        if (fcntl(IO->sock, F_SETFL, fdflags) < 0) {
@@ -355,7 +365,7 @@ int event_connect_socket(AsyncIO *IO, double conn_timeout, double first_rw_timeo
                              strerror(errno));
                StrBufPrintf(IO->ErrMsg, "Failed to set socket flags: %s", strerror(errno));
                close(IO->sock);
-               return -1;
+               return eAbort;
        }
 /* TODO: maye we could use offsetof() to calc the position of data... 
  * http://doc.dvgu.ru/devel/ev.html#associating_custom_data_with_a_watcher
@@ -369,17 +379,17 @@ int event_connect_socket(AsyncIO *IO, double conn_timeout, double first_rw_timeo
        IO->conn_fail.data = IO;
        ev_timer_init(&IO->rw_timeout, IO_Timout_callback, first_rw_timeout, 0);
        IO->rw_timeout.data = IO;
-       
-       rc = connect(IO->sock, 
-                    (struct sockaddr *) &IO->Addr,
-                    (IO->IP6)? ///HEnt->h_addrtype == AF_INET6)?
-                    sizeof(struct in6_addr):
-                    sizeof(struct sockaddr_in));
+       ///struct sockaddr_in *addr = &IO->Addr;
+       if (IO->IP6)
+               rc = connect(IO->sock, &IO->Addr, sizeof(struct in6_addr));
+       else
+               rc = connect(IO->sock, (struct sockaddr_in *)&IO->Addr, sizeof(struct sockaddr_in));
+
        if (rc >= 0){
 ////           freeaddrinfo(res);
                set_start_callback(event_base, IO, 0);
                ev_timer_start(event_base, &IO->rw_timeout);
-               return 0;
+               return IO->NextState;
        }
        else if (errno == EINPROGRESS) {
 
@@ -388,14 +398,16 @@ int event_connect_socket(AsyncIO *IO, double conn_timeout, double first_rw_timeo
 
                ev_io_start(event_base, &IO->conn_event);
                ev_timer_start(event_base, &IO->conn_fail);
-               return 0;
+               return IO->NextState;
        }
        else {
                CtdlLogPrintf(CTDL_ERR, "connect() failed: %s\n", strerror(errno));
                StrBufPrintf(IO->ErrMsg, "Failed to connect: %s", strerror(errno));
+               assert(IO->ConnFail);
                IO->ConnFail(IO);
-               return -1;
+               return eAbort;
        }
+       return IO->NextState;
 }
 
 void SetNextTimeout(AsyncIO *IO, double timeout)
@@ -404,11 +416,11 @@ void SetNextTimeout(AsyncIO *IO, double timeout)
        ev_timer_again (event_base,  &IO->rw_timeout);
 }
 
-void InitEventIO(AsyncIO *IO, 
-                void *pData, 
-                double conn_timeout, 
-                double first_rw_timeout,
-                int ReadFirst)
+eNextState InitEventIO(AsyncIO *IO, 
+                      void *pData, 
+                      double conn_timeout, 
+                      double first_rw_timeout,
+                      int ReadFirst)
 {
        IO->Data = pData;
        
@@ -420,5 +432,5 @@ void InitEventIO(AsyncIO *IO,
        }
        IO->IP6 = IO->HEnt->h_addrtype == AF_INET6;
 //     IO->res = HEnt->h_addr_list[0];
-       event_connect_socket(IO, conn_timeout, first_rw_timeout);
+       return event_connect_socket(IO, conn_timeout, first_rw_timeout);
 }
index 7fe12d1a4c9d40971c6e8e5e75e82d9b4dff4d44..9abda5329aa9f27d927d3fcdd223db25ce8e37a6 100644 (file)
@@ -87,13 +87,16 @@ void FreeAsyncIOContents(AsyncIO *IO);
 int QueueEventContext(AsyncIO *IO, IO_CallBack CB);
 int ShutDownEventQueue(void);
 
-void InitEventIO(AsyncIO *IO, 
-                void *pData, 
-                double conn_timeout, double first_rw_timeout,
-                int ReadFirst);
+eNextState InitEventIO(AsyncIO *IO, 
+                      void *pData, 
+                      double conn_timeout, 
+                      double first_rw_timeout,
+                      int ReadFirst);
 
 int QueueQuery(ns_type Type, char *name, AsyncIO *IO, IO_CallBack PostDNS);
 
 void StopClient(AsyncIO *IO);
 
 void SetNextTimeout(AsyncIO *IO, double timeout);
+
+void InitC_ares_dns(AsyncIO *IO);
index 6c1be1f167a9ed3bb701a5c0b2fac9c98579352c..5f8426f9894731910675c94ff78c99ce3ddd537c 100644 (file)
@@ -223,19 +223,23 @@ void QueryCb(void *arg,
        IO->PostDNS(IO);
 }
 
-int QueueQuery(ns_type Type, char *name, AsyncIO *IO, IO_CallBack PostDNS)
+
+void InitC_ares_dns(AsyncIO *IO)
 {
-       int length, family;
-       char address_b[sizeof(struct in6_addr)];
        int optmask = 0;
-
        if (IO->DNSChannel == NULL) {
                optmask |= ARES_OPT_SOCK_STATE_CB;
                IO->DNSOptions.sock_state_cb = SockStateCb;
                IO->DNSOptions.sock_state_cb_data = IO;
                ares_init_options(&IO->DNSChannel, &IO->DNSOptions, optmask);
        }
+}
+int QueueQuery(ns_type Type, char *name, AsyncIO *IO, IO_CallBack PostDNS)
+{
+       int length, family;
+       char address_b[sizeof(struct in6_addr)];
 
+       InitC_ares_dns(IO);
        IO->PostDNS = PostDNS;
        switch(Type) {
        case ns_t_a:
index 919f97f60769ba5306afdff3c5b437dcf0731c03..591d5d59d03f4b2229f3e6b5eaf9bf0f2d46de12 100644 (file)
@@ -108,7 +108,7 @@ typedef enum _eSMTP_C_States {
        eMaxSMTPC
 } eSMTP_C_States;
 
-const double SMTP_C_ConnTimeout = 60.; /* wail 1 minute for connections... */
+const double SMTP_C_ConnTimeout = 300.; /* wail 1 minute for connections... */
 const double SMTP_C_ReadTimeouts[eMaxSMTPC] = {
        300., /* Greeting... */
        30., /* EHLO */
@@ -210,7 +210,7 @@ typedef eNextState (*SMTPSendHandler)(SmtpOutMsg *Msg);
 
 #define SMTP_IS_STATE(WHICH_STATE) (ChrPtr(SendMsg->IO.IOBuf)[0] == WHICH_STATE)
 
-#define SMTP_DBG_SEND() CtdlLogPrintf(CTDL_DEBUG, "SMTP client[%ld]: > %s\n", SendMsg->n, ChrPtr(SendMsg->IO.IOBuf))
+#define SMTP_DBG_SEND() CtdlLogPrintf(CTDL_DEBUG, "SMTP client[%ld]: > %s\n", SendMsg->n, ChrPtr(SendMsg->IO.SendBuf.Buf))
 #define SMTP_DBG_READ() CtdlLogPrintf(CTDL_DEBUG, "SMTP client[%ld]: < %s\n", SendMsg->n, ChrPtr(SendMsg->IO.IOBuf))
 
 
@@ -255,6 +255,67 @@ void FinalizeMessageSend(SmtpOutMsg *Msg)
 }
 
 
+void SetConnectStatus(AsyncIO *IO)
+{
+       
+       SmtpOutMsg *SendMsg = IO->Data;
+       char buf[256];
+       void *src;
+
+       buf[0] = '\0';
+
+       if (IO->IP6) {
+               src = &IO->Addr.sin6_addr;
+       }
+       else {
+               unsigned long psaddr;
+               struct sockaddr_in *addr = (struct sockaddr_in *)&IO->Addr;
+
+               src = &addr->sin_addr.s_addr;
+               memcpy(&psaddr, &addr->sin_addr.s_addr, sizeof(psaddr));
+///            psaddr = ntohl(psaddr); 
+/*
+               CtdlLogPrintf(CTDL_DEBUG, 
+                             "SMTP client[%ld]: connecting to %s [%ld.%ld.%ld.%ld:%d] ...\n", 
+                             SendMsg->n, 
+                             SendMsg->mx_host, 
+                             (psaddr >> 24) & 0xFF,
+                             (psaddr >> 16) & 0xFF,
+                             (psaddr >>  8) & 0xFF,
+                             (psaddr >>  0) & 0xFF,
+                             SendMsg->IO.dport);
+
+               SendMsg->MyQEntry->Status = 5; 
+               StrBufPrintf(SendMsg->MyQEntry->StatusMessage, 
+                            "Timeout while connecting %s [%ld.%ld.%ld.%ld:%d] ", 
+                            SendMsg->mx_host,
+                            (psaddr >> 24) & 0xFF,
+                            (psaddr >> 16) & 0xFF,
+                            (psaddr >>  8) & 0xFF,
+                            (psaddr >>  0) & 0xFF,
+                            SendMsg->IO.dport);
+
+*/
+       }
+
+       inet_ntop((IO->IP6)?AF_INET6:AF_INET,
+                 src,
+                 buf, sizeof(buf));
+
+       CtdlLogPrintf(CTDL_DEBUG, 
+                     "SMTP client[%ld]: connecting to %s [%s]:%d ...\n", 
+                     SendMsg->n, 
+                     SendMsg->mx_host, 
+                     buf,
+                     SendMsg->IO.dport);
+
+       SendMsg->MyQEntry->Status = 5; 
+       StrBufPrintf(SendMsg->MyQEntry->StatusMessage, 
+                    "Timeout while connecting %s [%s]:%d ", 
+                    SendMsg->mx_host,
+                    buf,
+                    SendMsg->IO.dport);
+}
 
 eNextState mx_connect_relay_ip(AsyncIO *IO)
 {
@@ -280,7 +341,7 @@ eNextState mx_connect_relay_ip(AsyncIO *IO)
        else {
                struct sockaddr_in *addr = (struct sockaddr_in*) &IO->Addr;
                /* Bypass the ns lookup result like this: IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1"); */
-               memcpy(&addr->sin_addr, 
+               memcpy(&addr->sin_addr,///.s_addr, 
                       &SendMsg->pCurrRelay->Addr,
                       sizeof(struct in_addr));
                
@@ -288,48 +349,11 @@ eNextState mx_connect_relay_ip(AsyncIO *IO)
                addr->sin_port = htons(IO->dport);
        }
 
+       SetConnectStatus(IO);
 
-
-/*
-
-       SendMsg->pCurrRelay->
-       if ((SendMsg->pCurrRelay != NULL) && (SendMsg->pCurrRelay->IsIP)) {
-               connect = 1;
-
-       }
-               unsigned long psaddr;
-
-
-               memcpy(&psaddr, hostent->h_addr_list[0], sizeof(psaddr));
-               psaddr = ntohl(psaddr); 
-
-               CtdlLogPrintf(CTDL_DEBUG, 
-                             "SMTP client[%ld]: connecting to %s [%ld.%ld.%ld.%ld:%d] ...\n", 
-                             SendMsg->n, 
-                             SendMsg->mx_host, 
-                             (psaddr >> 24) & 0xFF,
-                             (psaddr >> 16) & 0xFF,
-                             (psaddr >>  8) & 0xFF,
-                             (psaddr >>  0) & 0xFF,
-                             SendMsg->IO.dport);
-
-               SendMsg->MyQEntry->Status = 5; 
-               StrBufPrintf(SendMsg->MyQEntry->StatusMessage, 
-                            "Timeout while connecting %s [%ld.%ld.%ld.%ld:%d] ", 
-                            SendMsg->mx_host,
-                            (psaddr >> 24) & 0xFF,
-                            (psaddr >> 16) & 0xFF,
-                            (psaddr >>  8) & 0xFF,
-                            (psaddr >>  0) & 0xFF,
-                            SendMsg->IO.dport);
-
-
-       }
-*/
-       /// TODO: else fail!
-       InitEventIO(IO, SendMsg, 
-                   SMTP_C_ConnTimeout, 
-                   SMTP_C_ReadTimeouts[0],
+       return InitEventIO(IO, SendMsg, 
+                          SMTP_C_ConnTimeout, 
+                          SMTP_C_ReadTimeouts[0],
                            1);
 }
 
@@ -340,15 +364,17 @@ void get_one_mx_host_ip_done(void *Ctx,
 {
        AsyncIO *IO = (AsyncIO *) Ctx;
        SmtpOutMsg *SendMsg = IO->Data;
+       eNextState State = eAbort;
 
        if ((status == ARES_SUCCESS) && (hostent != NULL) ) {
                
-               IO->IP6 = hostent->h_addrtype == AF_INET6;
-               
+               IO->IP6  = hostent->h_addrtype == AF_INET6;
+               IO->HEnt = hostent;
+
                memset(&IO->Addr, 0, sizeof(struct in6_addr));
                if (IO->IP6) {
                        memcpy(&IO->Addr.sin6_addr.s6_addr, 
-                              IO->HEnt->h_addr_list[0],
+                              &hostent->h_addr_list[0],
                               sizeof(struct in6_addr));
                        
                        IO->Addr.sin6_family = hostent->h_addrtype;
@@ -357,47 +383,56 @@ void get_one_mx_host_ip_done(void *Ctx,
                else {
                        struct sockaddr_in *addr = (struct sockaddr_in*) &IO->Addr;
                        /* Bypass the ns lookup result like this: IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1"); */
-                       memcpy(&addr->sin_addr, 
-                              IO->HEnt->h_addr_list[0],
-                              sizeof(struct in_addr));
+//                     addr->sin_addr.s_addr = htonl((uint32_t)&hostent->h_addr_list[0]);
+                       memcpy(&addr->sin_addr.s_addr, hostent->h_addr_list[0], sizeof(uint32_t));
                        
                        addr->sin_family = hostent->h_addrtype;
                        addr->sin_port = htons(IO->dport);
                        
                }
                SendMsg->IO.HEnt = hostent;
-               InitEventIO(IO, SendMsg, 
-                           SMTP_C_ConnTimeout, 
-                           SMTP_C_ReadTimeouts[0],
-                           1);
+               SetConnectStatus(IO);
+               State = InitEventIO(IO, SendMsg, 
+                                  SMTP_C_ConnTimeout, 
+                                  SMTP_C_ReadTimeouts[0],
+                                  1);
        }
+       if (State == eAbort)
+               SMTP_C_Terminate(IO);
 }
 
 const unsigned short DefaultMXPort = 25;
 eNextState get_one_mx_host_ip(AsyncIO *IO)
 {
        SmtpOutMsg * SendMsg = IO->Data;
-
+       const char *Hostname;
        //char *endpart;
        //char buf[SIZ];
+       InitC_ares_dns(IO);
 
-       CtdlLogPrintf(CTDL_DEBUG, "SMTP: %s\n", __FUNCTION__);
-       SendMsg->IO.dport = DefaultMXPort;
+       if (SendMsg->CurrMX) {
+               SendMsg->mx_host = SendMsg->CurrMX->host;
+               SendMsg->CurrMX = SendMsg->CurrMX->next;
+       }
 
-       SendMsg->mx_host = SendMsg->CurrMX->host;
-       SendMsg->CurrMX = SendMsg->CurrMX->next;
+       if (SendMsg->pCurrRelay != NULL) Hostname = SendMsg->pCurrRelay->Host;
+               else if (SendMsg->mx_host != NULL) Hostname = SendMsg->mx_host;
+       else Hostname = SendMsg->node;
+
+       CtdlLogPrintf(CTDL_DEBUG, "SMTP: %s\n", __FUNCTION__);
 
        CtdlLogPrintf(CTDL_DEBUG, 
                      "SMTP client[%ld]: looking up %s : %d ...\n", 
                      SendMsg->n, 
-                     SendMsg->mx_host
+                     Hostname
                      SendMsg->IO.dport);
 
        ares_gethostbyname(SendMsg->IO.DNSChannel,
-                          SendMsg->mx_host,   
+                          Hostname,   
                           AF_INET6, /* it falls back to ipv4 in doubt... */
                           get_one_mx_host_ip_done,
                           &SendMsg->IO);
+       return IO->NextState;
 }
 
 
@@ -415,7 +450,7 @@ eNextState smtp_resolve_mx_done(AsyncIO *IO)
        SendMsg->CurrMX = SendMsg->AllMX = IO->VParsedDNSReply;
        //// TODO: should we remove the current ares context???
        get_one_mx_host_ip(IO);
-       return 0;
+       return IO->NextState;
 }
 
 
@@ -433,9 +468,9 @@ eNextState resolve_mx_records(AsyncIO *IO)
                SendMsg->MyQEntry->Status = 5;
                StrBufPrintf(SendMsg->MyQEntry->StatusMessage, 
                             "No MX hosts found for <%s>", SendMsg->node);
-               return 0; ///////TODO: abort!
+               return IO->NextState;
        }
-       return 0;
+       return eAbort;
 }
 
 
@@ -533,12 +568,14 @@ void smtp_try(OneQueItem *MyQItem,
 
        SendMsg = (SmtpOutMsg *) malloc(sizeof(SmtpOutMsg));
        memset(SendMsg, 0, sizeof(SmtpOutMsg));
-       SendMsg->IO.sock    = (-1);
-       SendMsg->n          = MsgCount++;
-       SendMsg->MyQEntry   = MyQEntry;
-       SendMsg->MyQItem    = MyQItem;
-       SendMsg->pCurrRelay = MyQItem->URL;
-
+       SendMsg->IO.sock      = (-1);
+       SendMsg->IO.NextState = eReadMessage;
+       SendMsg->n            = MsgCount++;
+       SendMsg->MyQEntry     = MyQEntry;
+       SendMsg->MyQItem      = MyQItem;
+       SendMsg->pCurrRelay   = MyQItem->URL;
+
+       SendMsg->IO.dport       = DefaultMXPort;
        SendMsg->IO.Data        = SendMsg;
        SendMsg->IO.SendDone    = SMTP_C_DispatchWriteDone;
        SendMsg->IO.ReadDone    = SMTP_C_DispatchReadDone;
@@ -620,7 +657,8 @@ eNextState SMTPC_read_EHLO_reply(SmtpOutMsg *SendMsg)
        if (SMTP_IS_STATE('2')) {
                SendMsg->State ++;
 
-               if (SendMsg->pCurrRelay->User == NULL)
+               if ((SendMsg->pCurrRelay == NULL) || 
+                   (SendMsg->pCurrRelay->User == NULL))
                        SendMsg->State ++; /* Skip auth... */
        }
        /* else we fall back to 'helo' */
@@ -646,7 +684,8 @@ eNextState SMTPC_read_HELO_reply(SmtpOutMsg *SendMsg)
                else 
                        SMTP_VERROR(5);
        }
-       if (SendMsg->pCurrRelay->User == NULL)
+               if ((SendMsg->pCurrRelay == NULL) || 
+                   (SendMsg->pCurrRelay->User == NULL))
                SendMsg->State ++; /* Skip auth... */
        return eSendReply;
 }
@@ -656,6 +695,10 @@ eNextState SMTPC_send_auth(SmtpOutMsg *SendMsg)
        char buf[SIZ];
        char encoded[1024];
 
+       if ((SendMsg->pCurrRelay == NULL) || 
+           (SendMsg->pCurrRelay->User == NULL))
+               SendMsg->State ++; /* Skip auth, shouldn't even come here!... */
+       else {
        /* Do an AUTH command if necessary */
        sprintf(buf, "%s%c%s%c%s", 
                SendMsg->pCurrRelay->User, '\0', 
@@ -666,7 +709,7 @@ eNextState SMTPC_send_auth(SmtpOutMsg *SendMsg)
                         strlen(SendMsg->pCurrRelay->Pass) + 2, 0);
        StrBufPrintf(SendMsg->IO.SendBuf.Buf,
                     "AUTH PLAIN %s\r\n", encoded);
-
+       }
        SMTP_DBG_SEND();
        return eReadMessage;
 }
@@ -923,7 +966,7 @@ eNextState SMTP_C_Terminate(AsyncIO *IO)
        CtdlLogPrintf(CTDL_DEBUG, "SMTP: %s\n", __FUNCTION__);
        SmtpOutMsg *pMsg = IO->Data;
        FinalizeMessageSend(pMsg);
-       return 0;
+       return eAbort;
 }
 eNextState SMTP_C_Timeout(AsyncIO *IO)
 {
@@ -931,14 +974,14 @@ eNextState SMTP_C_Timeout(AsyncIO *IO)
        SmtpOutMsg *pMsg = IO->Data;
        StrBufPlain(IO->ErrMsg, CKEY(ReadErrors[pMsg->State]));
        FinalizeMessageSend(pMsg);
-       return 0;
+       return eAbort;
 }
 eNextState SMTP_C_ConnFail(AsyncIO *IO)
 {
        CtdlLogPrintf(CTDL_DEBUG, "SMTP: %s\n", __FUNCTION__);
        SmtpOutMsg *pMsg = IO->Data;
        FinalizeMessageSend(pMsg);
-       return 0;
+       return eAbort;
 }
 
 
index 4115cb5223e6b36fe34e7e00097174928a3db3e5..273cc6fb46dfa3b7ce5b1fa5b5524229d2f79066 100644 (file)
@@ -593,7 +593,7 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt)
 
 int ParseURL(ParsedURL **Url, StrBuf *UrlStr, short DefaultPort)
 {
-       const char *pch, *pStartHost, *pEndHost, *pPort, *pCredEnd, *pUserEnd;
+       const char *pch, *pEndHost, *pPort, *pCredEnd, *pUserEnd;
        ParsedURL *url = (ParsedURL *)malloc(sizeof(ParsedURL));
        memset(url, 0, sizeof(ParsedURL));
 
@@ -603,13 +603,13 @@ int ParseURL(ParsedURL **Url, StrBuf *UrlStr, short DefaultPort)
         * http://username:passvoid@[ipv6]:port/url 
         */
        url->URL = NewStrBufDup(UrlStr);
-       pStartHost = pch = ChrPtr(url->URL);
+       url->Host = pch = ChrPtr(url->URL);
        url->LocalPart = strchr(pch, '/');
        if (url->LocalPart != NULL) {
                if ((*(url->LocalPart + 1) == '/') && 
                    (*(url->LocalPart + 2) == ':')) { /* TODO: find default port for this protocol... */
-                       pStartHost = url->LocalPart + 3;
-                       url->LocalPart = strchr(pStartHost, '/');
+                       url->Host = url->LocalPart + 3;
+                       url->LocalPart = strchr(url->Host, '/');
                }
        }
        if (url->LocalPart == NULL) {
@@ -621,8 +621,8 @@ int ParseURL(ParsedURL **Url, StrBuf *UrlStr, short DefaultPort)
                pCredEnd = NULL;
        if (pCredEnd != NULL)
        {
-               url->User = pStartHost;
-               pStartHost = pCredEnd + 1;
+               url->User = url->Host;
+               url->Host = pCredEnd + 1;
                pUserEnd = strchr(url->User, ':');
                
                if (pUserEnd > pCredEnd)
@@ -635,9 +635,9 @@ int ParseURL(ParsedURL **Url, StrBuf *UrlStr, short DefaultPort)
        }
        
        pPort = NULL;
-       if (*pStartHost == '[') {
-               pStartHost ++;
-               pEndHost = strchr(pStartHost, ']');
+       if (*url->Host == '[') {
+               url->Host ++;
+               pEndHost = strchr(url->Host, ']');
                if (pEndHost == NULL) {
                        free(url);
                        return 0; /* invalid syntax, no ipv6 */
@@ -647,13 +647,13 @@ int ParseURL(ParsedURL **Url, StrBuf *UrlStr, short DefaultPort)
                url->af = AF_INET6;
        }
        else {
-               pPort = strchr(pStartHost, ':');
+               pPort = strchr(url->Host, ':');
                if (pPort != NULL)
                        pPort ++;
        }
        if (pPort != NULL)
                url->Port = atol(pPort);
-       url->IsIP = inet_pton(url->af, pStartHost, &url->Addr); 
+       url->IsIP = inet_pton(url->af, url->Host, &url->Addr);  
        return 1;
 }
 /*
index d0543518925f4c5c0be4eda17118ae3aebef4efa..0da68956184dcf1c0b5e0dd29006da1df5e3874e 100644 (file)
@@ -6,6 +6,7 @@ typedef struct ParsedURL ParsedURL;
 struct ParsedURL {
        StrBuf *URL;
        unsigned Port;
+       const char *Host;
        const char *User;
        const char *Pass;
        const char *LocalPart;