int NetworkClientDebugEnabled = 0;
-#define DBGLOG(LEVEL) if ((LEVEL != LOG_DEBUG) || (NetworkClientDebugEnabled != 0))
+#define NCDBGLOG(LEVEL) if ((LEVEL != LOG_DEBUG) || (NetworkClientDebugEnabled != 0))
-#define EVN_syslog(LEVEL, FORMAT, ...) \
- DBGLOG(LEVEL) syslog(LEVEL, \
- "IO[%ld]CC[%d]NW[%s][%ld]" FORMAT, \
- IO->ID, CCID, NODE, N, __VA_ARGS__)
+#define EVN_syslog(LEVEL, FORMAT, ...) \
+ NCDBGLOG(LEVEL) syslog(LEVEL, \
+ "IO[%ld]CC[%d]NW[%s][%ld]" FORMAT, \
+ IO->ID, CCID, NODE, N, __VA_ARGS__)
-#define EVNM_syslog(LEVEL, FORMAT) \
- DBGLOG(LEVEL) syslog(LEVEL, \
- "IO[%ld]CC[%d]NW[%s][%ld]" FORMAT, \
- IO->ID, CCID, NODE, N)
+#define EVNM_syslog(LEVEL, FORMAT) \
+ NCDBGLOG(LEVEL) syslog(LEVEL, \
+ "IO[%ld]CC[%d]NW[%s][%ld]" FORMAT, \
+ IO->ID, CCID, NODE, N)
#define EVNCS_syslog(LEVEL, FORMAT, ...) \
- DBGLOG(LEVEL) syslog(LEVEL, "IO[%ld]NW[%s][%ld]" FORMAT, \
- IO->ID, NODE, N, __VA_ARGS__)
+ NCDBGLOG(LEVEL) syslog(LEVEL, "IO[%ld]NW[%s][%ld]" FORMAT, \
+ IO->ID, NODE, N, __VA_ARGS__)
#define EVNCSM_syslog(LEVEL, FORMAT) \
- DBGLOG(LEVEL) syslog(LEVEL, "IO[%ld]NW[%s][%ld]" FORMAT, \
- IO->ID, NODE, N)
+ NCDBGLOG(LEVEL) syslog(LEVEL, "IO[%ld]NW[%s][%ld]" FORMAT, \
+ IO->ID, NODE, N)
typedef enum _eNWCState {
#define NWC_DBG_READ() EVN_syslog(LOG_DEBUG, ": < %s\n", ChrPtr(NW->IO.IOBuf))
#define NWC_OK (strncasecmp(ChrPtr(NW->IO.IOBuf), "+OK", 3) == 0)
+eNextState SendFailureMessage(AsyncIO *IO)
+{
+ AsyncNetworker *NW = IO->Data;
+ long lens[2];
+ const char *strs[2];
+
+ strs[0] = ChrPtr(NW->node);
+ lens[0] = StrLength(NW->node);
+
+ strs[1] = ChrPtr(NW->IO.ErrMsg);
+ lens[1] = StrLength(NW->IO.ErrMsg);
+ CtdlAideFPMessage(
+ ChrPtr(NW->IO.ErrMsg),
+ "Networker error",
+ 2, strs, (long*) &lens);
+
+ return eAbort;
+}
+
eNextState FinalizeNetworker(AsyncIO *IO)
{
AsyncNetworker *NW = (AsyncNetworker *)IO->Data;
"Connected to node \"%s\" but I was expecting to connect to node \"%s\".",
connected_to, ChrPtr(NW->node));
EVN_syslog(LOG_ERR, "%s\n", ChrPtr(NW->IO.ErrMsg));
- CtdlAideMessage(ChrPtr(NW->IO.ErrMsg), "Network error");
- return eAbort;/// todo: aide message in anderer queue speichern
+ StopClientWatchers(IO, 1);
+ return QueueDBOperation(IO, SendFailureMessage);
}
return eSendReply;
}
}
else
{
+ int Error = atol(ChrPtr(NW->IO.IOBuf));
if (NW->IO.ErrMsg == NULL)
NW->IO.ErrMsg = NewStrBuf();
StrBufPrintf(NW->IO.ErrMsg,
- "Connected to node \"%s\" but my secret wasn't accurate.",
- ChrPtr(NW->node));
- EVN_syslog(LOG_ERR, "%s\n", ChrPtr(NW->IO.ErrMsg));
- CtdlAideMessage(ChrPtr(NW->IO.ErrMsg), "Network error");
-
+ "Connected to node \"%s\" but my secret wasn't accurate.\nReason was:%s\n",
+ ChrPtr(NW->node), ChrPtr(NW->IO.IOBuf) + 4);
+ if (Error == 552) {
+ EVN_syslog(LOG_INFO,
+ "Already talking to %s; skipping this time.\n",
+ ChrPtr(NW->node));
+
+ }
+ else {
+ EVN_syslog(LOG_ERR, "%s\n", ChrPtr(NW->IO.ErrMsg));
+ StopClientWatchers(IO, 1);
+ return QueueDBOperation(IO, SendFailureMessage);
+ }
return eAbort;
}
}
NW->IO.IOB.TotalSentAlready = 0;
TotalSendSize = atol (ChrPtr(NW->IO.IOBuf) + 4);
- EVN_syslog(LOG_DEBUG, "Expecting to transfer %ld bytes\n", TotalSendSize);
+ EVN_syslog(LOG_DEBUG, "Expecting to transfer %d bytes\n", TotalSendSize);
if (TotalSendSize <= 0) {
NW->State = eNUOP - 1;
}
{
FDIOBufferDelete(&NW->IO.IOB);
unlink(ChrPtr(NW->tempFileName));
+ FDIOBufferDelete(&IO->IOB);
return eAbort;
}
StrBufPrintf(NW->IO.SendBuf.Buf, "READ %ld|%ld\n",
NW->IO.IOB.ChunkSize = atol(ChrPtr(NW->IO.IOBuf)+4);
return eReadFile;
}
+ FDIOBufferDelete(&IO->IOB);
return eAbort;
}
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",
{
AsyncIO *IO = &NW->IO;
NWC_DBG_READ();
+ FDIOBufferDelete(&IO->IOB);
if (ChrPtr(NW->IO.IOBuf)[0] != '2')
return eTerminateConnection;
return eSendReply;
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,
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);
{
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;
}
NWC_DBG_READ();
if (ChrPtr(NW->IO.IOBuf)[0] != '7')
{
+ FDIOBufferDelete(&IO->IOB);
return eAbort;
}
{
AsyncIO *IO = &NW->IO;
eNextState rc;
- if (IO->IOB.TotalSendSize == NW->IO.IOB.TotalSentAlready)
+ if (NW->IO.IOB.TotalSentAlready >= IO->IOB.TotalSendSize)
{
NW->State ++;
EVN_syslog(LOG_DEBUG, "Removing <%s>\n", ChrPtr(NW->SpoolFileName));
unlink(ChrPtr(NW->SpoolFileName));
}
+ FDIOBufferDelete(&IO->IOB);
return eSendReply;
}
eNextState NWC_FailNetworkConnection(AsyncIO *IO)
{
- return eAbort;
+ StopClientWatchers(IO, 1);
+ return QueueDBOperation(IO, SendFailureMessage);
}
void NWC_SetTimeout(eNextState NextTCPState, AsyncNetworker *NW)
strcmp("0.0.0.0", ChrPtr(NW->host)))
{
NW->Url = NewStrBuf();
- StrBufPrintf(NW->Url, "citadel://:%s@%s:%s",
+ StrBufPrintf(NW->Url, "citadel://%s@%s:%s",
ChrPtr(NW->secret),
ChrPtr(NW->host),
ChrPtr(NW->port));
{
CtdlFillSystemContext(&networker_client_CC, "CitNetworker");
- CtdlRegisterSessionHook(network_do_clientqueue, EVT_TIMER);
+ CtdlRegisterSessionHook(network_do_clientqueue, EVT_TIMER, PRIO_SEND + 10);
CtdlRegisterDebugFlagHook(HKEY("networkclient"), LogDebugEnableNetworkClient, &NetworkClientDebugEnabled);
}