From dae2bbc7215a8361e7b9092e6c307491c7e5722a Mon Sep 17 00:00:00 2001 From: Dave Hibberd Date: Wed, 7 Jan 2026 21:45:15 +0000 Subject: [PATCH] New upstream version 6.0.25.15+repack --- APRSCode.c | 2 - BBSHTMLConfig.c | 4 +- BBSUtilities.c | 6 +- BPQINP3.c | 339 +++++++++++++++++++++++++++++++++++++++--------- BPQMailConfig.c | 6 +- Bpq32.c | 4 + Cmd.c | 40 +++++- FreeDATA.c | 4 +- HTTPcode.c | 37 +++--- Housekeeping.c | 14 +- L2Code.c | 49 ++++++- MHSave.txt | 0 Moncode.c | 5 +- NETROMTCP.c | 172 ++++++++++++++++++------ RHP.c | 6 + TelnetV6.c | 27 ++-- Versions.h | 6 +- WINMOR.c | 4 +- WinRPR.c | 4 +- asmstrucs.h | 21 +-- bpqmail.h | 2 +- cMain.c | 34 ++++- config.c | 24 +++- configstructs.h | 3 + datadefs.c | 2 +- telnetserver.h | 1 + 26 files changed, 629 insertions(+), 187 deletions(-) create mode 100644 MHSave.txt diff --git a/APRSCode.c b/APRSCode.c index d236fc4..5f93809 100644 --- a/APRSCode.c +++ b/APRSCode.c @@ -441,8 +441,6 @@ HANDLE hMapFile; // Logging -static int LogAge = 14; - int APRSWriteLog(char * msg) { FILE *file; diff --git a/BBSHTMLConfig.c b/BBSHTMLConfig.c index b0b398c..05a08bb 100644 --- a/BBSHTMLConfig.c +++ b/BBSHTMLConfig.c @@ -1456,7 +1456,7 @@ VOID SaveHousekeeping(struct HTTPConnectionInfo * Session, char * MsgPtr, char * GetParam(input, "MaxAge=", Temp); MaxAge = atoi(Temp); GetParam(input, "LogLife=", Temp); - LogAge = atoi(Temp); + BBSLogAge = atoi(Temp); GetParam(input, "UserLife=", Temp); UserLifetime= atoi(Temp); @@ -2666,7 +2666,7 @@ VOID SendHouseKeeping(char * Reply, int * ReplyLen, char * Key) *ReplyLen = sprintf(Reply, HousekeepingTemplate, BBSName, Key, Key, Key, Key, Key, Key, Key, Key, Key, - MaintTime, MaintInterval, MaxMsgno, BidLifetime, LogAge, UserLifetime, + MaintTime, MaintInterval, MaxMsgno, BidLifetime, BBSLogAge, UserLifetime, (DeletetoRecycleBin) ? CHKD : UNC, (SendNonDeliveryMsgs) ? CHKD : UNC, (SuppressMaintEmail) ? CHKD : UNC, diff --git a/BBSUtilities.c b/BBSUtilities.c index e6f7ade..a6684d4 100644 --- a/BBSUtilities.c +++ b/BBSUtilities.c @@ -9939,8 +9939,8 @@ VOID SaveConfig(char * ConfigName) SaveIntValue(group, "MaxMsgno", MaxMsgno); SaveIntValue(group, "BidLifetime", BidLifetime); SaveIntValue(group, "MaxAge", MaxAge); - SaveIntValue(group, "LogLifetime", LogAge); - SaveIntValue(group, "LogLifetime", LogAge); + SaveIntValue(group, "LogLifetime", BBSLogAge); + SaveIntValue(group, "LogLifetime", BBSLogAge); SaveIntValue(group, "MaintInterval", MaintInterval); SaveIntValue(group, "UserLifetime", UserLifetime); SaveIntValue(group, "MaintTime", MaintTime); @@ -10601,7 +10601,7 @@ BOOL GetConfig(char * ConfigName) LastHouseKeepingTime = GetIntValue(group, "LastHouseKeepingTime"); LastTrafficTime = GetIntValue(group, "LastTrafficTime"); MaxMsgno = GetIntValue(group, "MaxMsgno"); - LogAge = GetIntValue(group, "LogLifetime"); + BBSLogAge = GetIntValue(group, "LogLifetime"); BidLifetime = GetIntValue(group, "BidLifetime"); MaxAge = GetIntValue(group, "MaxAge"); if (MaxAge == 0) diff --git a/BPQINP3.c b/BPQINP3.c index 86bfc96..3fcf1ae 100644 --- a/BPQINP3.c +++ b/BPQINP3.c @@ -37,13 +37,19 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses extern int DEBUGINP3; -int NegativePercent = 110; // if time is 10% worse send negative info +int NegativePercent = 120; // if time is 10% worse send negative info int PositivePercent = 80; // if time is 20% better send positive info +int NegativeDelay = 10; // Seconds between checks for negative info - should be quite shourt +int PositiveDelay = 300; + +time_t SENDRIFTIME = 0; +int RIFInterval = 60; VOID SendNegativeInfo(); VOID SortRoutes(struct DEST_LIST * Dest); VOID SendRTTMsg(struct ROUTE * Route); VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame); +void NETROMCloseTCP(struct ROUTE * Route); static VOID SendNetFrame(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) { @@ -105,7 +111,8 @@ struct _RTTMSG RTTMsg = {""}; //struct ROUTE DummyRoute = {"","",""}; int RIPTimerCount = 0; // 1 sec to 10 sec counter -int PosTimerCount = 0; // 1 sec to 5 Mins counter +int PosTimerCount = 0; +int NegTimerCount = 0; // Timer Runs every 10 Secs @@ -122,6 +129,8 @@ VOID InitialiseRTT() { UCHAR temp[256] = ""; + SENDRIFTIME = time(NULL); + memset(&RTTMsg, ' ', sizeof(struct _RTTMSG)); memcpy(RTTMsg.ID, "L3RTT: ", 7); memcpy(RTTMsg.VERSION, "LEVEL3_V2.1 ", 12); @@ -170,7 +179,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route) Route->Status = 0; Route->Timeout = 0; Route->NeighbourSRTT = 0; - + Route->localport = 0; Dest--; // Delete any Dest entries via this Route @@ -215,7 +224,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route) continue; } - Dest->INP3ROUTE[1].LastTT = Dest->INP3ROUTE[0].STT; // So next scan will check if rtt has increaced enough to need a RIF + Dest->INP3ROUTE[1].RouteLastTT[Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->recNum] = Dest->INP3ROUTE[0].STT; // So next scan will check if rtt has increaced enough to need a RIF memcpy(&Dest->INP3ROUTE[0], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memcpy(&Dest->INP3ROUTE[1], &Dest->INP3ROUTE[2], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memset(&Dest->INP3ROUTE[2], 0, sizeof(struct INP3_DEST_ROUTE_ENTRY)); @@ -571,7 +580,10 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops, Dest->INP3ROUTE[0].Hops = hops; Dest->INP3ROUTE[0].STT = rtt; - Dest->INP3ROUTE[0].LastTT = 0; + if (Dest->INP3ROUTE[0].RouteLastTT == 0) + Dest->INP3ROUTE[0].RouteLastTT = (uint16_t *)zalloc(MAXNEIGHBOURS * sizeof(uint16_t)); + + Dest->INP3ROUTE[0].RouteLastTT[Route->recNum] = 0; Dest->INP3FLAGS = NewNode; @@ -696,7 +708,10 @@ Found: VOID AddHere(struct INP3_DEST_ROUTE_ENTRY * ROUTEPTR,struct ROUTE * Route , int hops, int rtt) { ROUTEPTR->Hops = hops; - ROUTEPTR->LastTT = 0; + if (ROUTEPTR->RouteLastTT == 0) + ROUTEPTR->RouteLastTT = (uint16_t *)zalloc(MAXNEIGHBOURS * sizeof(uint16_t)); + + ROUTEPTR->RouteLastTT[Route->recNum] = 0; ROUTEPTR->STT = rtt; ROUTEPTR->ROUT_NEIGHBOUR = Route; @@ -874,6 +889,16 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len return; } + // Check TTL + + if (Buff->L3TTL < 2) + { + ReleaseBuffer(Buff); + return; + } + + Buff->L3TTL--; + if (Route->NEIGHBOUR_LINK->LINKPORT && (Route->NEIGHBOUR_LINK->LINKPORT->ALLOWINP3 || Route->NEIGHBOUR_LINK->LINKPORT->ENABLEINP3)) Route->INP3Node = 1; @@ -1084,17 +1109,11 @@ VOID SendOurRIF(struct ROUTE * Route) int totLen = 1; int App; APPLCALLS * APPL; - char Normcall[10]; Msg = GetBuff(); if (Msg == 0) return; - - Normcall[ConvFromAX25(Route->NEIGHBOUR_LINK->LINKCALL, Normcall)] = 0; - if (DEBUGINP3) Debugprintf("INP3 Sending Initial RIF to %s ", Normcall); - - Msg->L3SRCE[0] = 0xff; // send a RIF for our Node and all our APPLCalls @@ -1188,13 +1207,13 @@ int SendRIPTimer() Route->ConnectionAttempts++; - if (Route->INP3Node) + if (Route->INP3Node && ((Route->TCPPort == 0 || strcmp(Route->TCPHost, "0.0.0.0") != 0))) { Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0; if (DEBUGINP3) Debugprintf("INP3 Activating link to %s", Normcall); } - L2SETUPCROSSLINKEX(Route, 2); // Only try SABM twice + L2SETUPCROSSLINKEX(Route, 2); // Only try SABM/XID twice Route->NeighbourSRTT = 0; // just in case! Route->BCTimer = 0; @@ -1272,6 +1291,12 @@ int SendRIPTimer() Route->NEIGHBOUR_LINK->L2TIMER = 1; // TO FORCE DISC Route->NEIGHBOUR_LINK->L2STATE = 4; // DISCONNECTING } + else + { + // but we should reset the TCP connection + + NETROMCloseTCP(Route); + } } Route->BCTimer = 5; // Wait a while before retrying @@ -1327,74 +1352,101 @@ VOID SendRIF(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Msg) SendNetFrame(Route, Msg); } -VOID SendRIFToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_ROUTE_ENTRY * Entry, int Negative) +VOID SendRIFToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_ROUTE_ENTRY * Entry, int Negative, int portNum) { struct ROUTE * Routes = NEIGHBOURS; struct _L3MESSAGEBUFFER * Msg; int count, MaxRoutes = MAXNEIGHBOURS; - char Normcall[10]; - char Normcall2[10]; + char NodeCall[10]; + char destCall[10]; + int sendHops, sendTT, lastTT; - int sent = 0; - Normcall[ConvFromAX25(axcall, Normcall)] = 0; + // if portNum is set sending a periodic refresh. Just sent to this port + NodeCall[ConvFromAX25(axcall, NodeCall)] = 0; for (count = 0; count < MaxRoutes; count++) { if ((Entry->ROUT_NEIGHBOUR && Routes->INP3Node) && (Routes->Status) && + // (memcmp(Routes->NEIGHBOUR_CALL (Routes != Entry->ROUT_NEIGHBOUR)) // Dont send to originator of route { + // as the value sent will be different for each link, we need to check if change is enough here sendHops = Entry->Hops + 1; sendTT = Entry->STT + Entry->ROUT_NEIGHBOUR->RTTIncrement; - lastTT = Entry->LastTT + Entry->LastNeighbourTT; + lastTT = Entry->RouteLastTT[Entry->ROUT_NEIGHBOUR->recNum]; - if (Negative) - { - // only send if significantly worse - - if (sendTT < (lastTT * NegativePercent) / 100) + if (!portNum) + { + if (Negative) { - Routes+=1; - continue; - } - } - else - { - // Send if significantly better + // only send if significantly worse - if (sendTT > (lastTT * PositivePercent) / 100) - { - Routes+=1; - continue; + if (sendTT < (lastTT * NegativePercent) / 100) + { + Routes+=1; + continue; + } } + else + { + // Send if significantly better + + if (sendTT > (lastTT * PositivePercent) / 100) + { + Routes+=1; + continue; + } + } + } - sent++; + // Don't send if Node is the Neighbour we are sending to + if (memcmp(Routes->NEIGHBOUR_CALL, axcall, 7) == 0) + { + if (DEBUGINP3) Debugprintf("INP3 SendRIFToOtherNeighbours Don't send %s to itself", NodeCall); + Routes+=1; + continue; + } - if (DEBUGINP3) Debugprintf("INP3 SendRIFToOtherNeighbours for %s", Normcall); + if (portNum && Routes->NEIGHBOUR_PORT != portNum) + { + Routes+=1; + continue; + } - if (DEBUGINP3) Debugprintf("INP3 %s Old RTT %d Old NRTT %d New %d %d Sufficent change so sending if in other ends limits", - Normcall, Entry->LastTT, Entry->LastNeighbourTT, sendTT, Entry->ROUT_NEIGHBOUR->RTTIncrement); + if (portNum) + Routes->Status &= ~SentOurRIF; - Entry->LastTT = Entry->STT; - Entry->LastNeighbourTT = Entry->ROUT_NEIGHBOUR->RTTIncrement; + Entry->RouteLastTT[Entry->ROUT_NEIGHBOUR->recNum] = sendTT; // send, but only if within their constraints if ((Routes->RemoteMAXHOPS == 0 || Routes->RemoteMAXHOPS >= Entry->Hops) && - (Routes->RemoteMAXRTT == 0 || Routes->RemoteMAXRTT >= Entry->STT || Entry->STT == 60000)) + (Routes->RemoteMAXRTT == 0 || Routes->RemoteMAXRTT >= sendTT || sendTT == 60000)) { + if (DEBUGINP3) + { + if (portNum) + Debugprintf("INP3 %s Timer Refresh Sending to port %d", NodeCall, portNum); + else + Debugprintf("INP3 %s Old TT %d New %d Sufficent change so sending ", NodeCall, lastTT, sendTT); + } + Msg = Routes->Msg; if (Msg == NULL) { - Normcall2[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall2)] = 0; - if (DEBUGINP3) Debugprintf("INP3 Building RIF to send to %s", Normcall2); + if (DEBUGINP3) + { + destCall[ConvFromAX25(Entry->ROUT_NEIGHBOUR->NEIGHBOUR_CALL, destCall)] = 0; + Debugprintf("INP3 Building RIF to send to %s", destCall); + } Msg = Routes->Msg = CreateRIFHeader(Routes); } @@ -1402,12 +1454,12 @@ VOID SendRIFToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_RO { if (Routes->OldBPQ) Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], - axcall, alias, sendHops, sendTT + 10); + axcall, alias, sendHops, sendTT + 10); else Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], - axcall, alias, sendHops, sendTT); + axcall, alias, sendHops, sendTT); + - if (Msg->LENGTH > 250 - 15) // if (Msg->LENGTH > Routes->NBOUR_PACLEN - 11) { @@ -1418,13 +1470,9 @@ VOID SendRIFToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_RO } } - + Routes+=1; } - - if (sent) - Debugprintf("INP3 End of Loop %s Old RTT %d Old NRTT %d ", Normcall, Entry->LastTT, Entry->LastNeighbourTT); - } VOID SendRIFToNewNeighbour(struct ROUTE * Route) @@ -1456,9 +1504,9 @@ VOID SendRIFToNewNeighbour(struct ROUTE * Route) // Best Route not via this neighbour - send, but only if within their constraints sendHops = Entry->Hops + 1; - Entry->LastTT = Entry->STT; sendTT = Entry->STT + Entry->ROUT_NEIGHBOUR->RTTIncrement; + Entry->RouteLastTT[Entry->ROUT_NEIGHBOUR->recNum] = sendTT; if ((Route->RemoteMAXHOPS == 0 || Route->RemoteMAXHOPS >= Entry->Hops) && (Route->RemoteMAXRTT == 0 || Route->RemoteMAXRTT >= Entry->STT || Entry->STT == 60000)) @@ -1547,10 +1595,11 @@ VOID SendNegativeInfo() if (Entry->ROUT_NEIGHBOUR == 0) continue; - if (Entry->LastTT == 0) // if zero haven't yet reported +ve info. Shouldn't really be reporting negative without positive but just in case - SendRIFToOtherNeighbours(Dest->DEST_CALL, Dest->DEST_ALIAS, Entry, TRUE); + + if (Entry->RouteLastTT[Entry->ROUT_NEIGHBOUR->recNum] == 0) // if zero haven't yet reported +ve info. Shouldn't really be reporting negative without positive but just in case + SendRIFToOtherNeighbours(Dest->DEST_CALL, Dest->DEST_ALIAS, Entry, TRUE, FALSE); else - SendRIFToOtherNeighbours(Dest->DEST_CALL, 0, Entry, TRUE); + SendRIFToOtherNeighbours(Dest->DEST_CALL, 0, Entry, TRUE, FALSE); if (Entry->STT >= 60000) { @@ -1591,8 +1640,11 @@ VOID SendPositiveInfo() { Dest++; + if (Dest->DEST_CALL[0] == 0) // unused entry + continue; + Entry = &Dest->INP3ROUTE[0]; - SendRIFToOtherNeighbours(Dest->DEST_CALL, 0, Entry, FALSE); + SendRIFToOtherNeighbours(Dest->DEST_CALL, 0, Entry, FALSE, FALSE); } } @@ -1616,11 +1668,169 @@ VOID SendNewInfo() Entry = &Dest->INP3ROUTE[0]; - SendRIFToOtherNeighbours(Dest->DEST_CALL, Dest->DEST_ALIAS, Entry, FALSE); + SendRIFToOtherNeighbours(Dest->DEST_CALL, Dest->DEST_ALIAS, Entry, FALSE, FALSE); } } } +// Refresh RIF entries for each route. Shouldn't be necessary, but add for now + +int routeCount = 0; +struct ROUTE * Route = NULL; + +VOID sendAlltoOneNeigbour(struct ROUTE * Route) +{ + char Call[10]; + struct DEST_LIST * Dest = DESTS; + struct INP3_DEST_ROUTE_ENTRY * Entry; + + int i; + struct _L3MESSAGEBUFFER * Msg; + int sendHops, sendTT, lastTT; + APPLCALLS * APPL; + int App; + + Call[ConvFromAX25(Route->NEIGHBOUR_CALL, Call)] = 0; + + if (DEBUGINP3) Debugprintf("INP3 Manual send RIF to %s", Call); + + // send a RIF for our Node and all our APPLCalls + + Msg = Route->Msg; + + if (Msg == NULL) + Msg = Route->Msg = CreateRIFHeader(Route); + + if (Msg == 0) + return; + + if (Route->OldBPQ) + Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], MYCALL, MYALIASTEXT, 1, Route->RTTIncrement * 10); + else + Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], MYCALL, MYALIASTEXT, 1, Route->RTTIncrement); + + for (App = 0; App < NumberofAppls; App++) + { + APPL=&APPLCALLTABLE[App]; + + if (APPL->APPLQUAL > 0) + { + if (Route->OldBPQ) + Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], APPL->APPLCALL, APPL->APPLALIAS_TEXT, 1, Route->RTTIncrement * 10); + else + Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], APPL->APPLCALL, APPL->APPLALIAS_TEXT, 1, Route->RTTIncrement); + + } + } + + // Send all dests that have this route as their best inp3 route + + Dest--; + + for (i=0; i < MAXDESTS; i++) + { + Dest++; + + Entry = &Dest->INP3ROUTE[0]; + + if (Entry->ROUT_NEIGHBOUR == 0) + continue; + + if (Entry->ROUT_NEIGHBOUR && Route->INP3Node && Route->Status && Route != Entry->ROUT_NEIGHBOUR) // Dont send to originator of route + { + // as the value sent will be different for each link, we need to check if change is enough here + + // Don't send if Node is the Neighbour we are sending to + + if (memcmp(Route->NEIGHBOUR_CALL, Dest->DEST_CALL, 7) == 0) + { + if (DEBUGINP3) Debugprintf("INP3 Timer RIF Don't send %s to itself", Call); + Route++; + continue; + } + + sendHops = Entry->Hops + 1; + sendTT = Entry->STT + Entry->ROUT_NEIGHBOUR->RTTIncrement; + lastTT = Entry->RouteLastTT[Entry->ROUT_NEIGHBOUR->recNum]; + + Entry->RouteLastTT[Entry->ROUT_NEIGHBOUR->recNum] = sendTT; + + // send, but only if within their constraints + + if ((Route->RemoteMAXHOPS == 0 || Route->RemoteMAXHOPS >= Entry->Hops) && (Route->RemoteMAXRTT == 0 || Route->RemoteMAXRTT >= sendTT)) + { + Msg = Route->Msg; + + if (Msg == NULL) + Msg = Route->Msg = CreateRIFHeader(Route); + + if (Msg) + { + if (Route->OldBPQ) + sendTT *= 10; + + Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], Dest->DEST_CALL, Dest->DEST_ALIAS, sendHops, sendTT); + + if (Msg->LENGTH > 250 - 15) + { + SendRIF(Route, Msg); + Route->Msg = NULL; + } + } + } + } + } + + if (Route->Msg) + { + SendRIF(Route, Route->Msg); + Route->Msg = NULL; + } +} + + +VOID SendAllInfo() +{ + time_t Now = time(NULL); + + if (routeCount == 0) // Not sending + { + if (RIFInterval == 0 || (Now - SENDRIFTIME) < RIFInterval) // Time for new send? + return; + + Route = NEIGHBOURS; + } + + // Build RIF + + while (Route->INP3Node == 0) + { + Route++; + routeCount++; + + if (routeCount == MAXNEIGHBOURS) + { + //cycle finished + + SENDRIFTIME = Now; + routeCount = 0; + return; + } + } + + sendAlltoOneNeigbour(Route); + + Route++; + routeCount++; + + if (routeCount == MAXNEIGHBOURS) + { + //cycle finished + + SENDRIFTIME = Now; + routeCount = 0; + } +} VOID INP3TIMER() { @@ -1643,20 +1853,27 @@ VOID INP3TIMER() #endif - SendNegativeInfo(); // Urgent + if (NegTimerCount == 0) + { + NegTimerCount = NegativeDelay; + SendNegativeInfo(); + } + else + NegTimerCount--; if (RIPTimerCount == 0) { RIPTimerCount = 10; SendNewInfo(); // Not quite so urgent SendRIPTimer(); + SendAllInfo(); // Timer Driven refresh } else RIPTimerCount--; if (PosTimerCount == 0) { - PosTimerCount = 300; // 5 mins + PosTimerCount = PositiveDelay; SendPositiveInfo(); } else diff --git a/BPQMailConfig.c b/BPQMailConfig.c index 06aec1d..1f7fc2e 100644 --- a/BPQMailConfig.c +++ b/BPQMailConfig.c @@ -731,7 +731,7 @@ VOID WINAPI OnSelChanged(HWND hwndDlg) SetDlgItemInt(pHdr->hwndDisplay, IDC_MAXMSG, MaxMsgno, FALSE); SetDlgItemInt(pHdr->hwndDisplay, IDC_BIDLIFETIME, BidLifetime, FALSE); SetDlgItemInt(pHdr->hwndDisplay, IDC_USERLIFETIME, UserLifetime, FALSE); - SetDlgItemInt(pHdr->hwndDisplay, IDC_LOGLIFETIME, LogAge, FALSE); + SetDlgItemInt(pHdr->hwndDisplay, IDC_LOGLIFETIME, BBSLogAge, FALSE); SetDlgItemInt(pHdr->hwndDisplay, IDC_MAINTINTERVAL, MaintInterval, FALSE); sprintf(Time, "%04d", MaintTime); SetDlgItemText(pHdr->hwndDisplay, IDC_MAINTTIME, Time); @@ -1979,7 +1979,7 @@ VOID SaveMAINTConfigFromDialog() if (MaxMsgno > 99000) MaxMsgno = 99000; BidLifetime = GetDlgItemInt(hwndDisplay, IDC_BIDLIFETIME, &OK1, FALSE); - LogAge = GetDlgItemInt(hwndDisplay, IDC_LOGLIFETIME, &OK1, FALSE); + BBSLogAge = GetDlgItemInt(hwndDisplay, IDC_LOGLIFETIME, &OK1, FALSE); UserLifetime = GetDlgItemInt(hwndDisplay, IDC_USERLIFETIME, &OK1, FALSE); MaintInterval = GetDlgItemInt(hwndDisplay, IDC_MAINTINTERVAL, &OK1, FALSE); MaintTime = GetDlgItemInt(hwndDisplay, IDC_MAINTTIME, &OK1, FALSE); @@ -2657,7 +2657,7 @@ BOOL GetConfigFromRegistry() Vallen=4; RegQueryValueEx(hKey,"LogLifetime",0, - (ULONG *)&Type,(UCHAR *)&LogAge,(ULONG *)&Vallen); + (ULONG *)&Type,(UCHAR *)&BBSLogAge,(ULONG *)&Vallen); Vallen=4; retCode += RegQueryValueEx(hKey,"BidLifetime",0, diff --git a/Bpq32.c b/Bpq32.c index e88e26a..388f89a 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1304,6 +1304,10 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Add validation of INP3 RTT messages and various INP3 fixes (12) // Change NetromX connect syntax to Service@Node to fix passing commands to local applications (12) // Add config file option to enable writing monitor data to a file at startup (13) +// Add option to use V2.0 on a route (14) +// Don't reset NS on RR R(F) following I(P) just on RR poll following timeout. Can get problems with delayed RR R(F) (reverted) (14) +// Ignore packets that would cause an FRMR and respond to FRMR with DM (14) +// Add option to send periodic INP3 RIF refresh (15) diff --git a/Cmd.c b/Cmd.c index cf3000a..738b8ad 100644 --- a/Cmd.c +++ b/Cmd.c @@ -71,6 +71,7 @@ int CompareAlias(const void *a, const void *b); int CompareRoutes(const void * a, const void * b); void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer); VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest, BOOL Spy, int Service); +VOID sendAlltoOneNeigbour(struct ROUTE * Route); extern VOID KISSTX(struct KISSINFO * KISS, PMESSAGE Buffer); @@ -84,6 +85,7 @@ UCHAR SAVEDAPPLFLAGS = 0; UCHAR ALIASINVOKED = 0; extern int MONTOFILEFLAG; +extern int RIFInterval; VOID * CMDPTR = 0; @@ -357,6 +359,36 @@ VOID POLLNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struc SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); } + +VOID SENDRIF(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD) +{ + struct ROUTE * Route; + int Portnum = atoi(CmdTail); + unsigned char axCall[7]; + + char * Call = strlop(CmdTail, ' '); + + if (Call && Portnum) + { + ConvToAX25(Call, axCall); + + if (FindNeighbour(axCall, Portnum, &Route)) + { + sendAlltoOneNeigbour(Route); + + strcpy(Bufferptr, OKMSG); + Bufferptr += (int)strlen(OKMSG); + + SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); + return; + } + } + + Bufferptr = Cmdprintf(Session, Bufferptr, "Route not found\r"); + SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); + return; +} + VOID SENDNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD) { int Portnum = atoi(CmdTail); @@ -1910,9 +1942,13 @@ char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE * double srtt = Routes->SRTT/100.0; double nsrtt = Routes->NeighbourSRTT/100.0; - Bufferptr = Cmdprintf(Session, Bufferptr, " %4.2fs %4.2fs", srtt, nsrtt); + Bufferptr = Cmdprintf(Session, Bufferptr, " %4.2fs %4.2fs %X", srtt, nsrtt, Routes->Status); } + if (Routes->TCPPort) + Bufferptr = Cmdprintf(Session, Bufferptr, " %d", Routes->localport); + + Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); } else @@ -4629,6 +4665,7 @@ struct CMDX COMMANDS[] = "RESTARTTNC ",10,&RESTARTTNC,0, "POLLNODES ",8, &POLLNODES,0, "SENDNODES ",8, &SENDNODES,0, + "SENDRIF ",7, &SENDRIF,0, "EXTRESTART ",10, EXTPORTVAL, offsetof(EXTPORTDATA, EXTRESTART), "TXDELAY ",3, PORTVAL, offsetof(PORTCONTROLX, PORTTXDELAY), "MAXFRAME ",3, PORTVAL, offsetof(PORTCONTROLX, PORTWINDOW), @@ -4686,6 +4723,7 @@ struct CMDX COMMANDS[] = "L4WINDOW ",6,SWITCHVAL,(size_t)&L4DEFAULTWINDOW, "BTINTERVAL ",5,SWITCHVAL,(size_t)&BTINTERVAL, "DEBUGINP3 ",8,SWITCHVAL,(size_t)&DEBUGINP3, + "RIFINTERVAL ",11,SWITCHVALW,(size_t)&RIFInterval, "MAXHOPS ",7,SWITCHVAL,(size_t)&MaxHops, "PREFERINP3 ",10,SWITCHVAL,(size_t)&PREFERINP3ROUTES, "MAXRTT ",6,SWITCHVALW,(size_t)&MAXRTT, diff --git a/FreeDATA.c b/FreeDATA.c index 75951ee..846de0f 100644 --- a/FreeDATA.c +++ b/FreeDATA.c @@ -4187,7 +4187,7 @@ static BOOL RestartTNC(struct TNCINFO * TNC) SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); struct sockaddr_in destaddr; - Debugprintf("trying to restart TNC %s", TNC->ProgramPath); + // Debugprintf("trying to restart TNC %s", TNC->ProgramPath); if (sock == INVALID_SOCKET) return 0; @@ -4210,7 +4210,7 @@ static BOOL RestartTNC(struct TNCINFO * TNC) n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr)); - Debugprintf("Restart TNC - sendto returned %d", n); +// Debugprintf("Restart TNC - sendto returned %d", n); Sleep(100); closesocket(sock); diff --git a/HTTPcode.c b/HTTPcode.c index 8d32c88..b120822 100644 --- a/HTTPcode.c +++ b/HTTPcode.c @@ -1396,23 +1396,23 @@ int SetupNodeMenu(char * Buff, int LOCAL) char SigninBit[] = "SYSOP Signin"; char NodeTail[] = - "Edit Config" - "" - ""; + "Edit Config\ + \ + "; Len = sprintf(Buff, NodeMenuHeader, Mycall); @@ -1566,10 +1566,9 @@ VOID SaveConfigFile(SOCKET sock , char * MsgPtr, char * Rest, int LOCAL) } ReplyLen = sprintf(Reply, "", Mess); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); + HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen); send(sock, Header, HeaderLen, 0); send(sock, Reply, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); } return; } diff --git a/Housekeeping.c b/Housekeeping.c index bf2c49f..319126f 100644 --- a/Housekeeping.c +++ b/Housekeeping.c @@ -30,7 +30,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses char * APIENTRY GetBPQDirectory(); -int LogAge = 7; +int BBSLogAge = 7; BOOL DeletetoRecycleBin = FALSE; BOOL SuppressMaintEmail = FALSE; @@ -61,7 +61,7 @@ struct Override ** LTFROM; struct Override ** LTTO; struct Override ** LTAT; -int DeleteLogFiles(); +int DeleteBBSLogFiles(); VOID SendNonDeliveryMessage(struct MsgInfo * OldMsg, BOOL Forwarded, int Age); int CreateWPMessage(); @@ -281,7 +281,7 @@ VOID DoHouseKeeping(BOOL Manual) UpdateWP(); - DeleteLogFiles(); + DeleteBBSLogFiles(); RemoveKilledMessages(); ExpireMessages(); @@ -799,7 +799,7 @@ VOID MailHousekeepingResults() extern UCHAR LogDirectory[260]; -int DeleteLogFiles() +int DeleteBBSLogFiles() { WIN32_FIND_DATA ffd; @@ -848,7 +848,7 @@ int DeleteLogFiles() Age = (int)((now - ft.LowPart) / 86400); - if (Age > LogAge) + if (Age > BBSLogAge) { sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0); if (DeletetoRecycleBin) @@ -875,7 +875,7 @@ int Filter(const struct dirent * dir) return memcmp(dir->d_name, "log", 3) == 0 && strstr(dir->d_name, ".txt"); } -int DeleteLogFiles() +int DeleteBBSLogFiles() { struct dirent **namelist; int n; @@ -897,7 +897,7 @@ int DeleteLogFiles() { Age = (now - STAT.st_mtime) / 86400; - if (Age > LogAge) + if (Age > BBSLogAge) { printf("Deleting %s\n", FN); unlink(FN); diff --git a/L2Code.c b/L2Code.c index 44015e1..fa8739f 100644 --- a/L2Code.c +++ b/L2Code.c @@ -20,6 +20,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // // C replacement for L2Code.asm // + +#define FRMRHACK + #define Kernel #define _CRT_SECURE_NO_DEPRECATE @@ -1215,7 +1218,18 @@ VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * LINK->L2STATE = 2; LINK->Ver2point2 = FALSE; LINK->L2TIMER = 1; // Use retry to send SABM - + LINK->L2RETRIES--; // Make sure at least one is sent + + // if an L3 link mark neighbour as not V2.2 + + if (LINK->LINKTYPE == 3) + { + struct ROUTE * ROUTE = LINK->NEIGHBOUR; // TO NEIGHBOUR + + if (ROUTE) + ROUTE->noV2point2 = 1; + } + ReleaseBuffer(Buffer); return; } @@ -1901,7 +1915,7 @@ BOOL InternalL2SETUPCROSSLINK(PROUTE ROUTE, int Retries) else LINK->LINKWINDOW = PORT->PORTWINDOW; - if (SUPPORT2point2) + if (SUPPORT2point2 && (ROUTE->noV2point2 == 0)) LINK->L2STATE = 1; // Send XID else LINK->L2STATE = 2; @@ -2156,7 +2170,27 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B // FRAME REJECT RECEIVED - LOG IT AND RESET LINK - RESET2(LINK); +//#ifdef FRMRHACK + + // Treat as DM and break link + + Debugprintf("BPQ32 FRMR received, disconnecting link"); + + InformPartner(LINK, LINKLOST); // SEND DISC TO OTHER END + L2SENDCOMMAND(LINK, DM); + + CLEAROUTLINK(LINK); + + if (PORT->TNC && PORT->TNC->Hardware == H_KISSHF) + DetachKISSHF(PORT); + + PORT->L2FRMRRX++; + + return; + +//#endif + +/* RESET2(LINK); LINK->L2STATE = 2; // INITIALISING LINK->L2ACKREQ = 0; // DONT SEND ANYTHING ELSE @@ -2166,7 +2200,7 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B L2SENDCOMMAND(LINK, SABM | PFBIT); return; - +*/ default: // ANY OTHER - IGNORE @@ -3829,6 +3863,13 @@ VOID SENDFRMR(struct _LINKTABLE * LINK) MESSAGE * Buffer; UCHAR * ptr; +#ifdef FRMRHACK // Ignore any frames with invalid n(r). If spurious error retry should fix it. If not link will retry out and reset + + if (LINK->SDREJF & SDNRER) + return; + +#endif + Buffer = SETUPL2MESSAGE(LINK, FRMR); if (Buffer == NULL) diff --git a/MHSave.txt b/MHSave.txt new file mode 100644 index 0000000..e69de29 diff --git a/Moncode.c b/Moncode.c index 20482ec..6cbf95a 100644 --- a/Moncode.c +++ b/Moncode.c @@ -1020,8 +1020,7 @@ void WritePacketLogThread(void * param) int MsgLen; MESSAGE * MSG; MESSAGE * Q; - char buffer[512]; - + char buffer[2048]; while(1) { @@ -1075,6 +1074,8 @@ void WritePacketLogThread(void * param) MsgLen = IntDecodeFrame(MSG, buffer, MSG->Timestamp, 0xffffffffffffffff, FALSE, FALSE); IntSetTraceOptionsEx(MMASK, SaveMTX, SaveMCOM, SaveMUI); + buffer[MsgLen++] = 0x0a; // Add lf + fwrite(buffer , 1, MsgLen, Handle); GetSemaphore(&Semaphore, 101); diff --git a/NETROMTCP.c b/NETROMTCP.c index 69a91c0..acc890c 100644 --- a/NETROMTCP.c +++ b/NETROMTCP.c @@ -60,6 +60,7 @@ VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG); int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS); VOID L3LINKCLOSED(struct _LINKTABLE * LINK, int Reason); void NetromTCPTrace(struct _MESSAGE * Message, char * Dirn); +void NETROMCloseTCP(struct ROUTE * Route); extern SOCKET NodeAPISocket; @@ -98,11 +99,11 @@ struct ConnectionInfo * AllocateNRTCPRec() Info = NRTCPInfo[i] = (struct NRTCPSTRUCT *)zalloc(sizeof(struct NRTCPSTRUCT)); Info->sockptr = (struct ConnectionInfo *)zalloc(sizeof(struct ConnectionInfo)); Info->LINK = (struct _LINKTABLE *)zalloc(sizeof(struct _LINKTABLE)); - Info->sockptr->Number = i; } else Info = NRTCPInfo[i]; + Info->sockptr->Number = i; sockptr = Info->sockptr; if (sockptr->SocketActive == FALSE) @@ -110,7 +111,7 @@ struct ConnectionInfo * AllocateNRTCPRec() sockptr->SocketActive = TRUE; sockptr->ConnectTime = sockptr->LastSendTime = time(NULL); -// Debugprintf("NRTCP Allocated %d", i); + Debugprintf("NRTCP Allocated %d", i); return sockptr; } } @@ -124,6 +125,7 @@ void checkNRTCPSockets(int portNo) SOCKET maxsock; int retval; int i; + time_t Now = time(NULL); struct timeval timeout; fd_set readfd, writefd, exceptfd; @@ -149,9 +151,23 @@ void checkNRTCPSockets(int portNo) if (sockptr->SocketActive == 0) continue; + if (sockptr->Connected && (Now - sockptr->LastReceiveTime) > 600) + { + struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number]; + + if (Info) + Debugprintf("NETROMTCP link to %s idle for too long, closing", Info->Call); + else + Debugprintf("NETROMTCP link idle for too long, closing"); + + NETROMConnectionLost(sockptr); + continue; + } + + if (sockptr->Connecting) { - // look for complete or failed + // look for complete or failed FD_SET(sockptr->socket, &writefd); FD_SET(sockptr->socket, &exceptfd); @@ -217,38 +233,26 @@ int NETROMOpenConnection(struct ROUTE * Route) farCall[ConvFromAX25(Route->NEIGHBOUR_CALL, farCall)] = 0; -// Debugprintf("Opening NRTCP Connection to %s", farCall); - if (Route->TCPSession) - { - // SESSION ALREADY EXISTS + sockptr = AllocateNRTCPRec(); - sockptr = Route->TCPSession->sockptr; - - if (sockptr->Connected || sockptr->Connecting) - return TRUE; + if (sockptr == NULL) + return 0; - // previous connect failed - } - else - { - sockptr = AllocateNRTCPRec(); + Debugprintf("Opening NRTCP Connection to %s index %d", farCall, sockptr->Number); - if (sockptr == NULL) - return 0; + Info = Route->TCPSession = NRTCPInfo[sockptr->Number]; + memcpy(Info->Call, farCall, 10); + Route->NEIGHBOUR_LINK = Info->LINK; - Info = Route->TCPSession = NRTCPInfo[sockptr->Number]; - memcpy(Info->Call, farCall, 10); - Route->NEIGHBOUR_LINK = Info->LINK; + Info->Route = Route; + Info->LINK->NEIGHBOUR = Route; + Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); + memcpy(Route->NEIGHBOUR_LINK->LINKCALL, Route->NEIGHBOUR_CALL, 7); - Info->Route = Route; - Info->LINK->NEIGHBOUR = Route; - Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); - memcpy(Route->NEIGHBOUR_LINK->LINKCALL, Route->NEIGHBOUR_CALL, 7); - } + Route->NEIGHBOUR_LINK = Route->TCPSession->LINK; // Just in case! return NETROMTCPConnect(Route, sockptr); - } void NETROMTCPResolve() @@ -301,6 +305,14 @@ int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) char PortString[20]; struct addrinfo * res = Route->TCPAddress; int Port = Route->TCPPort; + struct sockaddr_in my_addr; + socklen_t len = sizeof(my_addr); + struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number]; + + // Get my ip address and port + + memset(&my_addr, 0, sizeof(my_addr)); + getsockname(sockptr->socket, (struct sockaddr *) &my_addr, &len); sprintf(PortString, "%d", Port); @@ -333,6 +345,7 @@ int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) // sockptr->Connected = TRUE; + sockptr->LastReceiveTime = time(NULL); return TRUE; } else @@ -342,8 +355,15 @@ int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK { // Connect in Progress - + sockptr->Connecting = TRUE; + + // Get my ip address and port + memset(&my_addr, 0, sizeof(my_addr)); + getsockname(sockptr->socket, (struct sockaddr *) &my_addr, &len); + Route->localport = htons(my_addr.sin_port); + + Debugprintf("NRTCP Connection in progress %s local port %d", Info->Call, Route->localport); return TRUE; } else @@ -366,7 +386,18 @@ void NETROMConnectionAccepted(struct ConnectionInfo * sockptr) { // Not sure we can do much here until first message arrives with callsign + struct sockaddr_in my_addr; + socklen_t len = sizeof(my_addr); + + // Get my ip address and port + + memset(&my_addr, 0, sizeof(my_addr)); +// getsockname(sockptr->socket, (struct sockaddr *) &my_addr, &len); + + Debugprintf("INP3 Accept() Local port %d", htons(sockptr->sin.sin_port)); + sockptr->Connected = TRUE; + sockptr->LastReceiveTime = time(NULL); // Debugprintf("NRTCP Connection Accepted"); } @@ -376,8 +407,11 @@ void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPS // Debugprintf("NRTCP Connected"); + Debugprintf("NRTCP Connection Complete %s Local port %d", Info->Call, Info->Route->localport); + sockptr->Connecting = FALSE; sockptr->Connected = TRUE; + sockptr->LastReceiveTime = time(NULL); Info->LINK->L2STATE = 5; @@ -410,6 +444,8 @@ int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct N return 0; } + sockptr->LastReceiveTime = time(NULL); + sockptr->InputLen += len; // Process data @@ -429,8 +465,6 @@ checkLen: // This must be an incoming connection as Call is set before calling so need to find route record and set things up. -// Debugprintf("New NRTCP Connection from %s", Msg->Call); - memcpy(Info->Call, Msg->Call, 10); ConvToAX25(Msg->Call, axCall); @@ -445,6 +479,10 @@ checkLen: Route->TCPSession = Info; Info->LINK->L2STATE = 5; memcpy(Route->NEIGHBOUR_LINK->LINKCALL, axCall, 7); + Route->localport = htons(sockptr->sin.sin_port); + + Debugprintf("New NRTCP Connection from %s port %d", Msg->Call, Route->localport); + if (Info->Route->INP3Node) SendRTTMsg(Info->Route); @@ -460,7 +498,6 @@ checkLen: } } - if (memcmp(Info->Call, Msg->Call, 10) != 0) { Debugprintf("NRTCP Mismatch - closing connection"); @@ -512,6 +549,8 @@ checkLen: ReleaseBuffer(Buffer); } + Info->Route->NEIGHBOUR_LINK = Info->LINK; // Just in case! + NETROMMSG(Info->LINK, L3Msg); seeifMore: @@ -534,6 +573,9 @@ VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) int DataLen = Frame->LENGTH - (MSGHDDRLEN + 1); // Not including PID int Ret; PMESSAGE Buffer; + struct sockaddr_in my_addr; + socklen_t len = sizeof(my_addr); + struct ConnectionInfo * sockptr; Msg.Length = DataLen + 13; // include PID memcpy(Msg.Call, MYNETROMCALL, 10); @@ -543,6 +585,47 @@ VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) if (Route->TCPSession == 0) return; + sockptr = Route->TCPSession->sockptr; + + // Get other port + + if (strcmp(Route->TCPHost, "0.0.0.0") == 0) + { + // incoming + +// Debugprintf("INP3 Remote port %d", htons(sockptr->sin.sin_port)); + + if (Route->localport != htons(sockptr->sin.sin_port)) + { + // Route is linked to wrong session. Close it + + // Route->TCPSession = 0; + // Route->NEIGHBOUR_LINK = 0; + return; + } + } + else + { + // outgoing + + memset(&my_addr, 0, sizeof(my_addr)); + + getsockname(sockptr->socket, (struct sockaddr *) &my_addr, &len); +// Debugprintf("INP3 Local port %d", htons(my_addr.sin_port)); + + if (Route->localport != htons(my_addr.sin_port)) + { + // Route is linked to wrong session. Close it + + // if (sockptr->Connecting == 0) + // { + // Route->TCPSession = 0; + // Route->NEIGHBOUR_LINK = 0; + // } + return; + } + } + Ret = send(Route->TCPSession->sockptr->socket, (char *)&Msg, DataLen + 13, 0); // Create a dummy L2 message so we can trace it @@ -555,7 +638,7 @@ VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) Buffer->CTL = 0; Buffer->PORT = Route->NEIGHBOUR_PORT; - ConvToAX25(Route->TCPSession->Call, Buffer->DEST); + memcpy(Buffer->DEST, Route->NEIGHBOUR_CALL, 7); ConvToAX25(MYNETROMCALL, Buffer->ORIGIN); memcpy(Buffer->L2DATA, &Frame->L3SRCE[0], DataLen); @@ -590,14 +673,12 @@ void NETROMConnectionLost(struct ConnectionInfo * sockptr) { Route = Info->Route; - if (sockptr->Connected) - L3LINKCLOSED(Info->LINK, LINKLOST); - - if (sockptr->Connecting) - L3LINKCLOSED(Info->LINK, SETUPFAILED); - if (Route) + { + Route->NEIGHBOUR_LINK = 0; Route->TCPSession = 0; + Route->localport = 0; + } Info->Call[0] = 0; Info->LINK->L2STATE = 0; @@ -608,3 +689,18 @@ void NETROMConnectionLost(struct ConnectionInfo * sockptr) memset(sockptr, 0, sizeof(struct ConnectionInfo)); } +void NETROMCloseTCP(struct ROUTE * Route) +{ + if (Route->TCPSession) + { + struct ConnectionInfo * sockptr = Route->TCPSession->sockptr; + NETROMConnectionLost(sockptr); + } + else + { + Route->NEIGHBOUR_LINK = 0; + } +} + + + diff --git a/RHP.c b/RHP.c index a82b091..8faacb6 100644 --- a/RHP.c +++ b/RHP.c @@ -387,6 +387,12 @@ int processRHCPOpen(struct ConnectionInfo * sockptr, SOCKET Socket, char * Msg, if (_stricmp(pfam, "ax25") != 0) return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0); + if (strlen(Local) > 10) + return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 6, \"errText\": \"%s\"}", ID, 0, ErrCodes[6]); + + if (strlen(Remote) > 10) + return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 7, \"errText\": \"%s\"}", ID, 0, ErrCodes[7]); + if (_stricmp(Mode, "stream") == 0) { { diff --git a/TelnetV6.c b/TelnetV6.c index 332e843..e2915db 100644 --- a/TelnetV6.c +++ b/TelnetV6.c @@ -178,17 +178,16 @@ void NETROMConnectionLost(struct ConnectionInfo * sockptr); void NETROMConnectionAccepted(struct ConnectionInfo * sockptr); struct ConnectionInfo * AllocateNRTCPRec(); -static int LogAge = 10; - int DeleteLogFile(char * Log, int KeepDays); -void DeleteTelnetLogFiles() +void DeleteLogFiles(int Age) { - DeleteLogFile("Telnet", 14); - DeleteLogFile("CMSAccess_", 14); - DeleteLogFile("ConnectLog_",14); - DeleteLogFile("APRS_", 14); - DeleteLogFile("PacketLog_",MONTOFILEFLAG); + DeleteLogFile("Telnet", Age); + DeleteLogFile("CMSAccess_", Age); + DeleteLogFile("ConnectLog_",Age); + DeleteLogFile("APRS_", Age); + if (MONTOFILEFLAG) + DeleteLogFile("PacketLog_", MONTOFILEFLAG); } #ifdef WIN32 @@ -235,11 +234,11 @@ int DeleteLogFile(char * Log, int KeepDays) Age = (int)((now - ft.LowPart) / 86400); if (Age > KeepDays) - { - sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0); - Debugprintf("Deleting %s", File); - DeleteFile(File); - } + { + sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0); + Debugprintf("Deleting %s", File); + DeleteFile(File); + } } } while (FindNextFile(hFind, &ffd) != 0); @@ -1445,8 +1444,6 @@ void * TelnetExtInit(EXTPORTDATA * PortEntry) } */ - DeleteTelnetLogFiles(LogAge); - initUTF8(); sprintf(msg,"Telnet Server "); diff --git a/Versions.h b/Versions.h index a6c8834..b7e091d 100644 --- a/Versions.h +++ b/Versions.h @@ -10,15 +10,15 @@ #endif -#define KVers 6,0,25,13 -#define KVerstring "6.0.25.13\0" +#define KVers 6,0,25,15 +#define KVerstring "6.0.25.15\0" #ifdef CKernel #define Vers KVers #define Verstring KVerstring -#define Datestring "October 2025" +#define Datestring "December 2025" #define VerComments "G8BPQ Packet Switch (C Version)" KVerstring #define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0" #define VerDesc "BPQ32 Switch\0" diff --git a/WINMOR.c b/WINMOR.c index 94630b3..ac47068 100644 --- a/WINMOR.c +++ b/WINMOR.c @@ -2929,7 +2929,7 @@ BOOL RestartTNC(struct TNCINFO * TNC) SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); struct sockaddr_in destaddr; - Debugprintf("trying to restart TNC %s", TNC->ProgramPath); +// Debugprintf("trying to restart TNC %s", TNC->ProgramPath); if (sock == INVALID_SOCKET) return 0; @@ -2952,7 +2952,7 @@ BOOL RestartTNC(struct TNCINFO * TNC) n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr)); - Debugprintf("Restart TNC - sendto returned %d", n); +// Debugprintf("Restart TNC - sendto returned %d", n); Sleep(100); closesocket(sock); diff --git a/WinRPR.c b/WinRPR.c index f2d8791..531f41e 100644 --- a/WinRPR.c +++ b/WinRPR.c @@ -120,7 +120,7 @@ static BOOL RestartTNC(struct TNCINFO * TNC) SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); struct sockaddr_in destaddr; - Debugprintf("trying to restart TNC %s", TNC->ProgramPath); +// Debugprintf("trying to restart TNC %s", TNC->ProgramPath); if (sock == INVALID_SOCKET) return 0; @@ -143,7 +143,7 @@ static BOOL RestartTNC(struct TNCINFO * TNC) n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr)); - Debugprintf("Restart TNC - sendto returned %d", n); +// Debugprintf("Restart TNC - sendto returned %d", n); Sleep(100); closesocket(sock); diff --git a/asmstrucs.h b/asmstrucs.h index 97e4a4d..7dca751 100644 --- a/asmstrucs.h +++ b/asmstrucs.h @@ -258,6 +258,9 @@ typedef struct ROUTE int TCPPort; struct NRTCPSTRUCT * TCPSession; struct addrinfo * TCPAddress; // Resolved Address + int localport; // for consistancy check + int recNum; // This entry's index it Routes table + int noV2point2; // Set to force V2.0 connect. Can be set in config or dynamically learned } *PROUTE; @@ -265,10 +268,8 @@ typedef struct ROUTE #define GotRTTRequest 1 // Other end has sent us a RTT Packet #define GotRTTResponse 2 // Other end has sent us a RTT Response -#define GotRIF 4 // Other end has sent RIF, so is probably an INP3 Node - // (could just be monitoring RTT for some reason -#define SentRTTRequest 8 -#define SentOurRIF 16 // Set when we have sent a rif for our Call and any ApplCalls +#define SentRTTRequest 4 +#define SentOurRIF 8 // Set when we have sent a rif for our Call and any ApplCalls // (only sent when we have seen both a request and response) #pragma pack(1) @@ -480,20 +481,18 @@ typedef struct _APPLCALLS typedef struct NR_DEST_ROUTE_ENTRY { struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH - UCHAR ROUT_QUALITY; // QUALITY + uint16_t * Dummy; // Padding so records are same length + UCHAR ROUT_QUALITY; // QUALITY UCHAR ROUT_OBSCOUNT; UCHAR ROUT_LOCKED; - UCHAR Padding[4]; // So Entries are the same length } *PNR_DEST_ROUTE_ENTRY; typedef struct INP3_DEST_ROUTE_ENTRY { struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH - USHORT LastTT; // Last Value Reported. This is our value, not the one actually sent (which includes Neighbour TT) - USHORT LastNeighbourTT; // Saved from last report so we can calulate what we actually sent - + uint16_t * RouteLastTT; // Last time sent should be saved for each neighbour. Area is mallod'ed as needed USHORT STT; // Current time to dest from here (was called RTT but is one way not round trip. - // Is actually a smoothed value as is calculated from smoother link times) + // Is actually a smoothed value as is calculated from smoothed link times) UCHAR Hops; } *PDEST_ROUTE_ENTRY; @@ -746,6 +745,8 @@ typedef struct PORTCONTROL int Hardware; // TNC H_TYPE. Copied here for access from application context int isRF; // For API reporting. -1 is unspecified + int SENDRIFTIMER; + time_t LastRIFTime; } PORTCONTROLX, *PPORTCONTROL; diff --git a/bpqmail.h b/bpqmail.h index a2d85b3..941d24a 100644 --- a/bpqmail.h +++ b/bpqmail.h @@ -1591,7 +1591,7 @@ extern RECT DebugRect; extern HWND hMonitor; //extern HWND hConsole; //extern RECT ConsoleRect; -extern int LogAge; +extern int BBSLogAge; extern BOOL DeletetoRecycleBin; extern BOOL SuppressMaintEmail; extern BOOL SaveRegDuringMaint; diff --git a/cMain.c b/cMain.c index 2773a95..c551265 100644 --- a/cMain.c +++ b/cMain.c @@ -58,6 +58,7 @@ VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD); void WritePacketLogThread(void * param); void hookNodeStarted(); void hookNodeRunning(); +void DeleteLogFiles(int Age); void APIL2Trace(struct _MESSAGE * Message, char * Dirn); #include "configstructs.h" @@ -71,11 +72,15 @@ extern int nodeStartedSent; extern SOCKADDR_IN UDPreportdest; extern char NodeAPIServer[80]; extern int NodeAPIPort; +extern int RIFInterval; time_t LastNodeStatus = 0; int nodeStatusTimer = 20 * 60; // 20 mins + +int LogAge = 10; + struct PORTCONFIG * PortRec; #define RNRSET 0x2 // RNR RECEIVED FROM OTHER END @@ -675,6 +680,7 @@ BOOL Start() struct CMDX * CMD; int PortSlot = 1; uintptr_t int3; + int index = 0; // Entry No. in ROUTES unsigned char * ptr2 = 0, * ptr3, * ptr4; USHORT * CWPTR; @@ -844,6 +850,10 @@ BOOL Start() MAXLINKS = cfg->C_MAXLINKS; MAXDESTS = cfg->C_MAXDESTS; MAXNEIGHBOURS = cfg->C_MAXNEIGHBOURS; + + if (MAXNEIGHBOURS == 0) + MAXNEIGHBOURS = 1; + MAXCIRCUITS = cfg->C_MAXCIRCUITS; HIDENODES = cfg->C_HIDENODES; @@ -888,6 +898,8 @@ BOOL Start() MONTOFILEFLAG = cfg->C_MONTOFILE; + RIFInterval = cfg->C_RIFInterval; + if (cfg->C_OnlyVer2point0) SUPPORT2point2 = 0; @@ -1362,6 +1374,7 @@ BOOL Start() char * VIA; char axcall[8]; + ConvToAX25(Rcfg->call, ROUTE->NEIGHBOUR_CALL); // if VIA convert digis @@ -1406,6 +1419,9 @@ BOOL Start() ROUTE->NoKeepAlive = 0; // Cant have INP3 and NOKEEPALIVES } + if (Rcfg->noV2point2) + ROUTE->noV2point2 = 1; + ROUTE->NBOUR_MAXFRAME = Rcfg->pwind & 0x3f; FRACK = Rcfg->pfrack; @@ -1423,6 +1439,8 @@ BOOL Start() ROUTE->TCPAddress = (struct addrinfo *)zalloc(sizeof(struct addrinfo)); ROUTE->TCPAddress->ai_addr = (struct sockaddr *) zalloc(sizeof(struct sockaddr)); } + + ROUTE->recNum = index++; Rcfg++; ROUTE++; @@ -1583,6 +1601,11 @@ BOOL Start() if (AUTOSAVEMH) ReadMH(); // Only if AutoSave configured + // Tidy Log Files + + DeleteLogFiles(LogAge); + + // set up stream number in BPQHOSTVECTOR for (i = 0; i < 64; i++) @@ -1657,14 +1680,19 @@ BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE) { struct ROUTE * ROUTE = NEIGHBOURS; struct ROUTE * FIRSTSPARE = NULL; - int n = MAXNEIGHBOURS; char Normcall[10]; + int n; - while (n--) + for (n = 0; n < MAXNEIGHBOURS; n++) { if (ROUTE->NEIGHBOUR_CALL[0] == 0) // Spare + { if (FIRSTSPARE == NULL) + { FIRSTSPARE = ROUTE; + ROUTE->recNum = n; + } + } if (ROUTE->NEIGHBOUR_PORT != Port) { @@ -1672,7 +1700,6 @@ BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE) continue; } - Normcall[ConvFromAX25(ROUTE->NEIGHBOUR_CALL, Normcall)] = 0; if (CompareCalls(ROUTE->NEIGHBOUR_CALL, Call)) @@ -1686,6 +1713,7 @@ BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE) // ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL *REQROUTE = FIRSTSPARE; + return FALSE; } diff --git a/config.c b/config.c index b883ad5..16dd091 100644 --- a/config.c +++ b/config.c @@ -310,7 +310,9 @@ static char *keywords[] = "LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS", "EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS", "L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe", -"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0", "DEBUGINP3", "ENABLEOARCAPI", "MONTOFILE" +"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0", "DEBUGINP3", "ENABLEOARCAPI", "MONTOFILE", +"RIFInterval" + }; /* parameter keywords */ static void * offset[] = @@ -334,7 +336,8 @@ static void * offset[] = &xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs, &xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS, &xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen, &xxcfg.C_L2Compress, &xxcfg.C_L2CompMaxframe, -&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0, &xxcfg.C_DEBUGINP3, &xxcfg.C_OARCAPI, &xxcfg.C_MONTOFILE}; /* offset for corresponding data in config file */ +&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0, &xxcfg.C_DEBUGINP3, &xxcfg.C_OARCAPI, &xxcfg.C_MONTOFILE, +&xxcfg.C_RIFInterval}; /* offset for corresponding data in config file */ static int routine[] = { @@ -357,7 +360,8 @@ static int routine[] = 2, 2, 1, 2, 2, 2, 2, 2, 0, 1, 20, 20, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1}; // Routine to process param +1, 1, 1, 1, 1, 1, +1}; // Routine to process param int PARAMLIM = sizeof(routine)/sizeof(int); //int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int); @@ -620,8 +624,7 @@ BOOL ProcessConfig() paramok[78]=1; // ENABLEADIFLOG optional paramok[79]=1; // EnableEvents optional paramok[80]=1; // SaveAPRSMsgs optional - paramok[79]=1; // SaveAPRSMsgs optional - paramok[80]=1; // EnableM0LTEMap optional + paramok[81]=1; // EnableM0LTEMap optional paramok[82]=1; // MQTT Params paramok[83]=1; // MQTT Params paramok[84]=1; // MQTT Params @@ -638,6 +641,7 @@ BOOL ProcessConfig() paramok[95]=1; // DEBUGINP3 paramok[96]=1; // EnableOARCAPI paramok[97]=1; // MONTOFILE + paramok[98]=1; // RIFInterval for (i=0; i < PARAMLIM; i++) @@ -1679,7 +1683,15 @@ int routes(int i) char * val = strtok_s(NULL, " ,=", &context); if (val) - Route->farQual = atoi(val); + Route->nokeepalives = atoi(val); + } + + else if (strcmp(ptr, "NOV2.2") == 0) + { + char * val = strtok_s(NULL, " ,=", &context); + + if (val) + Route->noV2point2 = atoi(val); } diff --git a/configstructs.h b/configstructs.h index 89ffb60..de974ff 100644 --- a/configstructs.h +++ b/configstructs.h @@ -97,6 +97,7 @@ struct ROUTECONFIG int farQual; int inp3; int nokeepalives; + int noV2point2; char * tcphost; int tcpport; }; @@ -188,6 +189,8 @@ struct CONFIGTABLE int C_DEBUGINP3; int C_OARCAPI; int C_MONTOFILE; + int C_RIFInterval; + //#define ApplOffset 80000 // Applications offset in config buffer diff --git a/datadefs.c b/datadefs.c index 5cb3711..e688283 100644 --- a/datadefs.c +++ b/datadefs.c @@ -39,7 +39,7 @@ int DEBUGINP3 = 0; int EnableOARCAPI = 0; -int RTTInterval = 30; // 5 Minutes +int RTTInterval = 30; // 10 second increments - 5 Minutes BOOL IPRequired = FALSE; BOOL PMRequired = FALSE; diff --git a/telnetserver.h b/telnetserver.h index 0bb4986..63dcef3 100644 --- a/telnetserver.h +++ b/telnetserver.h @@ -66,6 +66,7 @@ struct ConnectionInfo char Signon[100]; // User/Pass/Appl for Outgoing Connects BOOL Keepalive; // For HOST (esp CCC) Keepalives time_t LastSendTime; + time_t LastReceiveTime; BOOL NoCallsign; // Don't Send Callsign to host if no Signon UCHAR * ResendBuffer; // Used if send() returns EWOULDBLOCK int ResendLen; // Len to resend