X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fnetwork%2Fserv_networkclient.c;h=8ee884619ef2e6cac7d869acc83e90da17e0be6b;hb=1e62641ed3334a62c2bd58c537cc2a3eb75653f0;hp=51db451989d96192576a3a7aad7998fdb11687c1;hpb=959a32be2ef15652d1be4113bb1b72af24ec030c;p=citadel.git diff --git a/citadel/modules/network/serv_networkclient.c b/citadel/modules/network/serv_networkclient.c index 51db45198..8ee884619 100644 --- a/citadel/modules/network/serv_networkclient.c +++ b/citadel/modules/network/serv_networkclient.c @@ -2,7 +2,7 @@ * This module handles shared rooms, inter-Citadel mail, and outbound * mailing list processing. * - * Copyright (c) 2000-2011 by the citadel.org team + * Copyright (c) 2000-2012 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,22 +91,26 @@ struct CitContext networker_client_CC; #define NODE ChrPtr(((AsyncNetworker*)IO->Data)->node) #define N ((AsyncNetworker*)IO->Data)->n +int NetworkClientDebugEnabled = 0; + +#define DBGLOG(LEVEL) if ((LEVEL != LOG_DEBUG) || (NetworkClientDebugEnabled != 0)) + #define EVN_syslog(LEVEL, FORMAT, ...) \ - syslog(LEVEL, \ + DBGLOG(LEVEL) syslog(LEVEL, \ "IO[%ld]CC[%d]NW[%s][%ld]" FORMAT, \ IO->ID, CCID, NODE, N, __VA_ARGS__) #define EVNM_syslog(LEVEL, FORMAT) \ - syslog(LEVEL, \ + DBGLOG(LEVEL) syslog(LEVEL, \ "IO[%ld]CC[%d]NW[%s][%ld]" FORMAT, \ IO->ID, CCID, NODE, N) #define EVNCS_syslog(LEVEL, FORMAT, ...) \ - syslog(LEVEL, "IO[%ld]NW[%s][%ld]" FORMAT, \ + DBGLOG(LEVEL) syslog(LEVEL, "IO[%ld]NW[%s][%ld]" FORMAT, \ IO->ID, NODE, N, __VA_ARGS__) #define EVNCSM_syslog(LEVEL, FORMAT) \ - syslog(LEVEL, "IO[%ld]NW[%s][%ld]" FORMAT, \ + DBGLOG(LEVEL) syslog(LEVEL, "IO[%ld]NW[%s][%ld]" FORMAT, \ IO->ID, NODE, N) @@ -159,6 +163,10 @@ void DeleteNetworker(void *vptr) FreeStrBuf(&NW->Url); FreeStrBuf(&NW->IO.ErrMsg); FreeAsyncIOContents(&NW->IO); + if (NW->HostLookup.VParsedDNSReply != NULL) { + NW->HostLookup.DNSReplyFree(NW->HostLookup.VParsedDNSReply); + NW->HostLookup.VParsedDNSReply = NULL; + } free(NW); } @@ -266,7 +274,7 @@ eNextState NWC_ReadNDOPReply(AsyncNetworker *NW) NW->IO.IOB.TotalSentAlready = 0; TotalSendSize = atol (ChrPtr(NW->IO.IOBuf) + 4); - EVN_syslog(LOG_DEBUG, "Expecting to transfer %ld bytes\n", NW->IO.IOB.TotalSendSize); + EVN_syslog(LOG_DEBUG, "Expecting to transfer %d bytes\n", TotalSendSize); if (TotalSendSize <= 0) { NW->State = eNUOP - 1; } @@ -310,6 +318,7 @@ eNextState NWC_SendREAD(AsyncNetworker *NW) { FDIOBufferDelete(&NW->IO.IOB); unlink(ChrPtr(NW->tempFileName)); + FDIOBufferDelete(&IO->IOB); return eAbort; } StrBufPrintf(NW->IO.SendBuf.Buf, "READ %ld|%ld\n", @@ -344,6 +353,7 @@ eNextState NWC_ReadREADState(AsyncNetworker *NW) NW->IO.IOB.ChunkSize = atol(ChrPtr(NW->IO.IOBuf)+4); return eReadFile; } + FDIOBufferDelete(&IO->IOB); return eAbort; } eNextState NWC_ReadREADBlobDone(AsyncNetworker *NW); @@ -383,12 +393,11 @@ eNextState NWC_ReadREADBlobDone(AsyncNetworker *NW) eNextState rc; AsyncIO *IO = &NW->IO; /* we don't have any data to debug print here. */ - if (NW->IO.IOB.TotalSendSize == NW->IO.IOB.TotalSentAlready) + if (NW->IO.IOB.TotalSentAlready >= NW->IO.IOB.TotalSendSize) { NW->State ++; FDIOBufferDelete(&NW->IO.IOB); - if (link(ChrPtr(NW->tempFileName), ChrPtr(NW->SpoolFileName)) != 0) { EVN_syslog(LOG_ALERT, "Could not link %s to %s: %s\n", @@ -420,6 +429,7 @@ eNextState NWC_ReadCLOSReply(AsyncNetworker *NW) { AsyncIO *IO = &NW->IO; NWC_DBG_READ(); + FDIOBufferDelete(&IO->IOB); if (ChrPtr(NW->IO.IOBuf)[0] != '2') return eTerminateConnection; return eSendReply; @@ -440,7 +450,7 @@ eNextState NWC_SendNUOP(AsyncNetworker *NW) ChrPtr(NW->node)); StrBufStripSlashes(NW->SpoolFileName, 1); - fd = open(ChrPtr(NW->SpoolFileName), O_RDONLY); + fd = open(ChrPtr(NW->SpoolFileName), O_EXCL|O_NONBLOCK|O_RDONLY); if (fd < 0) { if (errno != ENOENT) { EVN_syslog(LOG_CRIT, @@ -468,6 +478,7 @@ eNextState NWC_SendNUOP(AsyncNetworker *NW) NW->State = eQUIT; rc = NWC_SendQUIT(NW); NWC_DBG_SEND(); + if (fd > 0) close(fd); return rc; } FDIOBufferInit(&NW->IO.IOB, &NW->IO.SendBuf, fd, TotalSendSize); @@ -481,8 +492,10 @@ eNextState NWC_ReadNUOPReply(AsyncNetworker *NW) { AsyncIO *IO = &NW->IO; NWC_DBG_READ(); - if (ChrPtr(NW->IO.IOBuf)[0] != '2') + if (ChrPtr(NW->IO.IOBuf)[0] != '2') { + FDIOBufferDelete(&IO->IOB); return eAbort; + } return eSendReply; } @@ -500,6 +513,7 @@ eNextState NWC_ReadWRITReply(AsyncNetworker *NW) NWC_DBG_READ(); if (ChrPtr(NW->IO.IOBuf)[0] != '7') { + FDIOBufferDelete(&IO->IOB); return eAbort; } @@ -512,7 +526,7 @@ eNextState NWC_SendBlobDone(AsyncNetworker *NW) { AsyncIO *IO = &NW->IO; eNextState rc; - if (IO->IOB.TotalSendSize == NW->IO.IOB.TotalSentAlready) + if (NW->IO.IOB.TotalSentAlready >= IO->IOB.TotalSendSize) { NW->State ++; @@ -548,6 +562,7 @@ eNextState NWC_ReadUCLS(AsyncNetworker *NW) EVN_syslog(LOG_DEBUG, "Removing <%s>\n", ChrPtr(NW->SpoolFileName)); unlink(ChrPtr(NW->SpoolFileName)); } + FDIOBufferDelete(&IO->IOB); return eSendReply; } @@ -913,97 +928,84 @@ void RunNetworker(AsyncNetworker *NW) * Set "full" to nonzero to force a poll of every node, or to zero to poll * only nodes to which we have data to send. */ -void network_poll_other_citadel_nodes(int full_poll, char *working_ignetcfg) +void network_poll_other_citadel_nodes(int full_poll, HashList *ignetcfg) { + const char *key; + long len; + HashPos *Pos; + void *vCfg; AsyncNetworker *NW; - StrBuf *CfgData; - StrBuf *Line; StrBuf *SpoolFileName; - const char *lptr; - const char *CfgPtr; - int Done; int poll = 0; - if ((working_ignetcfg == NULL) || (*working_ignetcfg == '\0')) { + if (GetCount(ignetcfg) ==0) { syslog(LOG_DEBUG, "network: no neighbor nodes are configured - not polling.\n"); return; } become_session(&networker_client_CC); - CfgData = NewStrBufPlain(working_ignetcfg, -1); SpoolFileName = NewStrBufPlain(ctdl_netout_dir, -1); - Line = NewStrBufPlain(NULL, StrLength(CfgData)); - Done = 0; - CfgPtr = NULL; - while (!Done) + + Pos = GetNewHashPos(ignetcfg, 0); + + while (GetNextHashPos(ignetcfg, Pos, &len, &key, &vCfg)) { /* Use the string tokenizer to grab one line at a time */ - StrBufSipLine(Line, CfgData, &CfgPtr); - Done = CfgPtr == StrBufNOTNULL; - if (StrLength(Line) > 0) + if(server_shutting_down) + return;/* TODO free stuff*/ + NodeConf *pNode = (NodeConf*) vCfg; + poll = 0; + NW = (AsyncNetworker*)malloc(sizeof(AsyncNetworker)); + memset(NW, 0, sizeof(AsyncNetworker)); + + NW->node = NewStrBufDup(pNode->NodeName); + NW->host = NewStrBufDup(pNode->Host); + NW->port = NewStrBufDup(pNode->Port); + NW->secret = NewStrBufDup(pNode->Secret); + + if ( (StrLength(NW->node) != 0) && + (StrLength(NW->secret) != 0) && + (StrLength(NW->host) != 0) && + (StrLength(NW->port) != 0)) { - if(server_shutting_down) - return;/* TODO free stuff*/ - lptr = NULL; - poll = 0; - NW = (AsyncNetworker*)malloc(sizeof(AsyncNetworker)); - memset(NW, 0, sizeof(AsyncNetworker)); - - NW->node = NewStrBufPlain(NULL, StrLength(Line)); - NW->host = NewStrBufPlain(NULL, StrLength(Line)); - NW->port = NewStrBufPlain(NULL, StrLength(Line)); - NW->secret = NewStrBufPlain(NULL, StrLength(Line)); - - StrBufExtract_NextToken(NW->node, Line, &lptr, '|'); - StrBufExtract_NextToken(NW->secret, Line, &lptr, '|'); - StrBufExtract_NextToken(NW->host, Line, &lptr, '|'); - StrBufExtract_NextToken(NW->port, Line, &lptr, '|'); - if ( (StrLength(NW->node) != 0) && - (StrLength(NW->secret) != 0) && - (StrLength(NW->host) != 0) && - (StrLength(NW->port) != 0)) + poll = full_poll; + if (poll == 0) { - poll = full_poll; - if (poll == 0) - { - StrBufAppendBufPlain(SpoolFileName, HKEY("/"), 0); - StrBufAppendBuf(SpoolFileName, NW->node, 0); - StrBufStripSlashes(SpoolFileName, 1); - - if (access(ChrPtr(SpoolFileName), R_OK) == 0) { - poll = 1; - } + StrBufAppendBufPlain(SpoolFileName, HKEY("/"), 0); + StrBufAppendBuf(SpoolFileName, NW->node, 0); + StrBufStripSlashes(SpoolFileName, 1); + + if (access(ChrPtr(SpoolFileName), R_OK) == 0) { + poll = 1; } } - if (poll && - (StrLength(NW->host) > 0) && - strcmp("0.0.0.0", ChrPtr(NW->host))) + } + if (poll && + (StrLength(NW->host) > 0) && + strcmp("0.0.0.0", ChrPtr(NW->host))) + { + NW->Url = NewStrBuf(); + StrBufPrintf(NW->Url, "citadel://:%s@%s:%s", + ChrPtr(NW->secret), + ChrPtr(NW->host), + ChrPtr(NW->port)); + if (!network_talking_to(SKEY(NW->node), NTT_CHECK)) { - NW->Url = NewStrBufPlain(NULL, StrLength(Line)); - StrBufPrintf(NW->Url, "citadel://:%s@%s:%s", - ChrPtr(NW->secret), - ChrPtr(NW->host), - ChrPtr(NW->port)); - if (!network_talking_to(SKEY(NW->node), NTT_CHECK)) - { - RunNetworker(NW); - continue; - } + RunNetworker(NW); + continue; } - DeleteNetworker(NW); } + DeleteNetworker(NW); } FreeStrBuf(&SpoolFileName); - FreeStrBuf(&CfgData); - FreeStrBuf(&Line); - + DeleteHashPos(&Pos); } void network_do_clientqueue(void) { - char *working_ignetcfg; + HashList *working_ignetcfg; int full_processing = 1; static time_t last_run = 0L; @@ -1018,19 +1020,20 @@ void network_do_clientqueue(void) ); } - working_ignetcfg = load_working_ignetcfg(); + working_ignetcfg = load_ignetcfg(); /* * Poll other Citadel nodes. Maybe. If "full_processing" is set * then we poll everyone. Otherwise we only poll nodes we have stuff * to send to. */ network_poll_other_citadel_nodes(full_processing, working_ignetcfg); - if (working_ignetcfg) - free(working_ignetcfg); + DeleteHash(&working_ignetcfg); } - - +void LogDebugEnableNetworkClient(const int n) +{ + NetworkClientDebugEnabled = n; +} /* * Module entry point */ @@ -1041,6 +1044,8 @@ CTDL_MODULE_INIT(network_client) CtdlFillSystemContext(&networker_client_CC, "CitNetworker"); CtdlRegisterSessionHook(network_do_clientqueue, EVT_TIMER); + CtdlRegisterDebugFlagHook(HKEY("networkclient"), LogDebugEnableNetworkClient, &NetworkClientDebugEnabled); + } - return "network_client"; + return "networkclient"; }