From d7b0d25ddb64850a2943f33d2450557629605bc9 Mon Sep 17 00:00:00 2001 From: Dave Hibberd Date: Sun, 23 Nov 2025 11:51:15 +0000 Subject: [PATCH 1/2] 6.0.25.12 hacky merge due t it not ffing. --- BPQINP3.c | 85 ++-- Bpq32.c | 9 +- Cmd.c | 187 +++++++-- Events.c | 4 +- L4Code.c | 31 +- LinBPQ.c | 8 +- NETROMTCP.c | 1044 ++++++++++++++++++++++++++++++++++++++++++++++++++ Versions.h | 8 + compatbits.c | 27 ++ compatbits.h | 3 +- 10 files changed, 1331 insertions(+), 75 deletions(-) diff --git a/BPQINP3.c b/BPQINP3.c index de4bf76..d87aa69 100644 --- a/BPQINP3.c +++ b/BPQINP3.c @@ -35,8 +35,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses #include //#include "vmm.h" -uint64_t INP3timeLoadedMS = 0; - extern int DEBUGINP3; VOID SendNegativeInfo(); @@ -64,11 +62,16 @@ static VOID SendNetFrame(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) typedef struct _RTTMSG { - UCHAR ID[7]; - UCHAR TXTIME[11]; - UCHAR SMOOTHEDRTT[11]; - UCHAR LASTRTT[11]; - UCHAR POINTER[11]; + UCHAR ID[6]; + UCHAR Space1; + UCHAR TXTIME[10]; + UCHAR Space2; + UCHAR SMOOTHEDRTT[10]; + UCHAR Space3; + UCHAR LASTRTT[10]; + UCHAR Space4; + UCHAR RTTID[10]; + UCHAR Space5; UCHAR ALIAS[7]; UCHAR VERSION[12]; UCHAR SWVERSION[9]; @@ -110,6 +113,8 @@ extern int RTTInterval; // 4 Minutes int RTTRetries = 2; int RTTTimeout = 6; // 1 Min (Horizon is 1 min) +uint32_t RTTID = 1; + VOID InitialiseRTT() { UCHAR temp[256] = ""; @@ -161,10 +166,11 @@ VOID DeleteINP3Routes(struct ROUTE * Route) Route->BCTimer = 0; Route->Status = 0; Route->Timeout = 0; + Route->NeighbourSRTT = 0; Dest--; - // Delete any Dest entries via this Route + // Delete any Dest entries via this Route for (i=0; i < MAXDESTS; i++) { @@ -340,8 +346,8 @@ VOID TellINP3LinkSetupFailed(struct ROUTE * Route) VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff) { - int RTT; - unsigned int OrigTime; + uint32_t RTT; + uint32_t OrigTime; char Normcall[10]; @@ -349,10 +355,10 @@ VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff) Route->Timeout = 0; // Got Response - sscanf(&Buff->L4DATA[6], "%d", &OrigTime); - RTT = (int)((GetTickCount() - INP3timeLoadedMS) / 10 - (OrigTime)); // We work internally in mS + sscanf(&Buff->L4DATA[6], "%u", &OrigTime); + RTT = GetTickCountINP3() - OrigTime; // We work internally in mS - if (RTT > 60000) + if (RTT > 60000 || RTT < 0) return; // Ignore if more than 60 secs (why ??) Route->RTT = RTT; @@ -890,8 +896,8 @@ VOID UpdateRoute(struct DEST_LIST * Dest, struct INP3_DEST_ROUTE_ENTRY * ROUTEPT VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len, int Port) { - int OtherRTT; - int Dummy; + uint32_t OtherRTT; + uint32_t Dummy; char * ptr; struct _RTTMSG * RTTMsg = (struct _RTTMSG *)&Buff->L4DATA[0]; char Normcall[10]; @@ -920,18 +926,28 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len return; // We don't want to use INP3 } - // Extract other end's SRTT + // Basic Validation - look for spaces in the right place - // Get SWVERSION to see if other end is old (Buggy) BPQ - - if (memcmp(RTTMsg->SWVERSION, "BPQ32001 ", 9) == 0) - Route->OldBPQ = 1; + if ((RTTMsg->Space1 | RTTMsg->Space2 | RTTMsg->Space3 | RTTMsg->Space4 | RTTMsg->Space5) != ' ') + { + Debugprintf("Corrupt INP3 RTT Message %s", &Buff->L4DATA[0]); + } else - Route->OldBPQ = 0; + { + // Extract other end's SRTT - sscanf(&Buff->L4DATA[6], "%d %d", &Dummy, &OtherRTT); + // Get SWVERSION to see if other end is old (Buggy) BPQ - Route->NeighbourSRTT = OtherRTT; + if (memcmp(RTTMsg->SWVERSION, "BPQ32001 ", 9) == 0) + Route->OldBPQ = 1; + else + Route->OldBPQ = 0; + + sscanf(&Buff->L4DATA[6], "%u %u", &Dummy, &OtherRTT); + + if (OtherRTT < 60000) // Don't save suspect values + Route->NeighbourSRTT = OtherRTT; + } // Look for $M and $H (MAXRTT MAXHOPS) @@ -945,6 +961,8 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len if (ptr) Route->RemoteMAXHOPS = atoi(ptr + 2); + + // Echo Back to sender SendNetFrame(Route, Buff); @@ -965,7 +983,8 @@ VOID SendRTTMsg(struct ROUTE * Route) char Stamp[50]; char Normcall[10]; unsigned char temp[256]; - uint64_t sendTime; + uint32_t sendTime; + int n; Normcall[ConvFromAX25(Route->NEIGHBOUR_CALL, Normcall)] = 0; @@ -985,14 +1004,21 @@ VOID SendRTTMsg(struct ROUTE * Route) Msg->L4TXNO = 0; Msg->L4FLAGS = L4INFO; - // The timestamp can possibly exceed 10 digits. INP3 only works on differece between send and received, so base can be reset safely. + // Windows GetTickCount wraps every 54 days or so. INP3 doesn't care, so long as the edge + // case where timer wraps between sending msg and getting response is ignored + // For platform independence use GetTickCountINP3() and map as appropriate - sendTime = ((uint64_t)GetTickCount() - INP3timeLoadedMS) / 10; // 10mS units + sendTime = GetTickCountINP3(); // 10mS units - if (sendTime > 9999999999) - sendTime = INP3timeLoadedMS = 0; + sprintf(Stamp, "%10u %10d %10d %10d ", sendTime, Route->SRTT, Route->RTT, RTTID++); - sprintf(Stamp, "%10llu %10d %10d %10d ", sendTime, Route->SRTT, Route->RTT, 0); + n = strlen(Stamp); + + if (n != 44) + { + Debugprintf("Trying to send corrupt RTT message %s", Stamp); + return; + } memcpy(RTTMsg.TXTIME, Stamp, 44); @@ -1209,6 +1235,7 @@ int SendRIPTimer() } L2SETUPCROSSLINKEX(Route, 2); // Only try SABM twice + Route->NeighbourSRTT = 0; // just in case! Route->LastConnectAttempt = REALTIMETICKS; diff --git a/Bpq32.c b/Bpq32.c index e49bd8b..23f53e9 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1300,6 +1300,12 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Fix FRMR caused by sending SREJ when no frames outstanding (8) // Fix some issues with NetromX connects and Route Selection when running INP3 and NODES routing (9) // Fix connecting to a netrom node with c p node command (10) +<<<<<<< Updated upstream +||||||| Stash base +======= +// 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) +>>>>>>> Stashed changes #define CKernel @@ -1540,7 +1546,6 @@ extern char ReportDest[7]; extern UCHAR ConfigDirectory[260]; -extern uint64_t INP3timeLoadedMS; VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Consoleprintf(const char * format, ...); @@ -2481,8 +2486,6 @@ FirstInit() EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses"); } - INP3timeLoadedMS = GetTickCount(); - srand(time(NULL)); INITIALISEPORTS(); diff --git a/Cmd.c b/Cmd.c index 42869d5..21ced5f 100644 --- a/Cmd.c +++ b/Cmd.c @@ -838,13 +838,14 @@ BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySess return FALSE; } -void ConnecttoService(TRANSPORTENTRY * Session, char * Bufferptr, int ServiceIndex, char * Node, int Stay) +void ConnecttoService(TRANSPORTENTRY * Session, char * Bufferptr, int Service, char * Node, int Stay) { struct DEST_LIST * Dest = DESTS; int n = MAXDESTS; int gotDest = 0; unsigned char axcall[7]; - int Service = -1; + char cmdName[80]; + int i; // Make Sure Node is Known @@ -889,9 +890,20 @@ void ConnecttoService(TRANSPORTENTRY * Session, char * Bufferptr, int ServiceInd Session->STAYFLAG = Stay; - Service = SERVICES[ServiceIndex].ServiceNo; + // Get command name if a named command - Bufferptr = Cmdprintf(Session, Bufferptr, "Connecting to Service %s on Node %s \r", SERVICES[ServiceIndex].ServiceName, Node); + sprintf(cmdName, "%d", Service); // default to number + + for (i = 0; i < NUMBEROFSSERVICES; i++) + { + if (SERVICES[i].ServiceNo == Service) + { + strcpy(cmdName, SERVICES[i].ServiceName); + break; + } + } + + Bufferptr = Cmdprintf(Session, Bufferptr, "Connecting to Service %s on Node %s \r", cmdName, Node); DoNetromConnect(Session, Bufferptr, Dest, 0, Service); @@ -930,7 +942,7 @@ int checkifService(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, s { if (strcmp(APPName, SERVICES[i].ServiceName) == 0) { - ConnecttoService(Session, Bufferptr, i, ptr, Stay); + ConnecttoService(Session, Bufferptr, SERVICES[i].ServiceNo, ptr, Stay); return 1; } } @@ -948,7 +960,6 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct char * ptr1, *ptr2; int n = 12; BOOL Stay = FALSE; - char * ptr, *Context; // Copy Appl and Null Terminate @@ -967,14 +978,17 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct return; } - ptr = strtok_s(CmdTail, " ", &Context); - // ptr is first param. Context is rest of string; + if (CmdTail[0] == 'S') + Stay = TRUE; + // could be Node for NETROMX connect or S flag + + // We now use service@node, so can't get here + +/* if (ptr) { - // could be Node for NETROMX connect or S flag - int i; if (strlen(ptr) > 1) @@ -983,6 +997,8 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct Session->STAYFLAG = Stay; // See if APPL is one of Paula's service + + for (i = 0; i < NUMBEROFSSERVICES; i++) { @@ -1003,7 +1019,7 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct else if (ptr[0] == 'S') Session->STAYFLAG = Stay; } - +*/ memcpy(Session->APPL, CMD->String, 12); // SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND @@ -2572,6 +2588,56 @@ VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C return; } + // See if NETROMX connect c service@node + + if (strchr(ptr, '@')) + { + // We now use service@node, unlike xr + + char * Context1; + + char * Cmd = strtok_s(ptr, "@", &Context1); + char * Node = strtok_s(NULL, " ", &Context1); + int i; + int Stay = 0; + + if (Context1 && Context1[0] == 'S') + Session->STAYFLAG = Stay; + + for (i = 0; i < NUMBEROFSSERVICES; i++) + { + if (strcmp(Cmd, SERVICES[i].ServiceName) == 0) + { + if (Node) + { + ConnecttoService(Session, Bufferptr, SERVICES[i].ServiceNo, Node, Stay); + return; + } + } + } + + // May be numeric service + + for (i = 0; i < strlen(Cmd); i++) + { + if (!isdigit(Cmd[i])) + break; + } + + if (i == strlen(Cmd)) + { + if (Node) + { + ConnecttoService(Session, Bufferptr, atoi(Cmd), Node, Stay); + return; + } + } + + Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid NetromX command\r"); + SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); + return; + } + Port = atoi(ptr); if (Port) @@ -2671,7 +2737,12 @@ NoPort: // SEE IF CALL TO ANY OF OUR HOST SESSIONS - UNLESS DIGIS SPECIFIED +<<<<<<< Updated upstream // if (axcalls[7] == 0 && axcalls[9]) +||||||| Stash base + if (axcalls[7] == 0 && axcalls[9] ) +======= +>>>>>>> Stashed changes if (axcalls[7] == 0) { // If this connect is as a result of a command alias, don't check appls or we will loop @@ -2723,6 +2794,7 @@ NoPort: } } +<<<<<<< Updated upstream // if no digis see if connect to known node. // But now could have a single numeric param as a service number (Paula's Netromx) @@ -2750,6 +2822,32 @@ NoPort: } if (axcalls[7] == 0 || haveService) +||||||| Stash base + // if no digis see if connect to known node. But now could have a single numeric param as a service number (Paula's Netromx) + // cmdCopy is command tail (after call) + + // Make sure field is numeric + + i = 0; + + while (cmdCopy[i] >= '0' && cmdCopy[i]<= '9') + i++; + + if (cmdCopy[i] != ' ') + goto Downlink; + else + { + if (i > 0) // Some digits + { + haveService = 1; + Service = atoi(cmdCopy); + } + } + + if (axcalls[7] == 0 || haveService) +======= + if (axcalls[7] == 0) +>>>>>>> Stashed changes { // SEE IF CALL TO ANOTHER NODE @@ -2792,9 +2890,6 @@ Downlink: // L2 NEEDS PORT NUMBER Bufferptr = Cmdprintf(Session, Bufferptr, "Downlink connect needs port number - C P CALLSIGN\r"); - - // Send Port List - SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); return; } @@ -5082,6 +5177,7 @@ VOID DoTheCommand(TRANSPORTENTRY * Session) int n; int i, Service = -1; char * Cmd, *Node, *Context; + int Stay = 0; ptr1 = &COMMANDBUFFER[0]; // @@ -5176,28 +5272,47 @@ VOID DoTheCommand(TRANSPORTENTRY * Session) // See if a NETROMX Service - Cmd = strtok_s(ptr1, " ", &Context); - Node = strtok_s(NULL, " ", &Context); - - for (i = 0; i < NUMBEROFSSERVICES; i++) + // We now use service@node, unlike xr + + if (strchr(ptr1, '@')) { - if (strcmp(Cmd, SERVICES[i].ServiceName) == 0) + Cmd = strtok_s(ptr1, "@", &Context); + Node = strtok_s(NULL, " ", &Context); + + if (Cmd && Node) { - int Stay = 0; - if (Context && Context[0] == 'S') Session->STAYFLAG = Stay; - if (Node) + for (i = 0; i < NUMBEROFSSERVICES; i++) { - ConnecttoService(Session, ReplyPointer, i, Node, Stay); + if (strcmp(Cmd, SERVICES[i].ServiceName) == 0) + { + ConnecttoService(Session, ReplyPointer, SERVICES[i].ServiceNo, Node, Stay); + return; + } + } + + // May be numeric service + + for (i = 0; i < strlen(Cmd); i++) + { + if (!isdigit(Cmd[i])) + break; + } + + if (i == strlen(Cmd)) + { + ConnecttoService(Session, ReplyPointer, atoi(Cmd), Node, Stay); return; } - - // Connecting to service on local node - msy be possible sometime } - } + ReplyPointer = Cmdprintf(Session, ReplyPointer, "Invalid NetromX command\r"); + SendCommandReply(Session, REPLYBUFFER, (int)(ReplyPointer - (char *)REPLYBUFFER)); + return; + + } Session->BADCOMMANDS++; if (Session->BADCOMMANDS > 6) // TOO MANY ERRORS @@ -5214,19 +5329,19 @@ VOID DoTheCommand(TRANSPORTENTRY * Session) ptr1 += CMDERRLEN; SendCommandReply(Session, Buffer, (int)(ptr1 - (char *)Buffer)); -} + } -VOID StatsTimer() -{ - struct PORTCONTROL * PORT = PORTTABLE; - uint64_t sum, sum2; - - // Interval is 60 secs - - while(PORT) + VOID StatsTimer() { - int index = PORT->StatsPointer++; + struct PORTCONTROL * PORT = PORTTABLE; + uint64_t sum, sum2; + + // Interval is 60 secs + + while(PORT) + { + int index = PORT->StatsPointer++; if (index == 1439) PORT->StatsPointer = 0; // Cyclic through 24 hours (1440 Mins) diff --git a/Events.c b/Events.c index bb2a8ef..8e63cfe 100644 --- a/Events.c +++ b/Events.c @@ -944,9 +944,9 @@ void APIL2Trace(struct _MESSAGE * Message, char * Dirn) // supervisory if (PF[0]) - udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"pf\": \"%s\", \"rseq\": %d, \"tseq\": %d", PF, NR, NS); + udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"pf\": \"%s\", \"rseq\": %d", PF, NR); else - udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"rseq\": %d, \"tseq\": %d", NR, NS); + udplen += snprintf(&UDPMsg[udplen], 2048 - udplen, ", \"rseq\": %d", NR); } diff --git a/L4Code.c b/L4Code.c index a319504..9a37668 100644 --- a/L4Code.c +++ b/L4Code.c @@ -1929,19 +1929,34 @@ void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG) void SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) { + struct TNCINFO * TNC; + L3MSG->L4FLAGS = L4CACK | L4BUSY; // REJECT L3MSG->L4DATA[0] = 0; // WINDOW L3SWAPADDRESSES(L3MSG); L3MSG->L3TTL = L3LIVES; - C_Q_ADD(&LINK->TX_Q, L3MSG); + TNC = LINK->LINKPORT->TNC; + + if (LINK->NEIGHBOUR && LINK->NEIGHBOUR->TCPPort) + { + TCPNETROMSend(LINK->NEIGHBOUR, L3MSG); + ReleaseBuffer(L3MSG); + } + else if (TNC && TNC->NetRomMode) + SendVARANetromMsg(TNC, L3MSG); + else + C_Q_ADD(&LINK->TX_Q, L3MSG); + } VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) { // Paula's extension + struct TNCINFO * TNC; + L3MSG->L4RXNO = L3MSG->L4ID; L3MSG->L4TXNO = L3MSG->L4INDEX; @@ -1951,7 +1966,19 @@ VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) L3MSG->L3TTL = L3LIVES; L3MSG->LENGTH = (int)(&L3MSG->L4DATA[0] - (UCHAR *)L3MSG); - C_Q_ADD(&LINK->TX_Q, L3MSG); + + TNC = LINK->LINKPORT->TNC; + + if (LINK->NEIGHBOUR && LINK->NEIGHBOUR->TCPPort) + { + TCPNETROMSend(LINK->NEIGHBOUR, L3MSG); + ReleaseBuffer(L3MSG); + } + else if (TNC && TNC->NetRomMode) + SendVARANetromMsg(TNC, L3MSG); + else + C_Q_ADD(&LINK->TX_Q, L3MSG); + } diff --git a/LinBPQ.c b/LinBPQ.c index ad749d0..03af5a4 100644 --- a/LinBPQ.c +++ b/LinBPQ.c @@ -86,8 +86,14 @@ void SendBBSDataToPktMap(); void CloseAllLinks(); void hookNodeClosing(char * Reason); void NETROMTCPResolve(); +<<<<<<< Updated upstream extern uint64_t INP3timeLoadedMS; +||||||| Stash base + +extern uint64_t INP3timeLoadedMS; +======= +>>>>>>> Stashed changes BOOL IncludesMail = FALSE; BOOL IncludesChat = FALSE; @@ -861,8 +867,6 @@ int main(int argc, char * argv[]) if (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO)) Redirected = 1; - INP3timeLoadedMS = GetTickCount(); - #endif printf("G8BPQ AX25 Packet Switch System Version %s %s\n", TextVerstring, Datestring); diff --git a/NETROMTCP.c b/NETROMTCP.c index f756621..e1d9fec 100644 --- a/NETROMTCP.c +++ b/NETROMTCP.c @@ -110,6 +110,7 @@ struct ConnectionInfo * AllocateNRTCPRec() sockptr->SocketActive = TRUE; sockptr->ConnectTime = sockptr->LastSendTime = time(NULL); +<<<<<<< Updated upstream Debugprintf("NRTCP Allocated %d", i); return sockptr; } @@ -593,6 +594,1049 @@ void NETROMConnectionLost(struct ConnectionInfo * sockptr) Route->TCPSession = 0; Info->Call[0] = 0; +||||||| Stash base +/* +Copyright 2001-2022 John Wiseman G8BPQ + +This file is part of LinBPQ/BPQ32. + +LinBPQ/BPQ32 is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +LinBPQ/BPQ32 is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses +*/ + +/* +Netrom over TCP Support + +This is intended for operation over radio links with an IP interface, eg New Packet Radio or possibly microwave links + +To simplify interface to the rest of the oode dummy LINK and PORT records are created + +Packet Format is Length (2 byte little endian) Call (10 bytes ASCII) NETROM L3/4 Packet, starting 0xcf (to detect framing errors). + +A TCP message can contain multiple packets and/or partial packets + +It uses the Telnet Server, with port defined in NETROMPORT + +ROUTE definitions have an extra field, the TCP Port Number + +*/ + +//#pragma data_seg("_BPQDATA") + + +#define _CRT_SECURE_NO_DEPRECATE + +#include "time.h" +#include "stdio.h" +#include +//#include "vmm.h" + +#include "cheaders.h" +#include "asmstrucs.h" +#include "telnetserver.h" + +#define NETROM_PID 0xCF + +void NETROMConnectionLost(struct ConnectionInfo * sockptr); +int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo); +int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr); +void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info); +VOID SendRTTMsg(struct ROUTE * Route); +BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE); +VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG); +int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS); +VOID L3LINKCLOSED(struct _LINKTABLE * LINK, int Reason); + +struct NRTCPMsg +{ + short Length; + char Call[10]; + unsigned char PID; + char Packet[1024]; +}; + +struct NRTCPSTRUCT +{ + struct ConnectionInfo * sockptr; + struct _LINKTABLE * LINK; // Dummy Link Record for this ROUTE + struct ROUTE * Route; // May need backlink + char Call[10]; +}; + +struct NRTCPSTRUCT * NRTCPInfo[256] = {0}; + +// Do we want to use normal TCP server connections, which are limited, or our own. Let's try our own for now + +struct ConnectionInfo * AllocateNRTCPRec() +{ + struct ConnectionInfo * sockptr = 0; + struct NRTCPSTRUCT * Info; + int i; + + for (i = 0; i < 255; i++) + { + if (NRTCPInfo[i] == 0) + { + // only allocate as many as needed + + 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]; + + sockptr = Info->sockptr; + + if (sockptr->SocketActive == FALSE) + { + sockptr->SocketActive = TRUE; + sockptr->ConnectTime = sockptr->LastSendTime = time(NULL); + + Debugprintf("NRTCP Allocated %d", i); + return sockptr; + } + } + return 0; +} + +void checkNRTCPSockets(int portNo) +{ + SOCKET sock; + int Active = 0; + SOCKET maxsock; + int retval; + int i; + + struct timeval timeout; + fd_set readfd, writefd, exceptfd; + + struct ConnectionInfo * sockptr; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; // poll + + maxsock = 0; + + FD_ZERO(&readfd); + FD_ZERO(&writefd); + FD_ZERO(&exceptfd); + + for (i = 0; i < 255; i++) + { + if (NRTCPInfo[i] == 0) + break; // only as many as have been used + + sockptr = NRTCPInfo[i]->sockptr; + + if (sockptr->SocketActive == 0) + continue; + + if (sockptr->Connecting) + { + // look for complete or failed + + FD_SET(sockptr->socket, &writefd); + FD_SET(sockptr->socket, &exceptfd); + } + else + { + FD_SET(sockptr->socket, &readfd); + FD_SET(sockptr->socket, &exceptfd); + } + + Active++; + + if (sockptr->socket > maxsock) + maxsock = sockptr->socket; + } + + if (Active) + { + retval = select((int)maxsock + 1, &readfd, &writefd, &exceptfd, &timeout); + + if (retval == -1) + { + perror("data select"); + Debugprintf("NRTCP Select Error %d Active %d", WSAGetLastError(), Active); + } + else + { + if (retval) + { + // see who has data + + for (i = 0; i < 255; i++) + { + if (NRTCPInfo[i] == 0) + break; + + sockptr = NRTCPInfo[i]->sockptr; + + if (sockptr->SocketActive == 0) + continue; + + sock = sockptr->socket; + + if (FD_ISSET(sock, &writefd)) + NETROMConnected(sockptr, sock, NRTCPInfo[i]); + + if (FD_ISSET(sock, &readfd)) + DataSocket_ReadNETROM(sockptr, sock, NRTCPInfo[i], portNo); + + if (FD_ISSET(sock, &exceptfd)) + NETROMConnectionLost(sockptr); + } + } + } + } +} + +int NETROMOpenConnection(struct ROUTE * Route) +{ + struct NRTCPSTRUCT * Info; + struct ConnectionInfo * sockptr; + + Debugprintf("Opening NRTCP Connection"); + + if (Route->TCPSession) + { + // SESSION ALREADY EXISTS + + sockptr = Route->TCPSession->sockptr; + + if (sockptr->Connected || sockptr->Connecting) + return TRUE; + + // previous connect failed + } + else + { + sockptr = AllocateNRTCPRec(); + + if (sockptr == NULL) + return 0; + + Info = Route->TCPSession = NRTCPInfo[sockptr->Number]; + memcpy(Info->Call, MYNETROMCALL, 10); + Route->NEIGHBOUR_LINK = Info->LINK; + + Info->Route = Route; + Info->LINK->NEIGHBOUR = Route; + Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); + } + + return NETROMTCPConnect(Route, sockptr); + +} + +int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) +{ + int err; + u_long param=1; + BOOL bcopt=TRUE; + SOCKET sock; + struct sockaddr_in sinx; + int addrlen=sizeof(sinx); + char PortString[20]; + struct addrinfo hints, *res = 0, *saveres; + int Port = Route->TCPPort; + + sprintf(PortString, "%d", Port); + + // get host info, make socket, and connect it + + memset(&hints, 0, sizeof hints); + + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + + hints.ai_socktype = SOCK_STREAM; + getaddrinfo(Route->TCPHost, PortString, &hints, &res); + + if (!res) + { + err = WSAGetLastError(); + Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err); + return FALSE; // Resolve failed + } + + // Step thorough the list of hosts + + saveres = res; // Save for free + + sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + + if (sock == INVALID_SOCKET) + { + Debugprintf, ("Netrom over TCP Create Socket Failed"); + return FALSE; + } + + ioctl(sock, FIONBIO, ¶m); + + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4); + + + if (connect(sock, res->ai_addr, (int)res->ai_addrlen) == 0) + { + // + // Connected successful + // + + sockptr->Connected = TRUE; + freeaddrinfo(saveres); + + return TRUE; + } + else + { + freeaddrinfo(saveres); + + err=WSAGetLastError(); + + if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK + { + // Connect in Progress + + sockptr->Connecting = TRUE; + return TRUE; + } + else + { + // Connect failed + + closesocket(sockptr->socket); + + return FALSE; + } + } + + return FALSE; +} + + + + +void NETROMConnectionAccepted(struct ConnectionInfo * sockptr) +{ + // Not sure we can do much here until first message arrives with callsign + + sockptr->Connected = TRUE; + Debugprintf("NRTCP Connection Accepted"); +} + +void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info) +{ + // Connection Complete + + Debugprintf("NRTCP Connected"); + + sockptr->Connecting = FALSE; + sockptr->Connected = TRUE; + + Info->LINK->L2STATE = 5; + + if (Info->Route->INP3Node) + SendRTTMsg(Info->Route); +} + +int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo) +{ + int len=0, maxlen; + struct NRTCPMsg * Msg; + struct _L3MESSAGEBUFFER * L3Msg; + struct ROUTE * Route; + UCHAR axCall[7]; + PMESSAGE Buffer; + + ioctl(sock,FIONREAD,&len); + + maxlen = InputBufferLen - sockptr->InputLen; + + if (len > maxlen) len = maxlen; + + len = recv(sock, &sockptr->InputBuffer[sockptr->InputLen], len, 0); + + if (len == SOCKET_ERROR || len == 0) + { + // Failed or closed - clear connection + + NETROMConnectionLost(sockptr); + return 0; + } + + sockptr->InputLen += len; + + // Process data + +checkLen: + + // See if we have a whole packet + + Msg = (struct NRTCPMsg *)&sockptr->InputBuffer[0]; + + if (Msg->Length > sockptr->InputLen) // if not got whole frame wait + return 0; + + if (Info->Call[0] == 0) + { + // first packet - do we need to do anything? + + // This must be an incoming connection as Call is set before calling so need to find route record and set things up. + + memcpy(Info->Call, Msg->Call, 10); + + ConvToAX25(Msg->Call, axCall); + + if (FindNeighbour(axCall, portNo, &Route)) + { + Info->Route = Route; + Route->NEIGHBOUR_LINK = Info->LINK; + Info->LINK->NEIGHBOUR = Route; + Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); + Route->TCPSession = Info; + Info->LINK->L2STATE = 5; + + if (Info->Route->INP3Node) + SendRTTMsg(Info->Route); + } + else + goto seeifMore; // Should we kill connection? + } + + + if (memcmp(Info->Call, Msg->Call, 10) != 0) + { + // something wrong - maybe connection reused + } + + // Format as if come from an ax.25 link + + L3Msg = GetBuff(); + + if (L3Msg == 0) + goto seeifMore; + + L3Msg->LENGTH = (Msg->Length - 12) + MSGHDDRLEN; + L3Msg->Next = 0; + L3Msg->Port = 0; + L3Msg->L3PID = NETROM_PID; + memcpy(&L3Msg->L3SRCE, Msg->Packet, Msg->Length - 13); + + // Create a dummy L2 message so we can trace it + + Buffer = GetBuff(); + + if (Buffer) + { + Buffer->CHAIN = 0; + Buffer->CTL = 0; + Buffer->PORT = portNo; + + ConvToAX25(Info->Call, Buffer->ORIGIN); + ConvToAX25(MYNETROMCALL, Buffer->DEST); + + memcpy(Buffer->L2DATA, &L3Msg->L3SRCE[0], Msg->Length - 13); + Buffer->ORIGIN[6] |= 1; // Set end of calls + Buffer->PID = NETROM_PID; + Buffer->LENGTH = Msg->Length + 10; + time(&Buffer->Timestamp); + + BPQTRACE(Buffer, FALSE); + ReleaseBuffer(Buffer); + } + + NETROMMSG(Info->LINK, L3Msg); + +seeifMore: + + sockptr->InputLen -= Msg->Length; + + if (sockptr->InputLen > 0) + { + memmove(sockptr->InputBuffer, &sockptr->InputBuffer[Msg->Length], sockptr->InputLen); + goto checkLen; + } + + return 0; +} + +VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) +{ + struct NRTCPMsg Msg; + unsigned char * Data = (unsigned char *)&Frame->L3SRCE[0]; + int DataLen = Frame->LENGTH - (MSGHDDRLEN + 1); // Not including PID + int Ret; + PMESSAGE Buffer; + + Msg.Length = DataLen + 13; // include PID + memcpy(Msg.Call, MYNETROMCALL, 10); + Msg.PID = NETROM_PID; + memcpy(Msg.Packet, Data, DataLen); + + if (Route->TCPSession == 0) + return; + + Ret = send(Route->TCPSession->sockptr->socket, (char *)&Msg, DataLen + 13, 0); + + // Create a dummy L2 message so we can trace it + + Buffer = GetBuff(); + + if (Buffer) + { + Buffer->CHAIN = 0; + Buffer->CTL = 0; + Buffer->PORT = Route->NEIGHBOUR_PORT | 128; // TX Flag + + ConvToAX25(Route->TCPSession->Call, Buffer->DEST); + ConvToAX25(MYNETROMCALL, Buffer->ORIGIN); + + memcpy(Buffer->L2DATA, &Frame->L3SRCE[0], DataLen); + Buffer->ORIGIN[6] |= 1; // Set end of calls + Buffer->PID = NETROM_PID; + Buffer->LENGTH = DataLen + 15 + MSGHDDRLEN; + time(&Buffer->Timestamp); + + BPQTRACE(Buffer, FALSE); + ReleaseBuffer(Buffer); + } + +} + + +void NETROMConnectionLost(struct ConnectionInfo * sockptr) +{ + struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number]; + struct ROUTE * Route; + + closesocket(sockptr->socket); + + // If there is an attached route (there should be) clear all connections + + if (Info) + { + Route = Info->Route; + + if (sockptr->Connected) + L3LINKCLOSED(Info->LINK, LINKLOST); + + if (sockptr->Connecting) + L3LINKCLOSED(Info->LINK, SETUPFAILED); + + Route->TCPSession = 0; + + Info->Call[0] = 0; + } + + sockptr->SocketActive = FALSE; + + memset(sockptr, 0, sizeof(struct ConnectionInfo)); +} + +======= +// Debugprintf("NRTCP Allocated %d", i); + return sockptr; + } + } + return 0; +} + +void checkNRTCPSockets(int portNo) +{ + SOCKET sock; + int Active = 0; + SOCKET maxsock; + int retval; + int i; + + struct timeval timeout; + fd_set readfd, writefd, exceptfd; + + struct ConnectionInfo * sockptr; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; // poll + + maxsock = 0; + + FD_ZERO(&readfd); + FD_ZERO(&writefd); + FD_ZERO(&exceptfd); + + for (i = 0; i < 255; i++) + { + if (NRTCPInfo[i] == 0) + break; // only as many as have been used + + sockptr = NRTCPInfo[i]->sockptr; + + if (sockptr->SocketActive == 0) + continue; + + if (sockptr->Connecting) + { + // look for complete or failed + + FD_SET(sockptr->socket, &writefd); + FD_SET(sockptr->socket, &exceptfd); + } + else + { + FD_SET(sockptr->socket, &readfd); + FD_SET(sockptr->socket, &exceptfd); + } + + Active++; + + if (sockptr->socket > maxsock) + maxsock = sockptr->socket; + } + + if (Active) + { + retval = select((int)maxsock + 1, &readfd, &writefd, &exceptfd, &timeout); + + if (retval == -1) + { + perror("data select"); + Debugprintf("NRTCP Select Error %d Active %d", WSAGetLastError(), Active); + } + else + { + if (retval) + { + // see who has data + + for (i = 0; i < 255; i++) + { + if (NRTCPInfo[i] == 0) + break; + + sockptr = NRTCPInfo[i]->sockptr; + + if (sockptr->SocketActive == 0) + continue; + + sock = sockptr->socket; + + if (FD_ISSET(sock, &writefd)) + NETROMConnected(sockptr, sock, NRTCPInfo[i]); + + if (FD_ISSET(sock, &readfd)) + DataSocket_ReadNETROM(sockptr, sock, NRTCPInfo[i], portNo); + + if (FD_ISSET(sock, &exceptfd)) + NETROMConnectionLost(sockptr); + } + } + } + } +} + +int NETROMOpenConnection(struct ROUTE * Route) +{ + struct NRTCPSTRUCT * Info; + struct ConnectionInfo * sockptr; + char farCall[10]; + + farCall[ConvFromAX25(Route->NEIGHBOUR_CALL, farCall)] = 0; + +// Debugprintf("Opening NRTCP Connection to %s", farCall); + + if (Route->TCPSession) + { + // SESSION ALREADY EXISTS + + sockptr = Route->TCPSession->sockptr; + + if (sockptr->Connected || sockptr->Connecting) + return TRUE; + + // previous connect failed + } + else + { + sockptr = AllocateNRTCPRec(); + + if (sockptr == NULL) + return 0; + + 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); + } + + return NETROMTCPConnect(Route, sockptr); + +} + +void NETROMTCPResolve() +{ + struct ROUTE * Route = NEIGHBOURS; + int n = MAXNEIGHBOURS; + struct addrinfo hints, *res = 0; + char PortString[20]; + int err; + + while (n--) + { + if (Route->TCPAddress) + { + // try to resolve host + + sprintf(PortString, "%d", Route->TCPPort); + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + getaddrinfo(Route->TCPHost, PortString, &hints, &res); + + err = WSAGetLastError(); + + if (res) + { + Route->TCPAddress->ai_family = res->ai_family; + Route->TCPAddress->ai_socktype = res->ai_socktype; + Route->TCPAddress->ai_protocol = res->ai_protocol; + Route->TCPAddress->ai_addrlen = res->ai_addrlen; + memcpy(Route->TCPAddress->ai_addr, res->ai_addr, sizeof(struct sockaddr)); + freeaddrinfo(res); + } + } + + Route++; + } +} + +int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) +{ + int err; + u_long param=1; + BOOL bcopt=TRUE; + SOCKET sock; + struct sockaddr_in sinx; + int addrlen=sizeof(sinx); + char PortString[20]; + struct addrinfo * res = Route->TCPAddress; + int Port = Route->TCPPort; + + sprintf(PortString, "%d", Port); + + // get host info, make socket, and connect it + + if (res->ai_family == 0) + { +// err = WSAGetLastError(); +// Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err); + return FALSE; // Resolve failed + } + + sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + if (sock == INVALID_SOCKET) + { + Debugprintf, ("Netrom over TCP Create Socket Failed"); + return FALSE; + } + + ioctl(sock, FIONBIO, ¶m); + + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4); + + + if (connect(sock, res->ai_addr, (int)res->ai_addrlen) == 0) + { + // + // Connected successful + // + + sockptr->Connected = TRUE; + return TRUE; + } + else + { + err=WSAGetLastError(); + + if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK + { + // Connect in Progress + + sockptr->Connecting = TRUE; + return TRUE; + } + else + { + // Connect failed + + closesocket(sockptr->socket); + + return FALSE; + } + } + + return FALSE; +} + + + + +void NETROMConnectionAccepted(struct ConnectionInfo * sockptr) +{ + // Not sure we can do much here until first message arrives with callsign + + sockptr->Connected = TRUE; +// Debugprintf("NRTCP Connection Accepted"); +} + +void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info) +{ + // Connection Complete + +// Debugprintf("NRTCP Connected"); + + sockptr->Connecting = FALSE; + sockptr->Connected = TRUE; + + Info->LINK->L2STATE = 5; + + if (Info->Route->INP3Node) + SendRTTMsg(Info->Route); +} + +int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo) +{ + int len=0, maxlen; + struct NRTCPMsg * Msg; + struct _L3MESSAGEBUFFER * L3Msg; + struct ROUTE * Route; + UCHAR axCall[7]; + PMESSAGE Buffer; + + ioctl(sock,FIONREAD,&len); + + maxlen = InputBufferLen - sockptr->InputLen; + + if (len > maxlen) len = maxlen; + + len = recv(sock, &sockptr->InputBuffer[sockptr->InputLen], len, 0); + + if (len == SOCKET_ERROR || len == 0) + { + // Failed or closed - clear connection + + NETROMConnectionLost(sockptr); + return 0; + } + + sockptr->InputLen += len; + + // Process data + +checkLen: + + // See if we have a whole packet + + Msg = (struct NRTCPMsg *)&sockptr->InputBuffer[0]; + + if (Msg->Length > sockptr->InputLen) // if not got whole frame wait + return 0; + + if (Info->Call[0] == 0) + { + // first packet - do we need to do anything? + + // 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); + + if (FindNeighbour(axCall, portNo, &Route)) + { + Info->Route = Route; + Route->NEIGHBOUR_LINK = Info->LINK; + Route->NEIGHBOUR_PORT = portNo; + Info->LINK->NEIGHBOUR = Route; + Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(portNo); + Route->TCPSession = Info; + Info->LINK->L2STATE = 5; + + if (Info->Route->INP3Node) + SendRTTMsg(Info->Route); + } + else + { + Debugprintf("Neighbour %s port %d not found - closing connection", Msg->Call, portNo); + closesocket(sockptr->socket); + sockptr->SocketActive = FALSE; + memset(sockptr, 0, sizeof(struct ConnectionInfo)); + Info->Call[0] = 0; + return 0; + } + } + + + if (memcmp(Info->Call, Msg->Call, 10) != 0) + { + Debugprintf("NRTCP Mismatch - closing connection"); + + closesocket(sockptr->socket); + sockptr->SocketActive = FALSE; + memset(sockptr, 0, sizeof(struct ConnectionInfo)); + Info->Call[0] = 0; + return 0; + } + + // Format as if come from an ax.25 link + + L3Msg = GetBuff(); + + if (L3Msg == 0) + goto seeifMore; + + L3Msg->LENGTH = (Msg->Length - 12) + MSGHDDRLEN; + L3Msg->Next = 0; + L3Msg->Port = portNo; + L3Msg->L3PID = NETROM_PID; + memcpy(&L3Msg->L3SRCE, Msg->Packet, Msg->Length - 13); + + // Create a dummy L2 message so we can trace it + + Buffer = GetBuff(); + + if (Buffer) + { + Buffer->CHAIN = 0; + Buffer->CTL = 0; + Buffer->PORT = portNo; + + ConvToAX25(Info->Call, Buffer->ORIGIN); + ConvToAX25(MYNETROMCALL, Buffer->DEST); + + memcpy(Buffer->L2DATA, &L3Msg->L3SRCE[0], Msg->Length - 13); + Buffer->ORIGIN[6] |= 1; // Set end of calls + Buffer->PID = NETROM_PID; + Buffer->LENGTH = Msg->Length + 10; + time(&Buffer->Timestamp); + + BPQTRACE(Buffer, FALSE); + + if(NodeAPISocket) + NetromTCPTrace(Buffer, "rcvd"); + + ReleaseBuffer(Buffer); + } + + NETROMMSG(Info->LINK, L3Msg); + +seeifMore: + + sockptr->InputLen -= Msg->Length; + + if (sockptr->InputLen > 0) + { + memmove(sockptr->InputBuffer, &sockptr->InputBuffer[Msg->Length], sockptr->InputLen); + goto checkLen; + } + + return 0; +} + +VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) +{ + struct NRTCPMsg Msg; + unsigned char * Data = (unsigned char *)&Frame->L3SRCE[0]; + int DataLen = Frame->LENGTH - (MSGHDDRLEN + 1); // Not including PID + int Ret; + PMESSAGE Buffer; + + Msg.Length = DataLen + 13; // include PID + memcpy(Msg.Call, MYNETROMCALL, 10); + Msg.PID = NETROM_PID; + memcpy(Msg.Packet, Data, DataLen); + + if (Route->TCPSession == 0) + return; + + Ret = send(Route->TCPSession->sockptr->socket, (char *)&Msg, DataLen + 13, 0); + + // Create a dummy L2 message so we can trace it + + Buffer = GetBuff(); + + if (Buffer) + { + Buffer->CHAIN = 0; + Buffer->CTL = 0; + Buffer->PORT = Route->NEIGHBOUR_PORT; + + ConvToAX25(Route->TCPSession->Call, Buffer->DEST); + ConvToAX25(MYNETROMCALL, Buffer->ORIGIN); + + memcpy(Buffer->L2DATA, &Frame->L3SRCE[0], DataLen); + Buffer->ORIGIN[6] |= 1; // Set end of calls + Buffer->PID = NETROM_PID; + Buffer->LENGTH = DataLen + 15 + MSGHDDRLEN; + time(&Buffer->Timestamp); + + if(NodeAPISocket) + NetromTCPTrace(Buffer, "sent"); + + Buffer->PORT = Route->NEIGHBOUR_PORT | 128; // TX Flag + BPQTRACE(Buffer, FALSE); + + + ReleaseBuffer(Buffer); + } + +} + + +void NETROMConnectionLost(struct ConnectionInfo * sockptr) +{ + struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number]; + struct ROUTE * Route; + + closesocket(sockptr->socket); + + // If there is an attached route (there should be) clear all connections + + if (Info) + { + Route = Info->Route; + + if (sockptr->Connected) + L3LINKCLOSED(Info->LINK, LINKLOST); + + if (sockptr->Connecting) + L3LINKCLOSED(Info->LINK, SETUPFAILED); + + if (Route) + Route->TCPSession = 0; + + Info->Call[0] = 0; + Info->LINK->L2STATE = 0; +>>>>>>> Stashed changes } sockptr->SocketActive = FALSE; diff --git a/Versions.h b/Versions.h index a988953..79b7aea 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,16 @@ #endif +<<<<<<< Updated upstream #define KVers 6,0,25,11 #define KVerstring "6.0.25.11\0" +||||||| Stash base +#define KVers 6,0,25,8 +#define KVerstring "6.0.25.8\0" +======= +#define KVers 6,0,25,12 +#define KVerstring "6.0.25.12\0" +>>>>>>> Stashed changes #ifdef CKernel diff --git a/compatbits.c b/compatbits.c index f93b2e5..a6ce8f5 100644 --- a/compatbits.c +++ b/compatbits.c @@ -25,6 +25,8 @@ Stuff to make compiling on WINDOWS and LINUX easier #ifdef WIN32 +#include + typedef unsigned int uint32_t; #define pthread_t uint32_t @@ -41,6 +43,7 @@ int pthread_equal(pthread_t T1, pthread_t T2) #include #include #include +#include #define BOOL int @@ -188,3 +191,27 @@ void closesocket(int sock) } #endif + +#ifdef WIN32 + +uint32_t GetTickCountINP3() +{ + // Returns system uptime in 10 mS, lower 20 bits only + + return (GetTickCount() / 10) & 0xfffff; +} +#else + +uint64_t GetTickCount(); + +uint32_t GetTickCountINP3() +{ + uint64_t Ticks = GetTickCount(); + + // Returns system uptime in 10 mS, lower 20 bits only + + return (Ticks / 10) & 0xfffff; +} + +#endif + diff --git a/compatbits.h b/compatbits.h index 9707771..1642af9 100644 --- a/compatbits.h +++ b/compatbits.h @@ -24,6 +24,7 @@ Stuff to make compiling on WINDOWS and LINUX easier #define strtoll _strtoi64 + #ifdef _WIN64 #include "stdint.h" #else @@ -219,7 +220,7 @@ typedef struct tagRECT #endif - +uint32_t GetTickCountINP3(); #ifdef LINBPQ From 559d5bbf7c0f401c1def858a9695b43b56a993ec Mon Sep 17 00:00:00 2001 From: Dave Hibberd Date: Tue, 23 Dec 2025 16:30:05 +0000 Subject: [PATCH 2/2] New upstream version 6.0.25.13+repack --- AISCommon.c | 4 +- APRSCode.c | 106 ----- BPQINP3.c | 255 ++++++------ Bpq32.c | 26 +- Cmd.c | 65 +-- CommonCode.c | 10 + HTTPcode.c | 28 +- L3Code.c | 14 +- LinBPQ.c | 9 - NETROMTCP.c | 1042 +---------------------------------------------- TelnetV6.c | 132 +++--- Versions.h | 12 +- asmstrucs.h | 8 +- cMain.c | 7 +- config.c | 83 ++-- configstructs.h | 1 + datadefs.c | 2 +- 17 files changed, 328 insertions(+), 1476 deletions(-) diff --git a/AISCommon.c b/AISCommon.c index e123bb2..2d7bc33 100644 --- a/AISCommon.c +++ b/AISCommon.c @@ -3256,9 +3256,9 @@ static VOID ADSBConnect(void * unused) { err=WSAGetLastError(); #ifdef LINBPQ - printf("Connect Failed for ADSB socket - error code = %d\n", err); + // printf("Connect Failed for ADSB socket - error code = %d\n", err); #else - Debugprintf("Connect Failed for ADSB socket - error code = %d", err); + // Debugprintf("Connect Failed for ADSB socket - error code = %d", err); #endif closesocket(TCPSock); ADSBConnected = FALSE; diff --git a/APRSCode.c b/APRSCode.c index 6e65001..d236fc4 100644 --- a/APRSCode.c +++ b/APRSCode.c @@ -443,110 +443,6 @@ HANDLE hMapFile; static int LogAge = 14; -#ifdef WIN32 - -int DeleteAPRSLogFiles() -{ - WIN32_FIND_DATA ffd; - - char szDir[MAX_PATH]; - char File[MAX_PATH]; - HANDLE hFind = INVALID_HANDLE_VALUE; - DWORD dwError=0; - LARGE_INTEGER ft; - time_t now = time(NULL); - int Age; - - // Prepare string for use with FindFile functions. First, copy the - // string to a buffer, then append '\*' to the directory name. - - strcpy(szDir, GetLogDirectory()); - strcat(szDir, "/logs/APRS*.log"); - - // Find the first file in the directory. - - hFind = FindFirstFile(szDir, &ffd); - - if (INVALID_HANDLE_VALUE == hFind) - return dwError; - - // Walk directory - - do - { - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - OutputDebugString(ffd.cFileName); - } - else - { - ft.HighPart = ffd.ftCreationTime.dwHighDateTime; - ft.LowPart = ffd.ftCreationTime.dwLowDateTime; - - ft.QuadPart -= 116444736000000000; - ft.QuadPart /= 10000000; - - Age = (int)((now - ft.LowPart) / 86400); - - if (Age > LogAge) - { - sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0); - Debugprintf("Deleting %s", File); - DeleteFile(File); - } - } - } - while (FindNextFile(hFind, &ffd) != 0); - - FindClose(hFind); - return dwError; -} - -#else - -#include - -int APRSFilter(const struct dirent * dir) -{ - return (memcmp(dir->d_name, "APRS", 4) == 0 && strstr(dir->d_name, ".log")); -} - -int DeleteAPRSLogFiles() -{ - struct dirent **namelist; - int n; - struct stat STAT; - time_t now = time(NULL); - int Age = 0, res; - char FN[256]; - - n = scandir("logs", &namelist, APRSFilter, alphasort); - - if (n < 0) - perror("scandir"); - else - { - while(n--) - { - sprintf(FN, "logs/%s", namelist[n]->d_name); - if (stat(FN, &STAT) == 0) - { - Age = (now - STAT.st_mtime) / 86400; - - if (Age > LogAge) - { - Debugprintf("Deleting %s\n", FN); - unlink(FN); - } - } - free(namelist[n]); - } - free(namelist); - } - return 0; -} -#endif - int APRSWriteLog(char * msg) { FILE *file; @@ -646,8 +542,6 @@ Dll BOOL APIENTRY Init_APRS() MobileBeaconInterval = 0; BeaconInterval = 0; - DeleteAPRSLogFiles(); - memset(MHTABLE, 0, sizeof(MHTABLE)); ConvToAX25(MYNODECALL, MYCALL); diff --git a/BPQINP3.c b/BPQINP3.c index d87aa69..86bfc96 100644 --- a/BPQINP3.c +++ b/BPQINP3.c @@ -37,6 +37,9 @@ 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 PositivePercent = 80; // if time is 20% better send positive info + VOID SendNegativeInfo(); VOID SortRoutes(struct DEST_LIST * Dest); VOID SendRTTMsg(struct ROUTE * Route); @@ -90,7 +93,7 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops, VOID UpdateRoute(struct DEST_LIST * Dest, struct INP3_DEST_ROUTE_ENTRY * ROUTEPTR, int hops, int rtt); VOID KillRoute(struct INP3_DEST_ROUTE_ENTRY * ROUTEPTR); VOID AddHere(struct INP3_DEST_ROUTE_ENTRY * ROUTEPTR,struct ROUTE * Route , int hops, int rtt); -VOID SendRIPToNeighbour(struct ROUTE * Route); +VOID SendRIFToNewNeighbour(struct ROUTE * Route); VOID DecayNETROMRoutes(struct ROUTE * Route); VOID DeleteINP3Routes(struct ROUTE * Route); BOOL L2SETUPCROSSLINKEX(PROUTE ROUTE, int Retries); @@ -200,7 +203,8 @@ VOID DeleteINP3Routes(struct ROUTE * Route) { // Only entry - Dest->INP3ROUTE[0].SRTT = 60000; + + Dest->INP3ROUTE[0].STT = 60000; Dest->INP3ROUTE[0].Hops = 255; if (DEBUGINP3) Debugprintf("Was the only INP3 route"); @@ -211,7 +215,7 @@ VOID DeleteINP3Routes(struct ROUTE * Route) continue; } - Dest->INP3ROUTE[1].LastRTT = Dest->INP3ROUTE[0].SRTT; // So next scan will check if rtt has increaced enough to need a RIF + Dest->INP3ROUTE[1].LastTT = 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)); @@ -361,6 +365,9 @@ VOID ProcessRTTReply(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff) if (RTT > 60000 || RTT < 0) return; // Ignore if more than 60 secs (why ??) + if (DEBUGINP3) Debugprintf("INP3 RTT reply from %s - SRTT was %d, Current RTT %d", Normcall, Route->SRTT, RTT); + + Route->RTT = RTT; if (Route->SRTT == 0) @@ -553,6 +560,7 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops, } + // Adding New Node memset(Dest, 0, sizeof(struct DEST_LIST)); @@ -562,8 +570,8 @@ VOID UpdateNode(struct ROUTE * Route, UCHAR * axcall, UCHAR * alias, int hops, // Set up First Route Dest->INP3ROUTE[0].Hops = hops; - Dest->INP3ROUTE[0].SRTT = rtt; - Dest->INP3ROUTE[0].LastRTT = 0; + Dest->INP3ROUTE[0].STT = rtt; + Dest->INP3ROUTE[0].LastTT = 0; Dest->INP3FLAGS = NewNode; @@ -587,7 +595,7 @@ Found: // Update ALIAS ConvFromAX25(Dest->DEST_CALL, call); - if (DEBUGINP3) Debugprintf("INP3 Updating Node %s Hops %d RTT %d", call, hops, rtt); + if (DEBUGINP3) Debugprintf("INP3 Updating Node %s Hops %d TT %d", call, hops, rtt); if (alias[0] > ' ') memcpy(Dest->DEST_ALIAS, alias, 6); @@ -598,7 +606,7 @@ Found: if (ROUTEPTR->ROUT_NEIGHBOUR == Route) { - if (DEBUGINP3) Debugprintf("INP3 Already have as route[0] - updating"); + if (DEBUGINP3) Debugprintf("INP3 Already have as route[0] - TT was %d updating to %d", ROUTEPTR->STT, rtt); UpdateRoute(Dest, ROUTEPTR, hops, rtt); return; } @@ -607,7 +615,7 @@ Found: if (ROUTEPTR->ROUT_NEIGHBOUR == Route) { - if (DEBUGINP3) Debugprintf("INP3 Already have as route[1] - updating"); + if (DEBUGINP3) Debugprintf("INP3 Already have as route[1] - TT was %d updating to %d", ROUTEPTR->STT, rtt); UpdateRoute(Dest, ROUTEPTR, hops, rtt); return; } @@ -616,7 +624,7 @@ Found: if (ROUTEPTR->ROUT_NEIGHBOUR == Route) { - if (DEBUGINP3) Debugprintf("INP3 Already have as route[2] - updating"); + if (DEBUGINP3) Debugprintf("INP3 Already have as route[2] - TT was %d updating to %d", ROUTEPTR->STT, rtt); UpdateRoute(Dest, ROUTEPTR, hops, rtt); return; } @@ -646,7 +654,7 @@ Found: // Note that wont replace any netrom routes with INP3 ones unless we add pseudo rtt values to netrom entries - if (Dest->INP3ROUTE[0].SRTT > rtt) + if (Dest->INP3ROUTE[0].STT > rtt) { // We are better. Move others down and add on front @@ -658,7 +666,7 @@ Found: return; } - if (Dest->INP3ROUTE[1].SRTT > rtt) + if (Dest->INP3ROUTE[1].STT > rtt) { // We are better. Move 2nd down and add @@ -668,7 +676,7 @@ Found: return; } - if (Dest->INP3ROUTE[2].SRTT > rtt) + if (Dest->INP3ROUTE[2].STT > rtt) { // We are better. Add here @@ -688,63 +696,13 @@ Found: VOID AddHere(struct INP3_DEST_ROUTE_ENTRY * ROUTEPTR,struct ROUTE * Route , int hops, int rtt) { ROUTEPTR->Hops = hops; - ROUTEPTR->SRTT = rtt; - ROUTEPTR->LastRTT = 0; - ROUTEPTR->RTT = 0; + ROUTEPTR->LastTT = 0; + ROUTEPTR->STT = rtt; ROUTEPTR->ROUT_NEIGHBOUR = Route; return; } - -/* LEA EDI,DEST_CALL[EBX] - MOV ECX,7 - REP MOVSB - - MOV ECX,6 ; ADD ALIAS - MOV ESI,OFFSET32 TEMPFIELD - REP MOVSB - - POP ESI -; -; GET _NEIGHBOURS FOR THIS DESTINATION -; - CALL CONVTOAX25 - JNZ SHORT BADROUTE -; - CALL GETVALUE - MOV _SAVEPORT,AL ; SET PORT FOR _FINDNEIGHBOUR - - CALL GETVALUE - MOV _ROUTEQUAL,AL -; - MOV ESI,OFFSET32 AX25CALL - - PUSH EBX ; SAVE DEST - CALL _FINDNEIGHBOUR - MOV EAX,EBX ; ROUTE TO AX - POP EBX - - JZ SHORT NOTBADROUTE - - JMP SHORT BADROUTE - -NOTBADROUTE: -; -; UPDATE ROUTE LIST FOR THIS DEST -; - MOV ROUT1_NEIGHBOUR[EBX],EAX - MOV AL,_ROUTEQUAL - MOV ROUT1_QUALITY[EBX],AL - MOV ROUT1_OBSCOUNT[EBX],255 ; LOCKED -; - POP EDI - POP EBX - - INC _NUMBEROFNODES - - JMP SENDOK -*/ struct INP3_DEST_ROUTE_ENTRY Temp; @@ -762,7 +720,7 @@ VOID SortRoutes(struct DEST_LIST * Dest) if (Dest->INP3ROUTE[1].ROUT_NEIGHBOUR == 0) { Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0; - if (DEBUGINP3) Debugprintf("INP3 1 route %d %s", Dest->INP3ROUTE[0].SRTT, Call1); + if (DEBUGINP3) Debugprintf("INP3 1 route %d %s", Dest->INP3ROUTE[0].STT, Call1); return; // Only One, so cant be out of order } if (Dest->INP3ROUTE[2].ROUT_NEIGHBOUR == 0) @@ -772,9 +730,9 @@ VOID SortRoutes(struct DEST_LIST * Dest) Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0; Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; - if (DEBUGINP3) Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2); + if (DEBUGINP3) Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].STT, Call1, Dest->INP3ROUTE[1].STT, Call2); - if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT) + if (Dest->INP3ROUTE[0].STT <= Dest->INP3ROUTE[1].STT) return; // Swap one and two @@ -786,7 +744,7 @@ VOID SortRoutes(struct DEST_LIST * Dest) Call1[ConvFromAX25(Dest->INP3ROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call1)] = 0; Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; - if (DEBUGINP3) Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2); + if (DEBUGINP3) Debugprintf("INP3 2 routes %d %s %d %s", Dest->INP3ROUTE[0].STT, Call1, Dest->INP3ROUTE[1].STT, Call2); return; } @@ -797,16 +755,16 @@ VOID SortRoutes(struct DEST_LIST * Dest) Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0; - if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3); + if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].STT, Call1, Dest->INP3ROUTE[1].STT, Call2, Dest->INP3ROUTE[2].STT, Call3); // In order? - if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT && Dest->INP3ROUTE[1].SRTT <= Dest->INP3ROUTE[2].SRTT)// In order? + if (Dest->INP3ROUTE[0].STT <= Dest->INP3ROUTE[1].STT && Dest->INP3ROUTE[1].STT <= Dest->INP3ROUTE[2].STT)// In order? return; // If second is better that first swap - if (Dest->INP3ROUTE[0].SRTT > Dest->INP3ROUTE[1].SRTT) + if (Dest->INP3ROUTE[0].STT > Dest->INP3ROUTE[1].STT) { memcpy(&Temp, &Dest->INP3ROUTE[0], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memcpy(&Dest->INP3ROUTE[0], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY)); @@ -818,11 +776,11 @@ VOID SortRoutes(struct DEST_LIST * Dest) Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0; - if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3); + if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].STT, Call1, Dest->INP3ROUTE[1].STT, Call2, Dest->INP3ROUTE[2].STT, Call3); // if 3 is better than 2 swap them. As two is worse than one. three will then be worst - if (Dest->INP3ROUTE[1].SRTT > Dest->INP3ROUTE[2].SRTT) + if (Dest->INP3ROUTE[1].STT > Dest->INP3ROUTE[2].STT) { memcpy(&Temp, &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memcpy(&Dest->INP3ROUTE[1], &Dest->INP3ROUTE[2], sizeof(struct INP3_DEST_ROUTE_ENTRY)); @@ -834,12 +792,12 @@ VOID SortRoutes(struct DEST_LIST * Dest) Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0; - if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3); + if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].STT, Call1, Dest->INP3ROUTE[1].STT, Call2, Dest->INP3ROUTE[2].STT, Call3); // 3 is now slowest. 2 could still be better than 1 - if (Dest->INP3ROUTE[0].SRTT > Dest->INP3ROUTE[1].SRTT) + if (Dest->INP3ROUTE[0].STT > Dest->INP3ROUTE[1].STT) { memcpy(&Temp, &Dest->INP3ROUTE[0], sizeof(struct INP3_DEST_ROUTE_ENTRY)); memcpy(&Dest->INP3ROUTE[0], &Dest->INP3ROUTE[1], sizeof(struct INP3_DEST_ROUTE_ENTRY)); @@ -851,9 +809,9 @@ VOID SortRoutes(struct DEST_LIST * Dest) Call2[ConvFromAX25(Dest->INP3ROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call2)] = 0; Call3[ConvFromAX25(Dest->INP3ROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Call3)] = 0; - if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].SRTT, Call1, Dest->INP3ROUTE[1].SRTT, Call2, Dest->INP3ROUTE[2].SRTT, Call3); + if (DEBUGINP3) Debugprintf("INP3 3 routes %d %s %d %s %d %s", Dest->INP3ROUTE[0].STT, Call1, Dest->INP3ROUTE[1].STT, Call2, Dest->INP3ROUTE[2].STT, Call3); - if (Dest->INP3ROUTE[0].SRTT <= Dest->INP3ROUTE[1].SRTT && Dest->INP3ROUTE[1].SRTT <= Dest->INP3ROUTE[2].SRTT)// In order? + if (Dest->INP3ROUTE[0].STT <= Dest->INP3ROUTE[1].STT && Dest->INP3ROUTE[1].STT <= Dest->INP3ROUTE[2].STT)// In order? return; // Something went wrong @@ -871,7 +829,7 @@ VOID UpdateRoute(struct DEST_LIST * Dest, struct INP3_DEST_ROUTE_ENTRY * ROUTEPT // This is not a INP3 Route - Convert it ROUTEPTR->Hops = hops; - ROUTEPTR->SRTT = rtt; + ROUTEPTR->STT = rtt; SortRoutes(Dest); return; @@ -879,7 +837,7 @@ VOID UpdateRoute(struct DEST_LIST * Dest, struct INP3_DEST_ROUTE_ENTRY * ROUTEPT if (rtt == 60000) { - ROUTEPTR->SRTT = rtt; + ROUTEPTR->STT = rtt; ROUTEPTR->Hops = hops; SortRoutes(Dest); @@ -887,7 +845,7 @@ VOID UpdateRoute(struct DEST_LIST * Dest, struct INP3_DEST_ROUTE_ENTRY * ROUTEPT } - ROUTEPTR->SRTT = rtt; + ROUTEPTR->STT = rtt; ROUTEPTR->Hops = hops; SortRoutes(Dest); @@ -947,6 +905,9 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len if (OtherRTT < 60000) // Don't save suspect values Route->NeighbourSRTT = OtherRTT; + + if (DEBUGINP3) Debugprintf("INP3 RTT Msg from %s remote SRTT %u", Normcall, OtherRTT); + } // Look for $M and $H (MAXRTT MAXHOPS) @@ -1174,7 +1135,6 @@ int SendRIPTimer() int INP3Delay; char Normcall[10]; - for (count=0; countNEIGHBOUR_CALL[0] != 0) @@ -1236,6 +1196,7 @@ int SendRIPTimer() L2SETUPCROSSLINKEX(Route, 2); // Only try SABM twice Route->NeighbourSRTT = 0; // just in case! + Route->BCTimer = 0; Route->LastConnectAttempt = REALTIMETICKS; @@ -1296,12 +1257,24 @@ int SendRIPTimer() char Call [11] = ""; ConvFromAX25(Route->NEIGHBOUR_CALL, Call); - if (DEBUGINP3) Debugprintf("BPQ32 INP3 Neighbour %s Lost", Call); + if (DEBUGINP3) Debugprintf("BPQ32 INP3 Neighbour %s Lost (No Response to RTT)", Call); + + DecayNETROMRoutes(Route); + DeleteINP3Routes(Route); Route->Status = 0; // Down + + // close the link + + if (Route->TCPPort == 0) // NetromTCP doesn't have a real link + { + Route->NEIGHBOUR_LINK->KILLTIMER = 0; + Route->NEIGHBOUR_LINK->L2TIMER = 1; // TO FORCE DISC + Route->NEIGHBOUR_LINK->L2STATE = 4; // DISCONNECTING + } } - Route->BCTimer=5; // Wait a while before retrying + Route->BCTimer = 5; // Wait a while before retrying } } @@ -1354,39 +1327,74 @@ VOID SendRIF(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Msg) SendNetFrame(Route, Msg); } -VOID SendRIPToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_ROUTE_ENTRY * Entry) +VOID SendRIFToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_ROUTE_ENTRY * Entry, int Negative) { struct ROUTE * Routes = NEIGHBOURS; struct _L3MESSAGEBUFFER * Msg; int count, MaxRoutes = MAXNEIGHBOURS; char Normcall[10]; - int sendHops, sendTT; + char Normcall2[10]; + int sendHops, sendTT, lastTT; + int sent = 0; Normcall[ConvFromAX25(axcall, Normcall)] = 0; - if (DEBUGINP3) Debugprintf("INP3 SendRIPToOtherNeighbours for %s", Normcall); - for (count=0; countINP3Node) && + if ((Entry->ROUT_NEIGHBOUR && Routes->INP3Node) && (Routes->Status) && (Routes != Entry->ROUT_NEIGHBOUR)) // Dont send to originator of route { - sendHops = Entry->Hops + 1; - sendTT = Entry->SRTT + Entry->ROUT_NEIGHBOUR->RTTIncrement; + // as the value sent will be different for each link, we need to check if change is enough here - // send, but only if within their constraints + sendHops = Entry->Hops + 1; + sendTT = Entry->STT + Entry->ROUT_NEIGHBOUR->RTTIncrement; + lastTT = Entry->LastTT + Entry->LastNeighbourTT; + + if (Negative) + { + // only send if significantly worse + + if (sendTT < (lastTT * NegativePercent) / 100) + { + Routes+=1; + continue; + } + } + else + { + // Send if significantly better + + if (sendTT > (lastTT * PositivePercent) / 100) + { + Routes+=1; + continue; + } + } + + sent++; + + + if (DEBUGINP3) Debugprintf("INP3 SendRIFToOtherNeighbours for %s", Normcall); + + 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); + + Entry->LastTT = Entry->STT; + Entry->LastNeighbourTT = Entry->ROUT_NEIGHBOUR->RTTIncrement; + + // send, but only if within their constraints if ((Routes->RemoteMAXHOPS == 0 || Routes->RemoteMAXHOPS >= Entry->Hops) && - (Routes->RemoteMAXRTT == 0 || Routes->RemoteMAXRTT >= Entry->SRTT || Entry->SRTT == 60000)) + (Routes->RemoteMAXRTT == 0 || Routes->RemoteMAXRTT >= Entry->STT || Entry->STT == 60000)) { - Msg = Routes->Msg; if (Msg == NULL) { - Normcall[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall)] = 0; - if (DEBUGINP3) Debugprintf("INP3 Building RIF to send to %s", Normcall); + Normcall2[ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall2)] = 0; + if (DEBUGINP3) Debugprintf("INP3 Building RIF to send to %s", Normcall2); Msg = Routes->Msg = CreateRIFHeader(Routes); } @@ -1398,6 +1406,7 @@ VOID SendRIPToOtherNeighbours(UCHAR * axcall, UCHAR * alias, struct INP3_DEST_RO else Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], axcall, alias, sendHops, sendTT); + if (Msg->LENGTH > 250 - 15) // if (Msg->LENGTH > Routes->NBOUR_PACLEN - 11) @@ -1408,11 +1417,17 @@ VOID SendRIPToOtherNeighbours(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 SendRIPToNeighbour(struct ROUTE * Route) +VOID SendRIFToNewNeighbour(struct ROUTE * Route) { int i; struct DEST_LIST * Dest = DESTS; @@ -1441,10 +1456,12 @@ VOID SendRIPToNeighbour(struct ROUTE * Route) // Best Route not via this neighbour - send, but only if within their constraints sendHops = Entry->Hops + 1; - sendTT = Entry->SRTT + Entry->ROUT_NEIGHBOUR->RTTIncrement; + Entry->LastTT = Entry->STT; + + sendTT = Entry->STT + Entry->ROUT_NEIGHBOUR->RTTIncrement; if ((Route->RemoteMAXHOPS == 0 || Route->RemoteMAXHOPS >= Entry->Hops) && - (Route->RemoteMAXRTT == 0 || Route->RemoteMAXRTT >= Entry->SRTT || Entry->SRTT == 60000)) + (Route->RemoteMAXRTT == 0 || Route->RemoteMAXRTT >= Entry->STT || Entry->STT == 60000)) { Msg = Route->Msg; @@ -1487,7 +1504,7 @@ VOID FlushRIFs() { Routes->Status |= SentOurRIF; SendOurRIF(Routes); - SendRIPToNeighbour(Routes); + SendRIFToNewNeighbour(Routes); } if (Routes->Msg) @@ -1505,9 +1522,11 @@ VOID FlushRIFs() VOID SendNegativeInfo() { - int i, Preload; + int i; struct DEST_LIST * Dest = DESTS; struct INP3_DEST_ROUTE_ENTRY * Entry; + char call[11]=""; + Dest--; @@ -1525,22 +1544,15 @@ VOID SendNegativeInfo() Entry = &Dest->INP3ROUTE[0]; - if (Entry->SRTT > Entry->LastRTT) - { - if (Entry->LastRTT) // if zero haven't yet reported +ve info - { - if (Entry->LastRTT == 1) // if 1, probably new, so send alias - SendRIPToOtherNeighbours(Dest->DEST_CALL, Dest->DEST_ALIAS, Entry); - else - SendRIPToOtherNeighbours(Dest->DEST_CALL, 0, Entry); + if (Entry->ROUT_NEIGHBOUR == 0) + continue; - Preload = Entry->SRTT /10; - if (Entry->SRTT < 60000) - Entry->LastRTT = Entry->SRTT + Preload; //10% Negative Preload - } - } + 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); + else + SendRIFToOtherNeighbours(Dest->DEST_CALL, 0, Entry, TRUE); - if (Entry->SRTT >= 60000) + if (Entry->STT >= 60000) { // It is dead, and we have reported it if necessary, so remove if no NETROM Routes @@ -1580,21 +1592,13 @@ VOID SendPositiveInfo() Dest++; Entry = &Dest->INP3ROUTE[0]; - - if (( (Entry->SRTT) && (Entry->LastRTT == 0) )|| // if zero haven't yet reported +ve info - ((((Entry->SRTT * 125) /100) < Entry->LastRTT) && // Better by 25% - ((Entry->LastRTT - Entry->SRTT) > 10))) // and 100ms - { - SendRIPToOtherNeighbours(Dest->DEST_CALL, 0, Entry); - Dest->INP3ROUTE[0].LastRTT = (Dest->INP3ROUTE[0].SRTT * 11) / 10; //10% Negative Preload - } + SendRIFToOtherNeighbours(Dest->DEST_CALL, 0, Entry, FALSE); } } VOID SendNewInfo() { int i; - unsigned int NewRTT; struct DEST_LIST * Dest = DESTS; struct INP3_DEST_ROUTE_ENTRY * Entry; @@ -1612,10 +1616,7 @@ VOID SendNewInfo() Entry = &Dest->INP3ROUTE[0]; - SendRIPToOtherNeighbours(Dest->DEST_CALL, Dest->DEST_ALIAS, Entry); - - NewRTT = (Entry->SRTT * 11) / 10; - Entry->LastRTT = NewRTT; //10% Negative Preload + SendRIFToOtherNeighbours(Dest->DEST_CALL, Dest->DEST_ALIAS, Entry, FALSE); } } } diff --git a/Bpq32.c b/Bpq32.c index 23f53e9..e88e26a 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1292,6 +1292,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Improvments to INP3 (4, 5) // Add Node API /api/tcpqueues (5) // Add sending link events to OARC API (disabled by default) (6) +// Add option to write monitor output to a file (6) // Fix possible program error in Telnet_Connected (7) // Close links when program is closed down (7) // Fix possible problem with deleting routes when using both NODES and INP3 routing on same link (7) @@ -1300,12 +1301,10 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Fix FRMR caused by sending SREJ when no frames outstanding (8) // Fix some issues with NetromX connects and Route Selection when running INP3 and NODES routing (9) // Fix connecting to a netrom node with c p node command (10) -<<<<<<< Updated upstream -||||||| Stash base -======= // 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) ->>>>>>> Stashed changes +// Add config file option to enable writing monitor data to a file at startup (13) + #define CKernel @@ -2825,7 +2824,13 @@ BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReser MessageBox(NULL,"NODES Table .c and .asm mismatch - fix and rebuild", "BPQ32", MB_OK); return 0; } - + + if (sizeof(struct NR_DEST_ROUTE_ENTRY) != sizeof(struct INP3_DEST_ROUTE_ENTRY)) + { + MessageBox(NULL,"Route Entry mismatch - fix and rebuild", "BPQ32", MB_OK); + return 0; + } + GetSemaphore(&Semaphore, 4); BPQHOSTVECPTR = &BPQHOSTVECTOR[0]; @@ -4223,13 +4228,12 @@ int APIENTRY Restart() hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, TimerInst); - if (hProc) - { - TerminateProcess(hProc, 0); - CloseHandle(hProc); - } + if (hProc) + { + TerminateProcess(hProc, 0); + CloseHandle(hProc); + } - return 0; } diff --git a/Cmd.c b/Cmd.c index 21ced5f..cf3000a 100644 --- a/Cmd.c +++ b/Cmd.c @@ -2737,12 +2737,6 @@ NoPort: // SEE IF CALL TO ANY OF OUR HOST SESSIONS - UNLESS DIGIS SPECIFIED -<<<<<<< Updated upstream -// if (axcalls[7] == 0 && axcalls[9]) -||||||| Stash base - if (axcalls[7] == 0 && axcalls[9] ) -======= ->>>>>>> Stashed changes if (axcalls[7] == 0) { // If this connect is as a result of a command alias, don't check appls or we will loop @@ -2794,60 +2788,7 @@ NoPort: } } -<<<<<<< Updated upstream - // if no digis see if connect to known node. - - // But now could have a single numeric param as a service number (Paula's Netromx) - // cmdCopy is command tail (after call) - - // Make sure field is numeric - - if (cmdCopy[0] != ' ') - { - i = 0; - - while (cmdCopy[i] >= '0' && cmdCopy[i]<= '9') - i++; - - if (i && cmdCopy[i] != ' ') // have an all digit param = probably a service - goto Downlink; - else - { - if (i > 0) // Some digits - { - haveService = 1; - Service = atoi(cmdCopy); - } - } - } - - if (axcalls[7] == 0 || haveService) -||||||| Stash base - // if no digis see if connect to known node. But now could have a single numeric param as a service number (Paula's Netromx) - // cmdCopy is command tail (after call) - - // Make sure field is numeric - - i = 0; - - while (cmdCopy[i] >= '0' && cmdCopy[i]<= '9') - i++; - - if (cmdCopy[i] != ' ') - goto Downlink; - else - { - if (i > 0) // Some digits - { - haveService = 1; - Service = atoi(cmdCopy); - } - } - - if (axcalls[7] == 0 || haveService) -======= if (axcalls[7] == 0) ->>>>>>> Stashed changes { // SEE IF CALL TO ANOTHER NODE @@ -3365,7 +3306,7 @@ char * DoOneNode(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * if (Neighbour) { - double srtt = Route->SRTT/100.0; + double srtt = Route->STT/100.0; len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall); Normcall[len] = 0; @@ -3385,7 +3326,7 @@ int DoViaEntry(struct DEST_LIST * Dest, int n, char * line, int cursor) char Portcall[10]; int len; - if (Dest->NRROUTE[n].ROUT_NEIGHBOUR != 0 && Dest->NRROUTE[n].ROUT_NEIGHBOUR->INP3Node == 0) + if (Dest->NRROUTE[n].ROUT_NEIGHBOUR != 0) { len=ConvFromAX25(Dest->NRROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall); Portcall[len]=0; @@ -3414,7 +3355,7 @@ int DoINP3ViaEntry(struct DEST_LIST * Dest, int n, char * line, int cursor) if (Dest->INP3ROUTE[n].ROUT_NEIGHBOUR != 0) { - srtt = Dest->INP3ROUTE[n].SRTT/100.0; + srtt = Dest->INP3ROUTE[n].STT/100.0; len=ConvFromAX25(Dest->INP3ROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall); Portcall[len]=0; diff --git a/CommonCode.c b/CommonCode.c index 9e8b37a..26dda97 100644 --- a/CommonCode.c +++ b/CommonCode.c @@ -76,6 +76,7 @@ char * FormatMH(PMHSTRUC MH, char Format); void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode); void SendDataToPktMap(); void NETROMTCPResolve(); +VOID FindLostBuffers(); extern BOOL LogAllConnects; extern BOOL M0LTEMap; @@ -565,6 +566,15 @@ VOID * _GetBuff(char * File, int Line) Msg->Linkptr = NULL; Msg->Padding[0] = 0; // Used for modem status info } + else if (QCOUNT != 0) + { + // Queue must be corrupt + + Debugprintf("Fatal - Getbuff returned NULL and Q not empty - exit"); + FindLostBuffers(); + WriteMiniDump(); + Restart(); + } else Debugprintf("Warning - Getbuff returned NULL"); diff --git a/HTTPcode.c b/HTTPcode.c index 385eca2..8d32c88 100644 --- a/HTTPcode.c +++ b/HTTPcode.c @@ -147,9 +147,15 @@ char IndexNoAPRS[] = "PortCallQualityNode CountFrame CountRetriesPercentMaxframeFrackLast HeardQueuedRem Qual"; +"PortCallQualityNode CountFrame CountRetriesPercentMaxframe" +"FrackLast HeardQueuedRem QualSRTTRem SRTT"; + +char RouteLine[] = "%s%d%s%s%d%d%d%d%d%%d%d" +"%02d:%02d%d%d"; + +char RouteLineINP3[] = "%s%d%s%s%d%d%d%d%d%%d%d" +"%02d:%02d%d%d%4.2fs%4.2fs"; -char RouteLine[] = "%s%d%s%s%d%d%d%d%d%%d%d%02d:%02d%d%d"; char xNodeHddr[] = "
" "" "
" @@ -3942,9 +3948,21 @@ doHeader: else Percent = 0; - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RouteLine, Active, Routes->NEIGHBOUR_PORT, Normcall, locked, - Routes->NEIGHBOUR_QUAL, NodeCount, Iframes, Retries, Percent, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK, - Routes->NEIGHBOUR_TIME >> 8, Routes->NEIGHBOUR_TIME & 0xff, Queued, Routes->OtherendsRouteQual); + if (Routes->INP3Node) // INP3 Enabled? + { + double srtt = Routes->SRTT/100.0; + double nsrtt = Routes->NeighbourSRTT/100.0; + + ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RouteLineINP3, Active, Routes->NEIGHBOUR_PORT, Normcall, locked, + Routes->NEIGHBOUR_QUAL, NodeCount, Iframes, Retries, Percent, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK, + Routes->NEIGHBOUR_TIME >> 8, Routes->NEIGHBOUR_TIME & 0xff, Queued, Routes->OtherendsRouteQual, srtt, nsrtt); + } + else + { + ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RouteLine, Active, Routes->NEIGHBOUR_PORT, Normcall, locked, + Routes->NEIGHBOUR_QUAL, NodeCount, Iframes, Retries, Percent, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK, + Routes->NEIGHBOUR_TIME >> 8, Routes->NEIGHBOUR_TIME & 0xff, Queued, Routes->OtherendsRouteQual); + } } Routes+=1; } diff --git a/L3Code.c b/L3Code.c index 0aafe67..84ebbdd 100644 --- a/L3Code.c +++ b/L3Code.c @@ -620,7 +620,7 @@ VOID PROCROUTES(struct DEST_LIST * DEST, struct ROUTE * ROUTE, int Qual) if (DEST->DEST_STATE & 0x80) // BBS ENTRY return; - for (Index = 0; Index < 4; Index++) + for (Index = 0; Index < 3; Index++) { if (DEST->NRROUTE[Index].ROUT_NEIGHBOUR == ROUTE) { @@ -692,6 +692,7 @@ UpdatateThisEntry: // IT DID - THIS IS ALSO CALLED BY CHECKL3TABLES. TRY RESETING // OBS, BUT NOT QUALITY + if ((DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80) == 0) DEST->NRROUTE[Index].ROUT_OBSCOUNT = OBSINIT; // SET OBSOLESCENCE COUNT @@ -1432,7 +1433,8 @@ VOID L3TRYNEXTDEST(struct ROUTE * ROUTE) { // not Locked - DEST->NRROUTE[ActiveRoute].ROUT_OBSCOUNT--; + if (ActiveRoute < 3) // Not INP3 Route + DEST->NRROUTE[ActiveRoute].ROUT_OBSCOUNT--; // if ROUTE HAS EXPIRED - WE SHOULD CLEAR IT, AND MOVE OTHERS (IF ANY) UP } @@ -1563,7 +1565,10 @@ struct DEST_LIST * CHECKL3TABLES(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * Msg if (DEST->DEST_ROUTE) { int Index = DEST->DEST_ROUTE -1; - + + if (Index > 2) // INP3 Route + return DEST; + if (DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80) // Locked: return DEST; @@ -1592,6 +1597,9 @@ VOID REFRESHROUTE(TRANSPORTENTRY * Session) Index--; + if (Index > 2) // INP3 Route + return; + if (DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80) return; // Locked diff --git a/LinBPQ.c b/LinBPQ.c index 03af5a4..08dae7c 100644 --- a/LinBPQ.c +++ b/LinBPQ.c @@ -86,14 +86,6 @@ void SendBBSDataToPktMap(); void CloseAllLinks(); void hookNodeClosing(char * Reason); void NETROMTCPResolve(); -<<<<<<< Updated upstream - -extern uint64_t INP3timeLoadedMS; -||||||| Stash base - -extern uint64_t INP3timeLoadedMS; -======= ->>>>>>> Stashed changes BOOL IncludesMail = FALSE; BOOL IncludesChat = FALSE; @@ -874,7 +866,6 @@ int main(int argc, char * argv[]) srand(time(NULL)); - // look for optarg format parameters { diff --git a/NETROMTCP.c b/NETROMTCP.c index e1d9fec..69a91c0 100644 --- a/NETROMTCP.c +++ b/NETROMTCP.c @@ -110,1043 +110,6 @@ struct ConnectionInfo * AllocateNRTCPRec() sockptr->SocketActive = TRUE; sockptr->ConnectTime = sockptr->LastSendTime = time(NULL); -<<<<<<< Updated upstream - Debugprintf("NRTCP Allocated %d", i); - return sockptr; - } - } - return 0; -} - -void checkNRTCPSockets(int portNo) -{ - SOCKET sock; - int Active = 0; - SOCKET maxsock; - int retval; - int i; - - struct timeval timeout; - fd_set readfd, writefd, exceptfd; - - struct ConnectionInfo * sockptr; - - timeout.tv_sec = 0; - timeout.tv_usec = 0; // poll - - maxsock = 0; - - FD_ZERO(&readfd); - FD_ZERO(&writefd); - FD_ZERO(&exceptfd); - - for (i = 0; i < 255; i++) - { - if (NRTCPInfo[i] == 0) - break; // only as many as have been used - - sockptr = NRTCPInfo[i]->sockptr; - - if (sockptr->SocketActive == 0) - continue; - - if (sockptr->Connecting) - { - // look for complete or failed - - FD_SET(sockptr->socket, &writefd); - FD_SET(sockptr->socket, &exceptfd); - } - else - { - FD_SET(sockptr->socket, &readfd); - FD_SET(sockptr->socket, &exceptfd); - } - - Active++; - - if (sockptr->socket > maxsock) - maxsock = sockptr->socket; - } - - if (Active) - { - retval = select((int)maxsock + 1, &readfd, &writefd, &exceptfd, &timeout); - - if (retval == -1) - { - perror("data select"); - Debugprintf("NRTCP Select Error %d Active %d", WSAGetLastError(), Active); - } - else - { - if (retval) - { - // see who has data - - for (i = 0; i < 255; i++) - { - if (NRTCPInfo[i] == 0) - break; - - sockptr = NRTCPInfo[i]->sockptr; - - if (sockptr->SocketActive == 0) - continue; - - sock = sockptr->socket; - - if (FD_ISSET(sock, &writefd)) - NETROMConnected(sockptr, sock, NRTCPInfo[i]); - - if (FD_ISSET(sock, &readfd)) - DataSocket_ReadNETROM(sockptr, sock, NRTCPInfo[i], portNo); - - if (FD_ISSET(sock, &exceptfd)) - NETROMConnectionLost(sockptr); - } - } - } - } -} - -int NETROMOpenConnection(struct ROUTE * Route) -{ - struct NRTCPSTRUCT * Info; - struct ConnectionInfo * sockptr; - char farCall[10]; - - farCall[ConvFromAX25(Route->NEIGHBOUR_CALL, farCall)] = 0; - - Debugprintf("Opening NRTCP Connection to %s", farCall); - - if (Route->TCPSession) - { - // SESSION ALREADY EXISTS - - sockptr = Route->TCPSession->sockptr; - - if (sockptr->Connected || sockptr->Connecting) - return TRUE; - - // previous connect failed - } - else - { - sockptr = AllocateNRTCPRec(); - - if (sockptr == NULL) - return 0; - - 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); - } - - return NETROMTCPConnect(Route, sockptr); - -} - -void NETROMTCPResolve() -{ - struct ROUTE * Route = NEIGHBOURS; - int n = MAXNEIGHBOURS; - struct addrinfo hints, *res = 0; - char PortString[20]; - int err; - - while (n--) - { - if (Route->TCPAddress) - { - // try to resolve host - - sprintf(PortString, "%d", Route->TCPPort); - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever - hints.ai_socktype = SOCK_STREAM; - - getaddrinfo(Route->TCPHost, PortString, &hints, &res); - - err = WSAGetLastError(); - - if (res) - { - Route->TCPAddress->ai_family = res->ai_family; - Route->TCPAddress->ai_socktype = res->ai_socktype; - Route->TCPAddress->ai_protocol = res->ai_protocol; - Route->TCPAddress->ai_addrlen = res->ai_addrlen; - memcpy(Route->TCPAddress->ai_addr, res->ai_addr, sizeof(struct sockaddr)); - freeaddrinfo(res); - } - } - - Route++; - } -} - -int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) -{ - int err; - u_long param=1; - BOOL bcopt=TRUE; - SOCKET sock; - struct sockaddr_in sinx; - int addrlen=sizeof(sinx); - char PortString[20]; - struct addrinfo * res = Route->TCPAddress; - int Port = Route->TCPPort; - - sprintf(PortString, "%d", Port); - - // get host info, make socket, and connect it - - if (res->ai_family == 0) - { -// err = WSAGetLastError(); -// Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err); - return FALSE; // Resolve failed - } - - sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - - if (sock == INVALID_SOCKET) - { - Debugprintf, ("Netrom over TCP Create Socket Failed"); - return FALSE; - } - - ioctl(sock, FIONBIO, ¶m); - - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4); - - - if (connect(sock, res->ai_addr, (int)res->ai_addrlen) == 0) - { - // - // Connected successful - // - - sockptr->Connected = TRUE; - return TRUE; - } - else - { - err=WSAGetLastError(); - - if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK - { - // Connect in Progress - - sockptr->Connecting = TRUE; - return TRUE; - } - else - { - // Connect failed - - closesocket(sockptr->socket); - - return FALSE; - } - } - - return FALSE; -} - - - - -void NETROMConnectionAccepted(struct ConnectionInfo * sockptr) -{ - // Not sure we can do much here until first message arrives with callsign - - sockptr->Connected = TRUE; - Debugprintf("NRTCP Connection Accepted"); -} - -void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info) -{ - // Connection Complete - - Debugprintf("NRTCP Connected"); - - sockptr->Connecting = FALSE; - sockptr->Connected = TRUE; - - Info->LINK->L2STATE = 5; - - if (Info->Route->INP3Node) - SendRTTMsg(Info->Route); -} - -int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo) -{ - int len=0, maxlen; - struct NRTCPMsg * Msg; - struct _L3MESSAGEBUFFER * L3Msg; - struct ROUTE * Route; - UCHAR axCall[7]; - PMESSAGE Buffer; - - ioctl(sock,FIONREAD,&len); - - maxlen = InputBufferLen - sockptr->InputLen; - - if (len > maxlen) len = maxlen; - - len = recv(sock, &sockptr->InputBuffer[sockptr->InputLen], len, 0); - - if (len == SOCKET_ERROR || len == 0) - { - // Failed or closed - clear connection - - NETROMConnectionLost(sockptr); - return 0; - } - - sockptr->InputLen += len; - - // Process data - -checkLen: - - // See if we have a whole packet - - Msg = (struct NRTCPMsg *)&sockptr->InputBuffer[0]; - - if (Msg->Length > sockptr->InputLen) // if not got whole frame wait - return 0; - - if (Info->Call[0] == 0) - { - // first packet - do we need to do anything? - - // 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); - - if (FindNeighbour(axCall, portNo, &Route)) - { - Info->Route = Route; - Route->NEIGHBOUR_LINK = Info->LINK; - Route->NEIGHBOUR_PORT = portNo; - Info->LINK->NEIGHBOUR = Route; - Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(portNo); - Route->TCPSession = Info; - Info->LINK->L2STATE = 5; - - if (Info->Route->INP3Node) - SendRTTMsg(Info->Route); - } - else - { - Debugprintf("Neighbour %s port %d not found - closing connection", Msg->Call, portNo); - closesocket(sockptr->socket); - sockptr->SocketActive = FALSE; - memset(sockptr, 0, sizeof(struct ConnectionInfo)); - Info->Call[0] = 0; - return 0; - } - } - - - if (memcmp(Info->Call, Msg->Call, 10) != 0) - { - Debugprintf("Mismatch"); - // something wrong - maybe connection reused - } - - // Format as if come from an ax.25 link - - L3Msg = GetBuff(); - - if (L3Msg == 0) - goto seeifMore; - - L3Msg->LENGTH = (Msg->Length - 12) + MSGHDDRLEN; - L3Msg->Next = 0; - L3Msg->Port = portNo; - L3Msg->L3PID = NETROM_PID; - memcpy(&L3Msg->L3SRCE, Msg->Packet, Msg->Length - 13); - - // Create a dummy L2 message so we can trace it - - Buffer = GetBuff(); - - if (Buffer) - { - Buffer->CHAIN = 0; - Buffer->CTL = 0; - Buffer->PORT = portNo; - - ConvToAX25(Info->Call, Buffer->ORIGIN); - ConvToAX25(MYNETROMCALL, Buffer->DEST); - - memcpy(Buffer->L2DATA, &L3Msg->L3SRCE[0], Msg->Length - 13); - Buffer->ORIGIN[6] |= 1; // Set end of calls - Buffer->PID = NETROM_PID; - Buffer->LENGTH = Msg->Length + 10; - time(&Buffer->Timestamp); - - BPQTRACE(Buffer, FALSE); - - if(NodeAPISocket) - NetromTCPTrace(Buffer, "rcvd"); - - ReleaseBuffer(Buffer); - } - - NETROMMSG(Info->LINK, L3Msg); - -seeifMore: - - sockptr->InputLen -= Msg->Length; - - if (sockptr->InputLen > 0) - { - memmove(sockptr->InputBuffer, &sockptr->InputBuffer[Msg->Length], sockptr->InputLen); - goto checkLen; - } - - return 0; -} - -VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) -{ - struct NRTCPMsg Msg; - unsigned char * Data = (unsigned char *)&Frame->L3SRCE[0]; - int DataLen = Frame->LENGTH - (MSGHDDRLEN + 1); // Not including PID - int Ret; - PMESSAGE Buffer; - - Msg.Length = DataLen + 13; // include PID - memcpy(Msg.Call, MYNETROMCALL, 10); - Msg.PID = NETROM_PID; - memcpy(Msg.Packet, Data, DataLen); - - if (Route->TCPSession == 0) - return; - - Ret = send(Route->TCPSession->sockptr->socket, (char *)&Msg, DataLen + 13, 0); - - // Create a dummy L2 message so we can trace it - - Buffer = GetBuff(); - - if (Buffer) - { - Buffer->CHAIN = 0; - Buffer->CTL = 0; - Buffer->PORT = Route->NEIGHBOUR_PORT; - - ConvToAX25(Route->TCPSession->Call, Buffer->DEST); - ConvToAX25(MYNETROMCALL, Buffer->ORIGIN); - - memcpy(Buffer->L2DATA, &Frame->L3SRCE[0], DataLen); - Buffer->ORIGIN[6] |= 1; // Set end of calls - Buffer->PID = NETROM_PID; - Buffer->LENGTH = DataLen + 15 + MSGHDDRLEN; - time(&Buffer->Timestamp); - - if(NodeAPISocket) - NetromTCPTrace(Buffer, "sent"); - - Buffer->PORT = Route->NEIGHBOUR_PORT | 128; // TX Flag - BPQTRACE(Buffer, FALSE); - - - ReleaseBuffer(Buffer); - } - -} - - -void NETROMConnectionLost(struct ConnectionInfo * sockptr) -{ - struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number]; - struct ROUTE * Route; - - closesocket(sockptr->socket); - - // If there is an attached route (there should be) clear all connections - - if (Info) - { - Route = Info->Route; - - if (sockptr->Connected) - L3LINKCLOSED(Info->LINK, LINKLOST); - - if (sockptr->Connecting) - L3LINKCLOSED(Info->LINK, SETUPFAILED); - - if (Route) - Route->TCPSession = 0; - - Info->Call[0] = 0; -||||||| Stash base -/* -Copyright 2001-2022 John Wiseman G8BPQ - -This file is part of LinBPQ/BPQ32. - -LinBPQ/BPQ32 is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -LinBPQ/BPQ32 is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses -*/ - -/* -Netrom over TCP Support - -This is intended for operation over radio links with an IP interface, eg New Packet Radio or possibly microwave links - -To simplify interface to the rest of the oode dummy LINK and PORT records are created - -Packet Format is Length (2 byte little endian) Call (10 bytes ASCII) NETROM L3/4 Packet, starting 0xcf (to detect framing errors). - -A TCP message can contain multiple packets and/or partial packets - -It uses the Telnet Server, with port defined in NETROMPORT - -ROUTE definitions have an extra field, the TCP Port Number - -*/ - -//#pragma data_seg("_BPQDATA") - - -#define _CRT_SECURE_NO_DEPRECATE - -#include "time.h" -#include "stdio.h" -#include -//#include "vmm.h" - -#include "cheaders.h" -#include "asmstrucs.h" -#include "telnetserver.h" - -#define NETROM_PID 0xCF - -void NETROMConnectionLost(struct ConnectionInfo * sockptr); -int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo); -int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr); -void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info); -VOID SendRTTMsg(struct ROUTE * Route); -BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE); -VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG); -int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS); -VOID L3LINKCLOSED(struct _LINKTABLE * LINK, int Reason); - -struct NRTCPMsg -{ - short Length; - char Call[10]; - unsigned char PID; - char Packet[1024]; -}; - -struct NRTCPSTRUCT -{ - struct ConnectionInfo * sockptr; - struct _LINKTABLE * LINK; // Dummy Link Record for this ROUTE - struct ROUTE * Route; // May need backlink - char Call[10]; -}; - -struct NRTCPSTRUCT * NRTCPInfo[256] = {0}; - -// Do we want to use normal TCP server connections, which are limited, or our own. Let's try our own for now - -struct ConnectionInfo * AllocateNRTCPRec() -{ - struct ConnectionInfo * sockptr = 0; - struct NRTCPSTRUCT * Info; - int i; - - for (i = 0; i < 255; i++) - { - if (NRTCPInfo[i] == 0) - { - // only allocate as many as needed - - 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]; - - sockptr = Info->sockptr; - - if (sockptr->SocketActive == FALSE) - { - sockptr->SocketActive = TRUE; - sockptr->ConnectTime = sockptr->LastSendTime = time(NULL); - - Debugprintf("NRTCP Allocated %d", i); - return sockptr; - } - } - return 0; -} - -void checkNRTCPSockets(int portNo) -{ - SOCKET sock; - int Active = 0; - SOCKET maxsock; - int retval; - int i; - - struct timeval timeout; - fd_set readfd, writefd, exceptfd; - - struct ConnectionInfo * sockptr; - - timeout.tv_sec = 0; - timeout.tv_usec = 0; // poll - - maxsock = 0; - - FD_ZERO(&readfd); - FD_ZERO(&writefd); - FD_ZERO(&exceptfd); - - for (i = 0; i < 255; i++) - { - if (NRTCPInfo[i] == 0) - break; // only as many as have been used - - sockptr = NRTCPInfo[i]->sockptr; - - if (sockptr->SocketActive == 0) - continue; - - if (sockptr->Connecting) - { - // look for complete or failed - - FD_SET(sockptr->socket, &writefd); - FD_SET(sockptr->socket, &exceptfd); - } - else - { - FD_SET(sockptr->socket, &readfd); - FD_SET(sockptr->socket, &exceptfd); - } - - Active++; - - if (sockptr->socket > maxsock) - maxsock = sockptr->socket; - } - - if (Active) - { - retval = select((int)maxsock + 1, &readfd, &writefd, &exceptfd, &timeout); - - if (retval == -1) - { - perror("data select"); - Debugprintf("NRTCP Select Error %d Active %d", WSAGetLastError(), Active); - } - else - { - if (retval) - { - // see who has data - - for (i = 0; i < 255; i++) - { - if (NRTCPInfo[i] == 0) - break; - - sockptr = NRTCPInfo[i]->sockptr; - - if (sockptr->SocketActive == 0) - continue; - - sock = sockptr->socket; - - if (FD_ISSET(sock, &writefd)) - NETROMConnected(sockptr, sock, NRTCPInfo[i]); - - if (FD_ISSET(sock, &readfd)) - DataSocket_ReadNETROM(sockptr, sock, NRTCPInfo[i], portNo); - - if (FD_ISSET(sock, &exceptfd)) - NETROMConnectionLost(sockptr); - } - } - } - } -} - -int NETROMOpenConnection(struct ROUTE * Route) -{ - struct NRTCPSTRUCT * Info; - struct ConnectionInfo * sockptr; - - Debugprintf("Opening NRTCP Connection"); - - if (Route->TCPSession) - { - // SESSION ALREADY EXISTS - - sockptr = Route->TCPSession->sockptr; - - if (sockptr->Connected || sockptr->Connecting) - return TRUE; - - // previous connect failed - } - else - { - sockptr = AllocateNRTCPRec(); - - if (sockptr == NULL) - return 0; - - Info = Route->TCPSession = NRTCPInfo[sockptr->Number]; - memcpy(Info->Call, MYNETROMCALL, 10); - Route->NEIGHBOUR_LINK = Info->LINK; - - Info->Route = Route; - Info->LINK->NEIGHBOUR = Route; - Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); - } - - return NETROMTCPConnect(Route, sockptr); - -} - -int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr) -{ - int err; - u_long param=1; - BOOL bcopt=TRUE; - SOCKET sock; - struct sockaddr_in sinx; - int addrlen=sizeof(sinx); - char PortString[20]; - struct addrinfo hints, *res = 0, *saveres; - int Port = Route->TCPPort; - - sprintf(PortString, "%d", Port); - - // get host info, make socket, and connect it - - memset(&hints, 0, sizeof hints); - - hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever - - hints.ai_socktype = SOCK_STREAM; - getaddrinfo(Route->TCPHost, PortString, &hints, &res); - - if (!res) - { - err = WSAGetLastError(); - Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err); - return FALSE; // Resolve failed - } - - // Step thorough the list of hosts - - saveres = res; // Save for free - - sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - - - if (sock == INVALID_SOCKET) - { - Debugprintf, ("Netrom over TCP Create Socket Failed"); - return FALSE; - } - - ioctl(sock, FIONBIO, ¶m); - - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4); - - - if (connect(sock, res->ai_addr, (int)res->ai_addrlen) == 0) - { - // - // Connected successful - // - - sockptr->Connected = TRUE; - freeaddrinfo(saveres); - - return TRUE; - } - else - { - freeaddrinfo(saveres); - - err=WSAGetLastError(); - - if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK - { - // Connect in Progress - - sockptr->Connecting = TRUE; - return TRUE; - } - else - { - // Connect failed - - closesocket(sockptr->socket); - - return FALSE; - } - } - - return FALSE; -} - - - - -void NETROMConnectionAccepted(struct ConnectionInfo * sockptr) -{ - // Not sure we can do much here until first message arrives with callsign - - sockptr->Connected = TRUE; - Debugprintf("NRTCP Connection Accepted"); -} - -void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info) -{ - // Connection Complete - - Debugprintf("NRTCP Connected"); - - sockptr->Connecting = FALSE; - sockptr->Connected = TRUE; - - Info->LINK->L2STATE = 5; - - if (Info->Route->INP3Node) - SendRTTMsg(Info->Route); -} - -int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo) -{ - int len=0, maxlen; - struct NRTCPMsg * Msg; - struct _L3MESSAGEBUFFER * L3Msg; - struct ROUTE * Route; - UCHAR axCall[7]; - PMESSAGE Buffer; - - ioctl(sock,FIONREAD,&len); - - maxlen = InputBufferLen - sockptr->InputLen; - - if (len > maxlen) len = maxlen; - - len = recv(sock, &sockptr->InputBuffer[sockptr->InputLen], len, 0); - - if (len == SOCKET_ERROR || len == 0) - { - // Failed or closed - clear connection - - NETROMConnectionLost(sockptr); - return 0; - } - - sockptr->InputLen += len; - - // Process data - -checkLen: - - // See if we have a whole packet - - Msg = (struct NRTCPMsg *)&sockptr->InputBuffer[0]; - - if (Msg->Length > sockptr->InputLen) // if not got whole frame wait - return 0; - - if (Info->Call[0] == 0) - { - // first packet - do we need to do anything? - - // This must be an incoming connection as Call is set before calling so need to find route record and set things up. - - memcpy(Info->Call, Msg->Call, 10); - - ConvToAX25(Msg->Call, axCall); - - if (FindNeighbour(axCall, portNo, &Route)) - { - Info->Route = Route; - Route->NEIGHBOUR_LINK = Info->LINK; - Info->LINK->NEIGHBOUR = Route; - Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); - Route->TCPSession = Info; - Info->LINK->L2STATE = 5; - - if (Info->Route->INP3Node) - SendRTTMsg(Info->Route); - } - else - goto seeifMore; // Should we kill connection? - } - - - if (memcmp(Info->Call, Msg->Call, 10) != 0) - { - // something wrong - maybe connection reused - } - - // Format as if come from an ax.25 link - - L3Msg = GetBuff(); - - if (L3Msg == 0) - goto seeifMore; - - L3Msg->LENGTH = (Msg->Length - 12) + MSGHDDRLEN; - L3Msg->Next = 0; - L3Msg->Port = 0; - L3Msg->L3PID = NETROM_PID; - memcpy(&L3Msg->L3SRCE, Msg->Packet, Msg->Length - 13); - - // Create a dummy L2 message so we can trace it - - Buffer = GetBuff(); - - if (Buffer) - { - Buffer->CHAIN = 0; - Buffer->CTL = 0; - Buffer->PORT = portNo; - - ConvToAX25(Info->Call, Buffer->ORIGIN); - ConvToAX25(MYNETROMCALL, Buffer->DEST); - - memcpy(Buffer->L2DATA, &L3Msg->L3SRCE[0], Msg->Length - 13); - Buffer->ORIGIN[6] |= 1; // Set end of calls - Buffer->PID = NETROM_PID; - Buffer->LENGTH = Msg->Length + 10; - time(&Buffer->Timestamp); - - BPQTRACE(Buffer, FALSE); - ReleaseBuffer(Buffer); - } - - NETROMMSG(Info->LINK, L3Msg); - -seeifMore: - - sockptr->InputLen -= Msg->Length; - - if (sockptr->InputLen > 0) - { - memmove(sockptr->InputBuffer, &sockptr->InputBuffer[Msg->Length], sockptr->InputLen); - goto checkLen; - } - - return 0; -} - -VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame) -{ - struct NRTCPMsg Msg; - unsigned char * Data = (unsigned char *)&Frame->L3SRCE[0]; - int DataLen = Frame->LENGTH - (MSGHDDRLEN + 1); // Not including PID - int Ret; - PMESSAGE Buffer; - - Msg.Length = DataLen + 13; // include PID - memcpy(Msg.Call, MYNETROMCALL, 10); - Msg.PID = NETROM_PID; - memcpy(Msg.Packet, Data, DataLen); - - if (Route->TCPSession == 0) - return; - - Ret = send(Route->TCPSession->sockptr->socket, (char *)&Msg, DataLen + 13, 0); - - // Create a dummy L2 message so we can trace it - - Buffer = GetBuff(); - - if (Buffer) - { - Buffer->CHAIN = 0; - Buffer->CTL = 0; - Buffer->PORT = Route->NEIGHBOUR_PORT | 128; // TX Flag - - ConvToAX25(Route->TCPSession->Call, Buffer->DEST); - ConvToAX25(MYNETROMCALL, Buffer->ORIGIN); - - memcpy(Buffer->L2DATA, &Frame->L3SRCE[0], DataLen); - Buffer->ORIGIN[6] |= 1; // Set end of calls - Buffer->PID = NETROM_PID; - Buffer->LENGTH = DataLen + 15 + MSGHDDRLEN; - time(&Buffer->Timestamp); - - BPQTRACE(Buffer, FALSE); - ReleaseBuffer(Buffer); - } - -} - - -void NETROMConnectionLost(struct ConnectionInfo * sockptr) -{ - struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number]; - struct ROUTE * Route; - - closesocket(sockptr->socket); - - // If there is an attached route (there should be) clear all connections - - if (Info) - { - Route = Info->Route; - - if (sockptr->Connected) - L3LINKCLOSED(Info->LINK, LINKLOST); - - if (sockptr->Connecting) - L3LINKCLOSED(Info->LINK, SETUPFAILED); - - Route->TCPSession = 0; - - Info->Call[0] = 0; - } - - sockptr->SocketActive = FALSE; - - memset(sockptr, 0, sizeof(struct ConnectionInfo)); -} - -======= // Debugprintf("NRTCP Allocated %d", i); return sockptr; } @@ -1281,6 +244,7 @@ int NETROMOpenConnection(struct ROUTE * Route) Info->Route = Route; Info->LINK->NEIGHBOUR = Route; Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT); + memcpy(Route->NEIGHBOUR_LINK->LINKCALL, Route->NEIGHBOUR_CALL, 7); } return NETROMTCPConnect(Route, sockptr); @@ -1480,7 +444,8 @@ checkLen: Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(portNo); Route->TCPSession = Info; Info->LINK->L2STATE = 5; - + memcpy(Route->NEIGHBOUR_LINK->LINKCALL, axCall, 7); + if (Info->Route->INP3Node) SendRTTMsg(Info->Route); } @@ -1636,7 +601,6 @@ void NETROMConnectionLost(struct ConnectionInfo * sockptr) Info->Call[0] = 0; Info->LINK->L2STATE = 0; ->>>>>>> Stashed changes } sockptr->SocketActive = FALSE; diff --git a/TelnetV6.c b/TelnetV6.c index 590186c..332e843 100644 --- a/TelnetV6.c +++ b/TelnetV6.c @@ -56,6 +56,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses extern UCHAR LogDirectory[]; +extern int MONTOFILEFLAG; static char ClassName[]="TELNETSERVER"; static char WindowTitle[] = "Telnet Server"; @@ -177,77 +178,74 @@ void NETROMConnectionLost(struct ConnectionInfo * sockptr); void NETROMConnectionAccepted(struct ConnectionInfo * sockptr); struct ConnectionInfo * AllocateNRTCPRec(); -static int LogAge = 13; +static int LogAge = 10; - -#ifdef WIN32 - -int DeleteLogFile(char * Log); +int DeleteLogFile(char * Log, int KeepDays); void DeleteTelnetLogFiles() { - DeleteLogFile("/logs/Telnet*.log"); - DeleteLogFile("/logs/CMSAccess_*.log"); - DeleteLogFile("/logs/ConnectLog_*.log"); + DeleteLogFile("Telnet", 14); + DeleteLogFile("CMSAccess_", 14); + DeleteLogFile("ConnectLog_",14); + DeleteLogFile("APRS_", 14); + DeleteLogFile("PacketLog_",MONTOFILEFLAG); } -int DeleteLogFile(char * Log) -{ +#ifdef WIN32 - +int DeleteLogFile(char * Log, int KeepDays) +{ WIN32_FIND_DATA ffd; - char szDir[MAX_PATH]; - char File[MAX_PATH]; - HANDLE hFind = INVALID_HANDLE_VALUE; - DWORD dwError=0; - LARGE_INTEGER ft; - time_t now = time(NULL); - int Age; + char szDir[MAX_PATH]; + char File[MAX_PATH]; + HANDLE hFind = INVALID_HANDLE_VALUE; + DWORD dwError=0; + LARGE_INTEGER ft; + time_t now = time(NULL); + int Age; - // Prepare string for use with FindFile functions. First, copy the - // string to a buffer, then append '\*' to the directory name. - strcpy(szDir, GetLogDirectory()); - strcat(szDir, Log); + strcpy(szDir, GetLogDirectory()); + strcat(szDir, "/Logs/"); + strcat(szDir, Log); + strcat(szDir, "*.log"); - // Find the first file in the directory. + // Find the first file in the directory. - hFind = FindFirstFile(szDir, &ffd); + hFind = FindFirstFile(szDir, &ffd); - if (INVALID_HANDLE_VALUE == hFind) - return dwError; + if (INVALID_HANDLE_VALUE == hFind) + return dwError; - // List all the files in the directory with some info about them. + do + { + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + OutputDebugString(ffd.cFileName); + } + else + { + ft.HighPart = ffd.ftCreationTime.dwHighDateTime; + ft.LowPart = ffd.ftCreationTime.dwLowDateTime; - do - { - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - OutputDebugString(ffd.cFileName); - } - else - { - ft.HighPart = ffd.ftCreationTime.dwHighDateTime; - ft.LowPart = ffd.ftCreationTime.dwLowDateTime; + ft.QuadPart -= 116444736000000000; + ft.QuadPart /= 10000000; - ft.QuadPart -= 116444736000000000; - ft.QuadPart /= 10000000; + Age = (int)((now - ft.LowPart) / 86400); - Age = (int)((now - ft.LowPart) / 86400); - - if (Age > LogAge) + if (Age > KeepDays) { sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0); Debugprintf("Deleting %s", File); DeleteFile(File); } - } - } - while (FindNextFile(hFind, &ffd) != 0); + } + } + while (FindNextFile(hFind, &ffd) != 0); - FindClose(hFind); - return dwError; + FindClose(hFind); + return dwError; } #else @@ -256,22 +254,19 @@ int DeleteLogFile(char * Log) int TelFilter(const struct dirent * dir) { - return (memcmp(dir->d_name, "CMSAccess", 9) == 0 - || memcmp(dir->d_name, "Telnet", 6) == 0 - || memcmp(dir->d_name, "ConnectLog", 6) == 0) - && strstr(dir->d_name, ".log"); + return strstr(dir->d_name, ".log") != 0; } -int DeleteTelnetLogFiles() +int DeleteLogFile(char * Log, int KeepDays) { struct dirent **namelist; - int n; + int n; struct stat STAT; time_t now = time(NULL); int Age = 0, res; char FN[256]; - - n = scandir("logs", &namelist, TelFilter, alphasort); + + n = scandir("logs", &namelist, TelFilter, alphasort); if (n < 0) perror("scandir"); @@ -279,21 +274,25 @@ int DeleteTelnetLogFiles() { while(n--) { - sprintf(FN, "logs/%s", namelist[n]->d_name); - if (stat(FN, &STAT) == 0) + if (memcmp(namelist[n]->d_name, Log, strlen(Log)) == 0) { - Age = (now - STAT.st_mtime) / 86400; - - if (Age > LogAge) + sprintf(FN, "logs/%s", namelist[n]->d_name); + + if (stat(FN, &STAT) == 0) { - Debugprintf("Deleting %s\n", FN); - unlink(FN); + Age = (now - STAT.st_mtime) / 86400; + + if (Age > KeepDays) + { + Debugprintf("Deleting %s", FN); + unlink(FN); + } } } free(namelist[n]); } free(namelist); - } + } return 0; } #endif @@ -320,7 +319,7 @@ void BuffertoNode(struct ConnectionInfo * sockptr, char * MsgPtr, int InputLen) sockptr->InputLen = 0; return; - } +} BOOL SendAndCheck(struct ConnectionInfo * sockptr, unsigned char * MsgPtr, int len, int flags) { @@ -331,7 +330,7 @@ BOOL SendAndCheck(struct ConnectionInfo * sockptr, unsigned char * MsgPtr, int l return TRUE; // OK err = WSAGetLastError(); - + Debugprintf("TCP Send Failed - Sent %d should be %d err %d - requeue data", sent, len, err); if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK @@ -1194,6 +1193,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) TNC = TNCInfo[n]; TNC->Port = n; + TNC->PortRecord = PortRecord; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_TELNET; TNC->RIG = &TNC->DummyRig; // Not using Rig control, so use Dummy @@ -1445,7 +1445,7 @@ void * TelnetExtInit(EXTPORTDATA * PortEntry) } */ - DeleteTelnetLogFiles(); + DeleteTelnetLogFiles(LogAge); initUTF8(); diff --git a/Versions.h b/Versions.h index 79b7aea..a6c8834 100644 --- a/Versions.h +++ b/Versions.h @@ -10,16 +10,8 @@ #endif -<<<<<<< Updated upstream -#define KVers 6,0,25,11 -#define KVerstring "6.0.25.11\0" -||||||| Stash base -#define KVers 6,0,25,8 -#define KVerstring "6.0.25.8\0" -======= -#define KVers 6,0,25,12 -#define KVerstring "6.0.25.12\0" ->>>>>>> Stashed changes +#define KVers 6,0,25,13 +#define KVerstring "6.0.25.13\0" #ifdef CKernel diff --git a/asmstrucs.h b/asmstrucs.h index 439b6f9..97e4a4d 100644 --- a/asmstrucs.h +++ b/asmstrucs.h @@ -489,9 +489,11 @@ typedef struct NR_DEST_ROUTE_ENTRY typedef struct INP3_DEST_ROUTE_ENTRY { struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH - USHORT LastRTT; // Last Value Reported - USHORT RTT; // Current - USHORT SRTT; // Smoothed RTT + 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 + + 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) UCHAR Hops; } *PDEST_ROUTE_ENTRY; diff --git a/cMain.c b/cMain.c index d592ecb..2773a95 100644 --- a/cMain.c +++ b/cMain.c @@ -882,11 +882,12 @@ BOOL Start() PREFERINP3ROUTES = cfg->C_PREFERINP3ROUTES; - if (cfg->C_DEBUGINP3) - DEBUGINP3 = 0; + DEBUGINP3 = cfg->C_DEBUGINP3; EnableOARCAPI = cfg->C_OARCAPI; + MONTOFILEFLAG = cfg->C_MONTOFILE; + if (cfg->C_OnlyVer2point0) SUPPORT2point2 = 0; @@ -2398,7 +2399,7 @@ L2Packet: if (MQTT && PORT->PROTOCOL == 0) MQTTKISSRX(Buffer); - if(NodeAPISocket &&PORT->PROTOCOL == 0) + if(NodeAPISocket && PORT->PROTOCOL == 0) APIL2Trace(Message, "rcvd"); // Bridge if requested diff --git a/config.c b/config.c index b41e0e8..b883ad5 100644 --- a/config.c +++ b/config.c @@ -310,7 +310,7 @@ 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" +"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0", "DEBUGINP3", "ENABLEOARCAPI", "MONTOFILE" }; /* parameter keywords */ static void * offset[] = @@ -334,7 +334,7 @@ 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}; /* 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}; /* offset for corresponding data in config file */ static int routine[] = { @@ -357,7 +357,7 @@ 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}; // Routine to process param +1, 1, 1, 1, 1, 1}; // Routine to process param int PARAMLIM = sizeof(routine)/sizeof(int); //int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int); @@ -560,7 +560,6 @@ BOOL ProcessConfig() heading = 1; } - paramok[6]=1; /* dont need BUFFERS */ paramok[8]=1; /* dont need TRANSDELAY */ paramok[13]=1; // NodeAlias @@ -610,35 +609,35 @@ BOOL ProcessConfig() paramok[45+i]=1; /* or APPLCALLS, APPLALIASS APPLQUAL */ paramok[69]=1; // BText optional - paramok[70]=1; // IPGateway optional + paramok[70]=1; // NETROMCALL optional paramok[71]=1; // C_IS_CHAT optional - paramok[72]=1; // MAXRTT optional - paramok[73]=1; // MAXHOPS optional - paramok[74]=1; // LogL4Connects optional - paramok[75]=1; // LogAllConnects optional - paramok[76]=1; // SAVEMH optional - paramok[77]=1; // ENABLEADIFLOG optional - paramok[78]=1; // EnableEvents optional - paramok[79]=1; // SaveAPRSMsgs optional + paramok[73]=1; // MAXTT optional + paramok[74]=1; // MAXHOPS optional + paramok[75]=1; // LogL4Connects optional + paramok[76]=1; // LogAllConnects optional + paramok[77]=1; // SAVEMH optional + 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; // MQTT Params paramok[82]=1; // MQTT Params paramok[83]=1; // MQTT Params paramok[84]=1; // MQTT Params paramok[85]=1; // MQTT Params - paramok[86]=1; // L4Compress - paramok[87]=1; // L4Compress Maxframe - paramok[88]=1; // L4Compress Paclen - paramok[89]=1; // L2Compress - paramok[90]=1; // L2Compress Maxframe - paramok[91]=1; // L2Compress Paclen - paramok[92]=1; // PREFERINP3ROUTES - paramok[93]=1; // ONLYVer2point0 - paramok[94]=1; // DEBUGINP3 - paramok[95]=1; // EnableOARCAPI - paramok[96]=1; // OARCAPI + paramok[86]=1; // MQTT Params + paramok[87]=1; // L4Compress + paramok[88]=1; // L4Compress Maxframe + paramok[89]=1; // L4Compress Paclen + paramok[90]=1; // L2Compress + paramok[91]=1; // L2Compress Maxframe + paramok[92]=1; // L2Compress Paclen + paramok[93]=1; // PREFERINP3ROUTES + paramok[94]=1; // ONLYVer2point0 + paramok[95]=1; // DEBUGINP3 + paramok[96]=1; // EnableOARCAPI + paramok[97]=1; // MONTOFILE for (i=0; i < PARAMLIM; i++) @@ -651,7 +650,7 @@ BOOL ProcessConfig() Consoleprintf("The following parameters were not correctly specified"); heading = 1; } - Consoleprintf(keywords[i]); + Consoleprintf("%s", keywords[i]); } } @@ -3069,13 +3068,39 @@ int simple(int i) /* Set PARAMOK flags on all values that are defaulted */ - for (i=0; i < PARAMLIM; i++) - paramok[i]=1; - paramok[15] = 0; // Must have callsign paramok[45] = 0; // Dont Have Appl1Call paramok[53] = 0; // or APPL1ALIAS + // Set defined flag on defaulted params + + paramok[0] = 1; // OBSINIT + paramok[1] = 1; // OBSMIN + paramok[2] = 1; // NODESINTERVAL + paramok[3] = 1; // L3TIMETOLIVE + paramok[4] = 1; // L4RETRIES + paramok[5] = 1; // L4TIMEOUT + paramok[7] = 1; // PACLEN + paramok[9] = 1; // T3 + paramok[10] = 1; // IDLETIME + paramok[11] = 1; // BBS + paramok[12] = 1; // NODE + paramok[18] = 1; // IDMSG: + paramok[19] = 1; // INFOMSG: + paramok[22] = 1; // MAXLINKS + paramok[23] = 1; // MAXNODES + paramok[24] = 1; // MAXROUTES + paramok[25] = 1; // MAXCIRCUITS + paramok[26] = 1; // IDINTERVAL + paramok[27] = 1; // MINQUAL + paramok[28] = 1; // HIDENODES + paramok[29] = 1; // L4DELAY + paramok[30] = 1; // L4WINDOW + paramok[31] = 1; // BTINTERVAL + paramok[36] = 1; // CTEXT: + paramok[39] = 1; // ENABLE_LINKED + paramok[41] = 1; // FULL_CTEXT + return(1); } diff --git a/configstructs.h b/configstructs.h index fae9d30..89ffb60 100644 --- a/configstructs.h +++ b/configstructs.h @@ -187,6 +187,7 @@ struct CONFIGTABLE int C_OnlyVer2point0; int C_DEBUGINP3; int C_OARCAPI; + int C_MONTOFILE; //#define ApplOffset 80000 // Applications offset in config buffer diff --git a/datadefs.c b/datadefs.c index 54766ab..5cb3711 100644 --- a/datadefs.c +++ b/datadefs.c @@ -39,7 +39,7 @@ int DEBUGINP3 = 0; int EnableOARCAPI = 0; -int RTTInterval = 24; // 4 Minutes +int RTTInterval = 30; // 5 Minutes BOOL IPRequired = FALSE; BOOL PMRequired = FALSE;