From 2b1af802b6361c71b7d2376cc8b5812918beb47f Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Sun, 23 Jan 2011 20:21:20 +0100 Subject: [PATCH] libev migration; relaying implementation - 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 | 56 +++--- citadel/event_client.h | 11 +- citadel/modules/c-ares-dns/serv_c-ares-dns.c | 12 +- citadel/modules/smtp/serv_smtpeventclient.c | 195 +++++++++++-------- citadel/modules/smtp/serv_smtpqueue.c | 22 +-- citadel/modules/smtp/smtpqueue.h | 1 + 6 files changed, 180 insertions(+), 117 deletions(-) diff --git a/citadel/event_client.c b/citadel/event_client.c index 6316a1c4c..4dca578f7 100644 --- a/citadel/event_client.c +++ b/citadel/event_client.c @@ -46,6 +46,8 @@ #include #include #include +#include + #include #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); } diff --git a/citadel/event_client.h b/citadel/event_client.h index 7fe12d1a4..9abda5329 100644 --- a/citadel/event_client.h +++ b/citadel/event_client.h @@ -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); diff --git a/citadel/modules/c-ares-dns/serv_c-ares-dns.c b/citadel/modules/c-ares-dns/serv_c-ares-dns.c index 6c1be1f16..5f8426f98 100644 --- a/citadel/modules/c-ares-dns/serv_c-ares-dns.c +++ b/citadel/modules/c-ares-dns/serv_c-ares-dns.c @@ -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: diff --git a/citadel/modules/smtp/serv_smtpeventclient.c b/citadel/modules/smtp/serv_smtpeventclient.c index 919f97f60..591d5d59d 100644 --- a/citadel/modules/smtp/serv_smtpeventclient.c +++ b/citadel/modules/smtp/serv_smtpeventclient.c @@ -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; } diff --git a/citadel/modules/smtp/serv_smtpqueue.c b/citadel/modules/smtp/serv_smtpqueue.c index 4115cb522..273cc6fb4 100644 --- a/citadel/modules/smtp/serv_smtpqueue.c +++ b/citadel/modules/smtp/serv_smtpqueue.c @@ -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; } /* diff --git a/citadel/modules/smtp/smtpqueue.h b/citadel/modules/smtp/smtpqueue.h index d05435189..0da689561 100644 --- a/citadel/modules/smtp/smtpqueue.h +++ b/citadel/modules/smtp/smtpqueue.h @@ -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; -- 2.30.2