diff --git a/APRSCode.c b/APRSCode.c
index 2ee3b5f..6e65001 100644
--- a/APRSCode.c
+++ b/APRSCode.c
@@ -7693,7 +7693,7 @@ VOID APRSProcessHTTPMessage(SOCKET sock, char * MsgPtr, BOOL LOCAL, BOOL COOKIE)
while (ptr)
{
char ToLopped[11] = "";
-
+
if (ptr->Acked)
strcpy(Retries, "A");
else if (ptr->Retries == 0)
@@ -7701,26 +7701,26 @@ VOID APRSProcessHTTPMessage(SOCKET sock, char * MsgPtr, BOOL LOCAL, BOOL COOKIE)
else
sprintf(Retries, "%d", ptr->Retries);
- memcpy(ToLopped, ptr->ToCall, 10);
- strlop(ToLopped, ' ');
+ memcpy(ToLopped, ptr->ToCall, 10);
+ strlop(ToLopped, ' ');
- OutputLen += sprintf(&OutBuffer[OutputLen], WebTXLine,
- ptr->ToCall, ptr->Seq, ptr->Time, Retries, ptr->Text);
- ptr = ptr->Next;
+ OutputLen += sprintf(&OutBuffer[OutputLen], WebTXLine,
+ ptr->ToCall, ptr->Seq, ptr->Time, Retries, ptr->Text);
+ ptr = ptr->Next;
- if (OutputLen > 99000)
- break;
+ if (OutputLen > 99000)
+ break;
- }
+ }
- OutputLen += sprintf(&OutBuffer[OutputLen], "%s", WebTrailer);
+ OutputLen += sprintf(&OutBuffer[OutputLen], "%s", WebTrailer);
- HeaderLen = sprintf(Header, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen);
- sendandcheck(sock, Header, HeaderLen);
- sendandcheck(sock, OutBuffer, OutputLen);
+ HeaderLen = sprintf(Header, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen);
+ sendandcheck(sock, Header, HeaderLen);
+ sendandcheck(sock, OutBuffer, OutputLen);
+
+ return;
- return;
-
}
diff --git a/ARDOP.c b/ARDOP.c
index 5832c44..ef92fad 100644
--- a/ARDOP.c
+++ b/ARDOP.c
@@ -466,107 +466,107 @@ static int ProcessLine(char * buf, int Port)
else
return FALSE; // Must start with ADDR
- TNC->InitScript = malloc(1000);
- TNC->InitScript[0] = 0;
+ TNC->InitScript = malloc(1000);
+ TNC->InitScript[0] = 0;
- ptr = strtok(NULL, " \t\n\r");
+ ptr = strtok(NULL, " \t\n\r");
- if (ptr)
+ if (ptr)
+ {
+ if (_stricmp(ptr, "PTT") == 0)
{
- if (_stricmp(ptr, "PTT") == 0)
+ ptr = strtok(NULL, " \t\n\r");
+
+ if (ptr)
{
+ DecodePTTString(TNC, ptr);
ptr = strtok(NULL, " \t\n\r");
-
- if (ptr)
- {
- DecodePTTString(TNC, ptr);
- ptr = strtok(NULL, " \t\n\r");
- }
}
}
-
- if (ptr)
+ }
+
+ if (ptr)
+ {
+ if (_memicmp(ptr, "PATH", 4) == 0)
{
- if (_memicmp(ptr, "PATH", 4) == 0)
- {
- p_cmd = strtok(NULL, "\n\r");
- if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
- }
+ p_cmd = strtok(NULL, "\n\r");
+ if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
}
+ }
- TNC->MaxConReq = 10; // Default
- TNC->OldMode = FALSE; // Default
+ TNC->MaxConReq = 10; // Default
+ TNC->OldMode = FALSE; // Default
- // Read Initialisation lines
+ // Read Initialisation lines
- while(TRUE)
- {
- if (GetLine(buf) == 0)
- return TRUE;
+ while(TRUE)
+ {
+ if (GetLine(buf) == 0)
+ return TRUE;
- strcpy(errbuf, buf);
+ strcpy(errbuf, buf);
- if (memcmp(buf, "****", 4) == 0)
- return TRUE;
+ if (memcmp(buf, "****", 4) == 0)
+ return TRUE;
- ptr = strchr(buf, ';');
- if (ptr)
- {
- *ptr++ = 13;
- *ptr = 0;
- }
-
- if ((_memicmp(buf, "CAPTURE", 7) == 0) || (_memicmp(buf, "PLAYBACK", 8) == 0))
- {} // Ignore
- else
-/*
+ ptr = strchr(buf, ';');
+ if (ptr)
+ {
+ *ptr++ = 13;
+ *ptr = 0;
+ }
+
+ if ((_memicmp(buf, "CAPTURE", 7) == 0) || (_memicmp(buf, "PLAYBACK", 8) == 0))
+ {} // Ignore
+ else
+ /*
if (_memicmp(buf, "PATH", 4) == 0)
{
- char * Context;
- p_cmd = strtok_s(&buf[5], "\n\r", &Context);
- if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
+ char * Context;
+ p_cmd = strtok_s(&buf[5], "\n\r", &Context);
+ if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
}
else
-*/
+ */
if (_memicmp(buf, "PACKETCHANNELS", 14) == 0) // Packet Channels
TNC->PacketChannels = atoi(&buf[14]);
else
- if (_memicmp(buf, "MAXCONREQ", 9) == 0) // Hold Time for Busy Detect
- TNC->MaxConReq = atoi(&buf[9]);
+ if (_memicmp(buf, "MAXCONREQ", 9) == 0) // Hold Time for Busy Detect
+ TNC->MaxConReq = atoi(&buf[9]);
- else
- if (_memicmp(buf, "STARTINROBUST", 13) == 0)
- TNC->StartInRobust = TRUE;
-
- else
- if (_memicmp(buf, "ROBUST", 6) == 0)
- {
- if (_memicmp(&buf[7], "TRUE", 4) == 0)
- TNC->Robust = TRUE;
-
- strcat (TNC->InitScript, buf);
- }
- else
- if (_memicmp(buf, "LOGDIR ", 7) == 0)
- TNC->LogPath = _strdup(&buf[7]);
- else
- if (_memicmp(buf, "ENABLEPACKET", 12) == 0)
- {
- if (TNC->PacketChannels == 0)
- TNC->PacketChannels = 5;
- // AddVirtualKISSPort(TNC, Port, buf);
- }
+ else
+ if (_memicmp(buf, "STARTINROBUST", 13) == 0)
+ TNC->StartInRobust = TRUE;
-// else if (_memicmp(buf, "PAC ", 4) == 0 && _memicmp(buf, "PAC MODE", 8) != 0)
-// {
- // PAC MODE goes to TNC, others are parsed locally
-//
-// ConfigVirtualKISSPort(TNC, buf);
-// }
- else if (standardParams(TNC, buf) == FALSE)
- strcat(TNC->InitScript, buf);
- }
+ else
+ if (_memicmp(buf, "ROBUST", 6) == 0)
+ {
+ if (_memicmp(&buf[7], "TRUE", 4) == 0)
+ TNC->Robust = TRUE;
+
+ strcat (TNC->InitScript, buf);
+ }
+ else
+ if (_memicmp(buf, "LOGDIR ", 7) == 0)
+ TNC->LogPath = _strdup(&buf[7]);
+ else
+ if (_memicmp(buf, "ENABLEPACKET", 12) == 0)
+ {
+ if (TNC->PacketChannels == 0)
+ TNC->PacketChannels = 5;
+ // AddVirtualKISSPort(TNC, Port, buf);
+ }
+
+ // else if (_memicmp(buf, "PAC ", 4) == 0 && _memicmp(buf, "PAC MODE", 8) != 0)
+ // {
+ // PAC MODE goes to TNC, others are parsed locally
+ //
+ // ConfigVirtualKISSPort(TNC, buf);
+ // }
+ else if (standardParams(TNC, buf) == FALSE)
+ strcat(TNC->InitScript, buf);
+ }
return (TRUE);
@@ -1041,8 +1041,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
TNC->Busy--;
if (TNC->Busy == 0)
+ {
MySetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear");
+ }
}
}
diff --git a/BBSUtilities.c b/BBSUtilities.c
index e803500..e6f7ade 100644
--- a/BBSUtilities.c
+++ b/BBSUtilities.c
@@ -3701,10 +3701,10 @@ void DoKillCommand(CIRCUIT * conn, struct UserInfo * user, char * Cmd, char * Ar
if (conn->sysop)
{
if (Arg1)
- if (KillMessagesFrom(conn, user, Arg1) == 0);
+ if (KillMessagesFrom(conn, user, Arg1) == 0)
BBSputs(conn, "No Messages found\r");
- return;
+ return;
}
}
@@ -6556,7 +6556,7 @@ nextline:
{
char APRS[128];
char Call[16];
- int SSID = user->flags >> 28;
+ int SSID = (user->flags >> 28) & 15; // on some platforms this is treated as signed ??
if (SSID)
sprintf(Call, "%s-%d", Msg->to, SSID);
@@ -13395,7 +13395,7 @@ int DeleteRedundantMessages()
{
while(n--)
{
- if (stat(namelist[n]->d_name, &STAT) == 0);
+ if (stat(namelist[n]->d_name, &STAT) == 0)
{
Msgno = atoi(&namelist[n]->d_name[2]);
diff --git a/BPQINP3.c b/BPQINP3.c
index 872496b..de4bf76 100644
--- a/BPQINP3.c
+++ b/BPQINP3.c
@@ -747,6 +747,9 @@ VOID SortRoutes(struct DEST_LIST * Dest)
{
char Call1[10], Call2[10], Call3[10];
+ // force route re-evaluation
+
+ Dest->DEST_ROUTE = 0;
// May now be out of order
diff --git a/Bpq32.c b/Bpq32.c
index 41d4e64..7215b3b 100644
--- a/Bpq32.c
+++ b/Bpq32.c
@@ -1406,6 +1406,7 @@ void initAIS();
void initADSB();
int CloseAllSessions();
int CloseAllLinks();
+void NETROMTCPResolve();
extern BOOL ADIFLogEnabled;
@@ -1413,6 +1414,8 @@ int CloseOnError = 0;
char UIClassName[]="UIMAINWINDOW"; // the main window class name
+char ClosingClassName[]="CLOSING"; // the main window class name
+
HWND UIhWnd;
extern char AUTOSAVE;
@@ -2216,6 +2219,8 @@ VOID TimerProcX()
Start();
+ NETROMTCPResolve();
+
INITIALISEPORTS(); // Restart Ports
SetApplPorts();
@@ -2398,7 +2403,7 @@ VOID TimerProcX()
if (CloseAllSessions() == 0)
{
if (CloseAllLinks() == 0) // No sessions closed so close links now
- CloseAllTimer = 0; // No Links so close now
+ CloseAllTimer = 1; // No Links so close now
else
CloseAllTimer = 39; // ~4 secs for links to close
}
@@ -2632,6 +2637,7 @@ Check_Timer()
WSAStartup(MAKEWORD(2, 0), &WsaData);
+
// Load Psapi.dll if possible
ExtDriver = LoadLibrary("Psapi.dll");
@@ -2646,6 +2652,8 @@ Check_Timer()
Start();
+ NETROMTCPResolve();
+
INITIALISEPORTS();
OpenReportingSockets();
@@ -2969,6 +2977,8 @@ BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReser
}
else
{
+ NETROMTCPResolve();
+
SetApplPorts();
GetUIConfig();
@@ -5967,14 +5977,96 @@ DllExport VOID APIENTRY CreateNewTrayIcon()
void hookNodeClosing(char * Reason);
+BOOL CALLBACK ClosaAllProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int wmId, wmEvent;
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return (INT_PTR)TRUE;
+
+ case WM_CTLCOLORDLG:
+ return (LONG)bgBrush;
+
+ case WM_CTLCOLORSTATIC:
+ {
+ HDC hdcStatic = (HDC)wParam;
+ SetTextColor(hdcStatic, RGB(0, 0, 0));
+ SetBkMode(hdcStatic, TRANSPARENT);
+
+ return (LONG)bgBrush;
+ }
+
+ case WM_COMMAND:
+
+ return 0;
+
+ case WM_SYSCOMMAND:
+
+ wmId = LOWORD(wParam); // Remember, these are...
+ wmEvent = HIWORD(wParam); // ...different for Win32!
+
+ switch (wmId)
+ {
+ case SC_RESTORE:
+
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+
+ case SC_MINIMIZE:
+
+ if (MinimizetoTray)
+ return ShowWindow(hWnd, SW_HIDE);
+ else
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+
+ break;
+
+ default:
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+
+ case WM_CLOSE:
+ return(DestroyWindow(hWnd));
+
+ default:
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+
+ }
+
+ return (0);
+}
+
+
+HWND hwndClosing = NULL; // Window handle of dialog box
+
DllExport VOID APIENTRY CloseAllPrograms()
{
+ WNDCLASS wc;
CLOSING = TRUE;
// Tell BG to shut when all links are gone or after 5 secs
CloseAllTimer = 50;
+
+
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = ClosaAllProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = DLGWINDOWEXTRA;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON) );
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = bgBrush;
+
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = ClosingClassName;
+
+ RegisterClass(&wc);
+
+ hwndClosing = CreateDialog(hInstance, ClosingClassName, NULL, (DLGPROC)ClosaAllProc);
+ ShowWindow(hwndClosing, SW_SHOW);
}
VOID RealCloseAllPrograms()
diff --git a/Cmd.c b/Cmd.c
index 605ccd1..d532a1e 100644
--- a/Cmd.c
+++ b/Cmd.c
@@ -130,6 +130,8 @@ int NOBUFFCOUNT = 0;
int BUFFERWAITS = 0;
int MAXDESTS = 0;
int NUMBEROFNODES = 0;
+int L2CONNECTSOUT = 0;
+int L2CONNECTSIN = 0;
int L4CONNECTSOUT = 0;
int L4CONNECTSIN = 0;
int L4FRAMESTX = 0;
@@ -903,8 +905,12 @@ int checkifService(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, s
BOOL Stay = FALSE;
char * ptr, *Context;
int i;
+ char TailCopy[256];
- ptr = strtok_s(CmdTail, " ", &Context);
+ strcpy(TailCopy, CmdTail);
+
+
+ ptr = strtok_s(TailCopy, " ", &Context);
// see if any param. if longer than two chars treat as remote node
@@ -2665,7 +2671,8 @@ NoPort:
// SEE IF CALL TO ANY OF OUR HOST SESSIONS - UNLESS DIGIS SPECIFIED
- if (axcalls[7] == 0 && axcalls[9] )
+// if (axcalls[7] == 0 && axcalls[9])
+ if (axcalls[7] == 0)
{
// If this connect is as a result of a command alias, don't check appls or we will loop
@@ -2716,24 +2723,29 @@ NoPort:
}
}
- // if no digis see if connect to known node. But now could have a single numeric param as a service number (Paula's Netromx)
+ // 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;
+ if (cmdCopy[0] != ' ')
+ {
+ i = 0;
- while (cmdCopy[i] >= '0' && cmdCopy[i]<= '9')
- i++;
+ while (cmdCopy[i] >= '0' && cmdCopy[i]<= '9')
+ i++;
- if (cmdCopy[i] != ' ')
- goto Downlink;
- else
- {
- if (i > 0) // Some digits
+ if (cmdCopy[i] != ' ')
+ goto Downlink;
+ else
{
- haveService = 1;
- Service = atoi(cmdCopy);
+ if (i > 0) // Some digits
+ {
+ haveService = 1;
+ Service = atoi(cmdCopy);
+ }
}
}
diff --git a/CommonCode.c b/CommonCode.c
index cffbdb7..9e8b37a 100644
--- a/CommonCode.c
+++ b/CommonCode.c
@@ -75,6 +75,7 @@ void printStack(void);
char * FormatMH(PMHSTRUC MH, char Format);
void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode);
void SendDataToPktMap();
+void NETROMTCPResolve();
extern BOOL LogAllConnects;
extern BOOL M0LTEMap;
@@ -3739,15 +3740,14 @@ VOID ResolveUpdateThread(void * Unused)
LastNodeStatus = time(NULL);
}
}
+
+ NETROMTCPResolve();
if (HostEnt1 && HostEnt2)
{
- Sleep(1000 * 60 * 30);
+ Sleep(1000 * 60 * 15);
continue;
}
-
- Debugprintf("Resolve Failed for update.g8bpq.net or chatmap.g8bpq.net");
- Sleep(1000 * 60 * 5);
}
}
diff --git a/DRATS.c b/DRATS.c
index c7b6b83..7fd85cf 100644
--- a/DRATS.c
+++ b/DRATS.c
@@ -568,18 +568,19 @@ void DRATSConnectionLost(struct ConnectionInfo * sockptr)
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen)
{
- int ret;
- z_stream strm;
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
-
- ret = inflateInit(&strm);
- if (ret != Z_OK)
- return ret;
+ int ret;
+ z_stream strm;
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+
+ ret = inflateInit(&strm);
+
+ if (ret != Z_OK)
+ return ret;
strm.avail_in = Len;
strm.next_in = source;
diff --git a/Events.c b/Events.c
index 2030929..d095bd9 100644
--- a/Events.c
+++ b/Events.c
@@ -57,6 +57,8 @@ extern char LOC[7];
extern char VersionString[50];
extern double LatFromLOC;
extern double LonFromLOC;
+extern int NUMBEROFNODES, MAXDESTS, L4CONNECTSOUT, L4CONNECTSIN, L4FRAMESTX, L4FRAMESRX, L4FRAMESRETRIED, OLDFRAMES;
+extern int L2CONNECTSOUT, L2CONNECTSIN;
void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Direction);
int ConvFromAX25(unsigned char * incall, unsigned char * outcall);
@@ -66,6 +68,7 @@ int decodeNETROMUIMsg(unsigned char * Msg, int iLen, char * Buffer, int BufferLe
int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferLen);
int decodeINP3RIF(unsigned char * Msg, int iLen, char * Buffer, int BufferLen);
int decodeRecordRoute(L3MESSAGE * L3, int iLen, char * Buffer, int BufferLen);
+char * byte_base64_encode(char *str, int len);
// Runs use specified routine on certain event
@@ -145,9 +148,11 @@ void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _
char UDPMsg[1024];
int udplen;
- LINK->ConnectTime = time(NULL);
- LINK->bytesTXed = LINK->bytesRXed = LINK->framesResent = LINK->framesRXed = LINK->framesTXed = 0;
+ L2CONNECTSIN++;
+ LINK->lastStatusSentTime = LINK->ConnectTime = time(NULL);
+ LINK->bytesTXed = LINK->bytesRXed = LINK->framesResent = LINK->framesRXed = LINK->framesTXed = 0;
+ LINK->LastStatusbytesTXed = LINK->LastStatusbytesRXed = 0;
strcpy(LINK->callingCall, remotecall);
strcpy(LINK->receivingCall, ourcall);
strcpy(LINK->Direction, "In");
@@ -217,9 +222,9 @@ void hookL2SessionDeleted(struct _LINKTABLE * LINK)
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK)
{
- LINK->ConnectTime = time(NULL);
+ LINK->lastStatusSentTime = LINK->ConnectTime = time(NULL);
LINK->bytesTXed = LINK->bytesRXed = LINK->framesResent = LINK->framesRXed = LINK->framesTXed = 0;
-
+ LINK->LastStatusbytesTXed = LINK->LastStatusbytesRXed = 0;
strcpy(LINK->callingCall, ourcall);
strcpy(LINK->receivingCall, remotecall);
strcpy(LINK->Direction, "Out");
@@ -232,6 +237,8 @@ void hookL2SessionConnected(struct _LINKTABLE * LINK)
char UDPMsg[1024];
int udplen;
+ L2CONNECTSOUT++;
+
if (NodeAPISocket)
{
LINK->lastStatusSentTime = time(NULL);
@@ -251,6 +258,7 @@ void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Directi
char UDPMsg[1024];
int udplen;
+ time_t Now = time(NULL);
if (NodeAPISocket)
{
@@ -259,16 +267,21 @@ void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Directi
if (strcmp(Direction, "Out") == 0)
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\","
- "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\"}",
+ "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\","
+ " \"time\": %d, \"upForSecs\": %d, \"frmsQdPeak\": %d}",
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall,
- LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason);
+ LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason,
+ (int)Now, (int)Now - LINK->ConnectTime, LINK->maxQueued);
else
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkDownEvent\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\","
- "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\"}",
+ "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d, \"reason\": \"%s\","
+ " \"time\": %d, \"upForSecs\": %d, \"frmsQdPeak\": %d}",
NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall,
- LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason);
+ LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent, Reason,
+ (int)Now, (int)Now - LINK->ConnectTime, LINK->maxQueued);
-// Debugprintf(UDPMsg);
+
+ Debugprintf(UDPMsg);
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
}
@@ -280,23 +293,37 @@ void hookL2SessionStatus(struct _LINKTABLE * LINK)
char UDPMsg[1024];
int udplen;
+ time_t Now = time(NULL);
+ int bpsTx, bpsRx, interval;
if (NodeAPISocket)
{
- LINK->lastStatusSentTime = time(NULL);
+ interval = Now - (int)LINK->lastStatusSentTime;
+ bpsTx = (LINK->bytesTXed - LINK->LastStatusbytesTXed) / interval;
+ bpsRx = (LINK->bytesRXed - LINK->LastStatusbytesRXed) / interval;
+
+ LINK->lastStatusSentTime = Now;
+ LINK->LastStatusbytesTXed = LINK->bytesTXed;
+ LINK->LastStatusbytesRXed = LINK->bytesRXed;
if (strcmp(LINK->Direction, "Out") == 0)
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkStatus\", \"node\": \"%s\", \"id\": %d, \"direction\": \"outgoing\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\","
- "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d}",
- NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall,
- LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, 0, LINK->framesResent);
+ "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d,"
+ "\"upForSecs\": %d, \"frmsQdPeak\": %d, \"bpsTxMean\": %d, \"bpsRxMean\": %d, \"frmQMax\": %d, \"l2rttMs\": %d}",
+ NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->receivingCall, LINK->callingCall,
+ LINK->bytesTXed, LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, 0, LINK->framesResent,
+ (int)Now - LINK->ConnectTime, LINK->maxQueued, bpsTx, bpsRx, LINK->intervalMaxQueued, LINK->RTT);
else
udplen = sprintf(UDPMsg, "{\"@type\":\"LinkStatus\", \"node\": \"%s\", \"id\": %d, \"direction\": \"incoming\", \"port\": \"%d\", \"remote\": \"%s\", \"local\": \"%s\","
- "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d}",
- NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall,
- LINK->bytesTXed , LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, COUNT_AT_L2(LINK), LINK->framesResent);
+ "\"bytesSent\": %d, \"bytesRcvd\": %d, \"frmsSent\": %d, \"frmsRcvd\": %d, \"frmsQueued\": %d, \"frmsResent\": %d,"
+ "\"upForSecs\": %d, \"frmsQdPeak\": %d, \"bpsTxMean\": %d, \"bpsRxMean\": %d, \"frmQMax\": %d, \"l2rttMs\": %d}",
+ NODECALLLOPPED, UDPSeq++, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall,
+ LINK->bytesTXed, LINK->bytesRXed, LINK->framesTXed, LINK->framesRXed, 0, LINK->framesResent,
+ (int)Now - LINK->ConnectTime, LINK->maxQueued, bpsTx, bpsRx, LINK->intervalMaxQueued, LINK->RTT);
-// Debugprintf(UDPMsg);
+ LINK->intervalMaxQueued = 0;
+
+ Debugprintf(UDPMsg);
sendto(NodeAPISocket, UDPMsg, udplen, 0, (struct sockaddr *)&UDPreportdest, sizeof(UDPreportdest));
}
@@ -412,8 +439,9 @@ void hookNodeClosing(char * Reason)
if (NodeAPISocket)
{
- udplen = sprintf(UDPMsg, "{\"@type\": \"NodeDownEvent\", \"nodeCall\": \"%s\", \"nodeAlias\": \"%s\", \"reason\": \"%s\"}",
- NODECALLLOPPED, MYALIASLOPPED, Reason);
+ udplen = sprintf(UDPMsg, "{\"@type\": \"NodeDownEvent\", \"nodeCall\": \"%s\", \"nodeAlias\": \"%s\", \"reason\": \"%s\", \"uptimeSecs\": %d,"
+ "\"linksIn\": %d, \"linksOut\": %d, \"cctsIn\": %d, \"cctsOut\": %d, \"l3Relayed\": %d}",
+ NODECALLLOPPED, MYALIASLOPPED, Reason, time(NULL) - TimeLoaded, L2CONNECTSIN, L2CONNECTSOUT, L4CONNECTSIN, L4CONNECTSOUT, L3FRAMES);
// Debugprintf(UDPMsg);
@@ -438,9 +466,10 @@ void hookNodeRunning()
{
udplen = sprintf(UDPMsg, "{\"@type\": \"NodeStatus\", \"nodeCall\": \"%s\", \"nodeAlias\": \"%s\", \"locator\": \"%s\","
- "\"latitude\": %f, \"longitude\": %f, \"software\": \"%s\", \"version\": \"%s\", \"uptimeSecs\": %d}",
- NODECALLLOPPED, MYALIASLOPPED, LOC, LatFromLOC, LonFromLOC, Software, VersionString, time(NULL) - TimeLoaded);
-
+ "\"latitude\": %f, \"longitude\": %f, \"software\": \"%s\", \"version\": \"%s\", \"uptimeSecs\": %d,"
+ "\"linksIn\": %d, \"linksOut\": %d, \"cctsIn\": %d, \"cctsOut\": %d, \"l3Relayed\": %d}",
+ NODECALLLOPPED, MYALIASLOPPED, LOC, LatFromLOC, LonFromLOC, Software, VersionString, time(NULL) - TimeLoaded,
+ L2CONNECTSIN, L2CONNECTSOUT, L4CONNECTSIN, L4CONNECTSOUT, L3FRAMES);
// Debugprintf(UDPMsg);
@@ -633,7 +662,42 @@ char * PIDtoText(int PID)
return "?";
}
-void APIL2Trace(struct _MESSAGE * Message, char Dirn)
+void dumpDuffPacket(char * call, char * Buffer, int Len)
+{
+ // log to syslog in base64
+
+ char * Base64;
+
+ Base64 = byte_base64_encode(Buffer, Len);
+
+ Debugprintf("Trace Error %s %s", call, Base64);
+ free(Base64);
+}
+
+int checkCall(char * call, unsigned char * Buffer, int Len)
+{
+ char c;
+ int i;
+
+ // Validate source and dest calls - if duff, dump packet
+
+ for (i = 0; i < strlen(call); i++)
+ {
+ c = call[i];
+
+ if (isalnum(c) || c == '-' || c == '@')
+ continue;
+
+ dumpDuffPacket(call, Buffer, Len);
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+void APIL2Trace(struct _MESSAGE * Message, char * Dirn)
{
char UDPMsg[2048];
int udplen;
@@ -650,13 +714,22 @@ void APIL2Trace(struct _MESSAGE * Message, char Dirn)
int NS;
int NR;
+
if ((Message->ORIGIN[6] & 1) == 0) // Digis
return;
destcall[ConvFromAX25(Message->DEST, destcall)] = 0;
srcecall[ConvFromAX25(Message->ORIGIN, srcecall)] = 0;
- // See if any Digis
+ // Validate source and dest calls - if duff, dump packet
+
+ if (!checkCall(destcall,(char *) Message, Message->LENGTH))
+ return;
+
+ if (!checkCall(srcecall, (char *) Message, Message->LENGTH))
+ return;
+
+ // see if any Digis
if ((Message->ORIGIN[6] & 1) == 0) // Digis - ignore for now
return;
@@ -784,9 +857,9 @@ void APIL2Trace(struct _MESSAGE * Message, char Dirn)
// Common to all frame types
udplen = snprintf(UDPMsg, 2048,
- "{\"@type\": \"L2Trace\", \"reportFrom\": \"%s\", \"port\": \"%d\", \"srce\": \"%s\", \"dest\": \"%s\", \"ctrl\": %d,"
- "\"l2type\": \"%s\", \"modulo\": 8, \"cr\": \"%s\"",
- NODECALLLOPPED, Message->PORT, srcecall, destcall, Message->CTL, Type, CR);
+ "{\"@type\": \"L2Trace\", \"dirn\": \"%s\", \"reportFrom\": \"%s\", \"port\": \"%d\", \"srce\": \"%s\", \"dest\": \"%s\", \"ctrl\": %d,"
+ "\"l2Type\": \"%s\", \"modulo\": 8, \"cr\": \"%s\"",
+ Dirn, NODECALLLOPPED, Message->PORT, srcecall, destcall, Message->CTL, Type, CR);
if (UIFlag)
{
@@ -921,6 +994,13 @@ int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferL
destcall[ConvFromAX25(L3MSG->L3DEST, destcall)] = 0;
srcecall[ConvFromAX25(L3MSG->L3SRCE, srcecall)] = 0;
+ if (!checkCall(destcall, Msg, iLen))
+ return 0;
+
+ if (!checkCall(srcecall, Msg, iLen))
+ return 0;
+
+
if (strcmp(destcall, "KEEPLI") == 0)
return 0;
@@ -955,6 +1035,14 @@ int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferL
srcUser[ConvFromAX25(&L3MSG->L4DATA[1], srcUser)] = 0;
srcNode[ConvFromAX25(&L3MSG->L4DATA[8], srcNode)] = 0;
+ if (!checkCall(srcUser, Msg, iLen))
+ return 0;
+
+
+ if (!checkCall(srcNode, Msg, iLen))
+ return 0;
+
+
if (netromx)
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN REQX\", \"fromCct\": %d, \"srcUser\": \"%s\", \"srcNode\": \"%s\", \"window\": %d, \"service\": %d",
(L3MSG->L4INDEX << 8) | L3MSG->L4ID, srcUser, srcNode, L3MSG->L4DATA[0], service);
@@ -969,7 +1057,7 @@ int decodeNETROMIFrame(unsigned char * Msg, int iLen, char * Buffer, int BufferL
// Can be ACK or NACK depending on Choke flag
if (L3MSG->L4FLAGS & L4BUSY)
- Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN NACK\", \"toCct\": %d",
+ Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN NAK\", \"toCct\": %d",
(L3MSG->L4INDEX << 8) | L3MSG->L4ID);
else
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"CONN ACK\", \"toCct\": %d, \"fromCct\": %d, \"accWin\": %d",
@@ -1073,7 +1161,7 @@ int decodeRecordRoute(L3MESSAGE * L3, int iLen, char * Buffer, int BufferLen)
Len += snprintf(&Buffer[Len], BufferLen - Len, ", \"l4Type\": \"NRR Request\", \"nrrId\": %d, \"nrrRoute\": \"%s\"",
(L3->L4TXNO << 8) | L3->L4RXNO, callList);
- Debugprintf(Buffer);
+// Debugprintf(Buffer);
return Len;
}
diff --git a/KernelScript1.rc b/KernelScript1.rc
index 4eef3b5..b230ace 100644
--- a/KernelScript1.rc
+++ b/KernelScript1.rc
@@ -50,6 +50,19 @@ BEGIN
LTEXT "Enable IGate",IDC_STATIC,5,2,49,10
END
+CLOSING DIALOG DISCARDABLE 300, 300, 200, 50
+STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
+ WS_THICKFRAME
+CAPTION "BPQ32 Close All"
+CLASS "CLOSING"
+FONT 8, "Fixedsys"
+BEGIN
+ LTEXT "Closing Links - Please wait....",IDC_BACKGROUND,22,20,337,273
+
+END
+
+
+
CONFIG DIALOGEX 249, 200, 160, 118
STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION
EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE
diff --git a/L2Code.c b/L2Code.c
index 8171d49..44015e1 100644
--- a/L2Code.c
+++ b/L2Code.c
@@ -2346,6 +2346,9 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
LINK->L2TIMER = ONEMINUTE; // (RE)SET TIMER
+
+ LINK->framesResent++;
+
PORT = LINK->LINKPORT;
if (PORT)
@@ -2452,6 +2455,20 @@ treatasRR:
LINK->L2FLAGS &= ~POLLSENT; // CLEAR I(P) or RR(P) SET
+ // ?? is this the place to do RTT?
+
+ if (LINK->lastPSent)
+ {
+ int RTT = GetTickCount() - LINK->lastPSent;
+
+ if (LINK->RTT)
+ LINK->RTT = ((LINK->RTT * 90) / 100) + RTT /10; // Smooth - 90% of old + 10% of new
+ else
+ LINK->RTT = RTT;
+
+ LINK->lastPSent = 0;
+ }
+
if ((CTL & 0xf) == RNR)
{
// Dont Clear timer on receipt of RNR(F), spec says should poll for clearing of busy,
@@ -2927,6 +2944,8 @@ VOID RESETNS(struct _LINKTABLE * LINK, UCHAR NS)
{
int Resent = (LINK->LINKNS - NS) & 7; // FRAMES TO RESEND
+ LINK->framesResent += Resent;
+
LINK->LINKNS = NS; // RESET N(S)
if (LINK->LINKTYPE == 3) // mode-Node
@@ -3150,6 +3169,11 @@ VOID SDETX(struct _LINKTABLE * LINK)
LINK->LASTFRAMESENT = time(NULL);
LINK->LASTSENTQCOUNT = COUNT_AT_L2(LINK);
+ if (LINK->LASTSENTQCOUNT > LINK->maxQueued)
+ LINK->maxQueued = LINK->LASTSENTQCOUNT;
+
+ if (LINK->LASTSENTQCOUNT > LINK->intervalMaxQueued)
+ LINK->intervalMaxQueued = LINK->LASTSENTQCOUNT;
if (LINK->AllowCompress && Msg->LENGTH > 20 && LINK->TX_Q && Msg->PID == 240) // if short and no more not worth trying compression
{
@@ -3352,6 +3376,7 @@ VOID SDETX(struct _LINKTABLE * LINK)
// FLAG BUFFER TO CAUSE TIMER TO BE RESET AFTER SEND (or ACK if ACKMODE)
Buffer->Linkptr = LINK;
+ LINK->lastPSent = GetTickCount();
}
}
diff --git a/L3Code.c b/L3Code.c
index c25df5b..0aafe67 100644
--- a/L3Code.c
+++ b/L3Code.c
@@ -236,7 +236,7 @@ BOOL ACTIVATE_DEST(struct DEST_LIST * DEST)
return L2SETUPCROSSLINK(ROUTE);
}
- // We umst be waiting for link to come up
+ // We must be waiting for link to come up
return TRUE;
@@ -627,9 +627,6 @@ VOID PROCROUTES(struct DEST_LIST * DEST, struct ROUTE * ROUTE, int Qual)
if (Index == 0)
{
// THIS IS A REFRESH OF BEST - IF THIS ISNT ACTIVE ROUTE, MAKE IT ACTIVE
-
- if (DEST->DEST_ROUTE > 1) // LEAVE IT IF NOT SELECTED OR ALREADY USING BEST
- DEST->DEST_ROUTE = 1;
}
goto UpdatateThisEntry;
@@ -728,6 +725,8 @@ SORTROUTES:
goto SORTROUTES; // 1 AND 2 MAY NOW BE WRONG!
}
+
+ DEST->DEST_ROUTE = 0; // OForce re-evaluation.
}
int COUNTNODES(struct ROUTE * ROUTE)
@@ -1042,7 +1041,8 @@ VOID L3TimerProc()
LINK = LINKS;
i = MAXLINKS;
- while (i--);
+
+ while (i--)
{
if (LINK->LINKTYPE == 3) // Only if Internode
{
@@ -1310,6 +1310,9 @@ VOID REMOVENODE(dest_list * DEST)
while (DEST->DEST_Q)
ReleaseBuffer(Q_REM(&DEST->DEST_Q));
+ if (DEST->DEST_STATE & 0x80) // LOCKED DESTINATION
+ return;
+
// MAY NEED TO CHECK FOR L4 CIRCUITS USING DEST, BUT PROBABLY NOT,
// AS THEY SHOULD HAVE TIMED OUT LONG AGO
diff --git a/L4Code.c b/L4Code.c
index ecfd5f0..5704e49 100644
--- a/L4Code.c
+++ b/L4Code.c
@@ -1601,7 +1601,8 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
int Index;
char APPLCMD[13] = "";
- memcpy(APPLCMD, APPL->APPLCMD, 13);
+ if (APPL)
+ memcpy(APPLCMD, APPL->APPLCMD, 13);
memcpy(BPQPARAMS, &L4T1, 2); // SET DEFAULT T1 IN CASE NOT FROM ANOTHER BPQ NODE
@@ -1674,6 +1675,8 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
{
// At the moment I only handle connects to appls. May support other node commands later.
+ memcpy(APPLCMD, CMD->String, 13);
+
if (n < APPL1 + NumberofAppls)
goto doAPPLConnect;
}
@@ -2028,7 +2031,7 @@ TryAgain:
while (n--)
{
- if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0) // Not used and not INP3
+ if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0 && (DEST->DEST_STATE & 0x80) == 0) // Not used and not INP3 and not Appl
{
if (DEST->NRROUTE[0].ROUT_QUALITY < WorstQual)
{
diff --git a/LinBPQ.c b/LinBPQ.c
index 1c16ef4..ad749d0 100644
--- a/LinBPQ.c
+++ b/LinBPQ.c
@@ -85,6 +85,7 @@ VOID GetPGConfig();
void SendBBSDataToPktMap();
void CloseAllLinks();
void hookNodeClosing(char * Reason);
+void NETROMTCPResolve();
extern uint64_t INP3timeLoadedMS;
@@ -1015,6 +1016,8 @@ int main(int argc, char * argv[])
return (0);
}
+ NETROMTCPResolve();
+
for (i=0;PWTEXT[i] > 0x20;i++); //Scan for cr or null
PWLen=i;
@@ -1546,6 +1549,8 @@ int main(int argc, char * argv[])
Consoleprintf(VerCopyright);
Start();
+
+ NETROMTCPResolve();
INITIALISEPORTS();
diff --git a/MailNode.vcproj b/MailNode.vcproj
index 00ed307..ab890bc 100644
--- a/MailNode.vcproj
+++ b/MailNode.vcproj
@@ -468,6 +468,10 @@
RelativePath="..\CommonSource\MULTIPSK.c"
>
+
+
diff --git a/MailTCP.c b/MailTCP.c
index 289fb62..37c7cf9 100644
--- a/MailTCP.c
+++ b/MailTCP.c
@@ -2092,20 +2092,19 @@ int CreateSMTPMessage(SocketConn * sockptr, int i, char * MsgTitle, time_t Date,
struct tm * tm;
tm = gmtime(&Date);
-
+
sprintf(DateString, "%04d/%02d/%02d %02d:%02d",
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
if (strcmp(Msg->to, "RMS") == 0) // Address is in via
- strcpy(B2To, Msg->via);
- else
- if (Msg->via[0])
- sprintf(B2To, "%s@%s", Msg->to, Msg->via);
+ strcpy(B2To, Msg->via);
else
- strcpy(B2To, Msg->to);
+ if (Msg->via[0])
+ sprintf(B2To, "%s@%s", Msg->to, Msg->via);
+ else
+ strcpy(B2To, Msg->to);
-
Msg->B2Flags = B2Msg | Attachments;
if (Msg->type == 'P')
@@ -3934,12 +3933,12 @@ int CreatePOP3Message(char * From, char * To, char * MsgTitle, time_t Date, char
if (strcmp(Msg->to, "RMS") == 0) // Address is in via
- strcpy(B2To, Msg->via);
- else
- if (Msg->via[0])
- sprintf(B2To, "%s@%s", Msg->to, Msg->via);
+ strcpy(B2To, Msg->via);
else
- strcpy(B2To, Msg->to);
+ if (Msg->via[0])
+ sprintf(B2To, "%s@%s", Msg->to, Msg->via);
+ else
+ strcpy(B2To, Msg->to);
Msg->B2Flags = B2Msg | Attachments;
diff --git a/NETROMTCP.c b/NETROMTCP.c
index 79f186b..63c0494 100644
--- a/NETROMTCP.c
+++ b/NETROMTCP.c
@@ -1,551 +1,585 @@
-/*
-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));
-}
-
+/*
+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);
+
+}
+
+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)
+ {
+ // 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);
+ 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);
+
+ if (Route)
+ Route->TCPSession = 0;
+
+ Info->Call[0] = 0;
+ }
+
+ sockptr->SocketActive = FALSE;
+
+ memset(sockptr, 0, sizeof(struct ConnectionInfo));
+}
+
diff --git a/TelnetV6.c b/TelnetV6.c
index 0761363..590186c 100644
--- a/TelnetV6.c
+++ b/TelnetV6.c
@@ -3874,12 +3874,14 @@ MsgLoop:
LFPtr=memchr(MsgPtr, 10, InputLen);
if (LFPtr == 0)
+ {
if (CRPtr)
{
LFPtr = ++CRPtr;
InputLen++;
}
- if (LFPtr == 0)
+ }
+ if (LFPtr == 0)
{
// Check Paclen
@@ -3895,7 +3897,7 @@ MsgLoop:
}
// Send to Node
-
+
// Line could be up to 500 chars if coming from a program rather than an interative user
// Limit send to node to 255
@@ -3907,16 +3909,16 @@ MsgLoop:
memmove(MsgPtr,MsgPtr+255,InputLen);
}
-
+
SendtoNode(TNC, sockptr->Number, MsgPtr, InputLen);
sockptr->InputLen = 0;
-
+
} // PACLEN
return 0; // No CR
}
-
+
// Got a LF
// Process data up to the cr
@@ -3929,7 +3931,7 @@ MsgLoop:
case 2:
// Normal Data State
-
+
STREAM->bytesRXed += MsgLen;
SendIndex = 0;
@@ -3944,7 +3946,7 @@ MsgLoop:
}
SendtoNode(TNC, sockptr->Number, MsgPtr + SendIndex, MsgLen);
-
+
MsgLen += SendIndex;
// If anything left, copy down buffer, and go back
@@ -3963,20 +3965,20 @@ MsgLoop:
return 0;
case 0:
-
- // Check Username
- //
+
+ // Check Username
+ //
*(LFPtr-1)=0; // remove cr
-
- // send(sock, NLMsg, 2, 0);
- if (LogEnabled)
+ // send(sock, NLMsg, 2, 0);
+
+ if (LogEnabled)
{
char Addr[256];
-
+
Tel_Format_Addr(sockptr, Addr);
-
+
if (strlen(MsgPtr) > 64)
{
MsgPtr[64] = 0;
@@ -4571,7 +4573,8 @@ MsgLoop:
if (P8 == 1)
SendPortsForMonitor(sock, sockptr->UserPointer->Secure);
- sockptr->InputLen = 0;
+
+ sockptr->InputLen = 0;
return 0;
}
}
@@ -6386,10 +6389,10 @@ VOID SaveCMSHostInfo(int port, struct TCPINFO * TCP, int CMSNo)
char ip[256];
int n;
- if (sizeof(time_t) == 4)
- n = sscanf(buf,"%s %d %s", addr, (int *)&t, ip);
- else
- n = sscanf(buf, "%s %lld %s", addr, &t, ip);
+ if (sizeof(time_t) == 4)
+ n = sscanf(buf,"%s %d %s", addr, (int *)&t, ip);
+ else
+ n = sscanf(buf, "%s %lld %s", addr, &t, ip);
if (n == 3)
{
diff --git a/UZ7HODrv.c b/UZ7HODrv.c
index e166b36..2adfe12 100644
--- a/UZ7HODrv.c
+++ b/UZ7HODrv.c
@@ -1586,81 +1586,81 @@ static int ProcessLine(char * buf, int Port)
if (TNC->TCPPort == 0)
TNC->TCPPort = 8000;
- TNC->destaddr.sin_family = AF_INET;
- TNC->destaddr.sin_port = htons(TNC->TCPPort);
- TNC->HostName = malloc(strlen(p_ipad)+1);
+ TNC->destaddr.sin_family = AF_INET;
+ TNC->destaddr.sin_port = htons(TNC->TCPPort);
+ TNC->HostName = malloc(strlen(p_ipad)+1);
- if (TNC->HostName == NULL) return TRUE;
+ if (TNC->HostName == NULL) return TRUE;
- strcpy(TNC->HostName,p_ipad);
+ strcpy(TNC->HostName,p_ipad);
- ptr = strtok(NULL, " \t\n\r");
+ ptr = strtok(NULL, " \t\n\r");
- if (ptr)
+ if (ptr)
+ {
+ if (_stricmp(ptr, "PTT") == 0)
{
- if (_stricmp(ptr, "PTT") == 0)
- {
- ptr = strtok(NULL, " \t\n\r");
+ ptr = strtok(NULL, " \t\n\r");
- if (ptr)
- {
- DecodePTTString(TNC, ptr);
- ptr = strtok(NULL, " \t\n\r");
- }
- }
-
- if (ptr &&_memicmp(ptr, "PATH", 4) == 0)
+ if (ptr)
{
- p_cmd = strtok(NULL, "\n\r");
- if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
+ DecodePTTString(TNC, ptr);
+ ptr = strtok(NULL, " \t\n\r");
}
}
- // Read Initialisation lines
-
- while(TRUE)
+ if (ptr &&_memicmp(ptr, "PATH", 4) == 0)
{
- if (GetLine(buf) == 0)
- return TRUE;
+ p_cmd = strtok(NULL, "\n\r");
+ if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
+ }
+ }
- strcpy(errbuf, buf);
+ // Read Initialisation lines
- if (memcmp(buf, "****", 4) == 0)
- return TRUE;
+ while(TRUE)
+ {
+ if (GetLine(buf) == 0)
+ return TRUE;
- ptr = strchr(buf, ';');
- if (ptr)
- {
- *ptr++ = 13;
- *ptr = 0;
- }
-
- if (_memicmp(buf, "MAXSESSIONS", 11) == 0)
- {
- AGW->MaxSessions = atoi(&buf[12]);
- if (AGW->MaxSessions > 26 ) AGW->MaxSessions = 26;
- }
- if (_memicmp(buf, "CONTIMEOUT", 10) == 0)
- AGW->ConnTimeOut = atoi(&buf[11]) * 10;
- else
+ strcpy(errbuf, buf);
+
+ if (memcmp(buf, "****", 4) == 0)
+ return TRUE;
+
+ ptr = strchr(buf, ';');
+ if (ptr)
+ {
+ *ptr++ = 13;
+ *ptr = 0;
+ }
+
+ if (_memicmp(buf, "MAXSESSIONS", 11) == 0)
+ {
+ AGW->MaxSessions = atoi(&buf[12]);
+ if (AGW->MaxSessions > 26 ) AGW->MaxSessions = 26;
+ }
+ if (_memicmp(buf, "CONTIMEOUT", 10) == 0)
+ AGW->ConnTimeOut = atoi(&buf[11]) * 10;
+ else
if (_memicmp(buf, "UPDATEMAP", 9) == 0)
TNC->PktUpdateMap = TRUE;
else
- if (_memicmp(buf, "BEACONAFTERSESSION", 18) == 0) // Send Beacon after each session
- TNC->RPBEACON = TRUE;
- else
- if (_memicmp(buf, "WINDOW", 6) == 0)
- TNC->Window = atoi(&buf[7]);
- else
- if (_memicmp(buf, "DEFAULTMODEM", 12) == 0)
- TNC->AGWInfo->Modem = atoi(&buf[13]);
- else
- if (_memicmp(buf, "MODEMCENTER", 11) == 0 || _memicmp(buf, "MODEMCENTRE", 11) == 0)
- TNC->AGWInfo->CenterFreq = atoi(&buf[12]);
- else
- if (standardParams(TNC, buf) == FALSE)
- strcat(TNC->InitScript, buf);
- }
+ if (_memicmp(buf, "BEACONAFTERSESSION", 18) == 0) // Send Beacon after each session
+ TNC->RPBEACON = TRUE;
+ else
+ if (_memicmp(buf, "WINDOW", 6) == 0)
+ TNC->Window = atoi(&buf[7]);
+ else
+ if (_memicmp(buf, "DEFAULTMODEM", 12) == 0)
+ TNC->AGWInfo->Modem = atoi(&buf[13]);
+ else
+ if (_memicmp(buf, "MODEMCENTER", 11) == 0 || _memicmp(buf, "MODEMCENTRE", 11) == 0)
+ TNC->AGWInfo->CenterFreq = atoi(&buf[12]);
+ else
+ if (standardParams(TNC, buf) == FALSE)
+ strcat(TNC->InitScript, buf);
+ }
return (TRUE);
diff --git a/VARA.c b/VARA.c
index 70f7461..f913fe8 100644
--- a/VARA.c
+++ b/VARA.c
@@ -423,8 +423,9 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
TNC->Busy--;
if (TNC->Busy == 0)
- SetWindowText(TNC->xIDC_CHANSTATE, "Clear");
+ { SetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear");
+ }
}
}
diff --git a/Versions.h b/Versions.h
index be8a65e..f5d5fb8 100644
--- a/Versions.h
+++ b/Versions.h
@@ -10,8 +10,8 @@
#endif
-#define KVers 6,0,25,8
-#define KVerstring "6.0.25.8\0"
+#define KVers 6,0,25,9
+#define KVerstring "6.0.25.9\0"
#ifdef CKernel
diff --git a/WINMOR.c b/WINMOR.c
index 836a070..94630b3 100644
--- a/WINMOR.c
+++ b/WINMOR.c
@@ -618,8 +618,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
TNC->Busy--;
if (TNC->Busy == 0)
+ {
SetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear");
+ }
}
}
diff --git a/WebMail.c b/WebMail.c
index 63bfd6e..a97b9bf 100644
--- a/WebMail.c
+++ b/WebMail.c
@@ -3311,7 +3311,7 @@ char * xxReadTemplate(char * FormSet, char * DirName, char *FileName)
while ((entry = readdir(dir)) != NULL)
{
if (entry->d_type == DT_DIR)
- continue;
+ continue;
if (stristr(entry->d_name, FileName))
{
@@ -5609,7 +5609,7 @@ char * CheckFile(struct HtmlFormDir * Dir, char * FN)
while ((entry = readdir(dir)) != NULL)
{
if (entry->d_type == DT_DIR)
- continue;
+ continue;
if (stricmp(entry->d_name, FN) == 0)
{
diff --git a/asmstrucs.h b/asmstrucs.h
index 3ac464b..89e5277 100644
--- a/asmstrucs.h
+++ b/asmstrucs.h
@@ -250,7 +250,8 @@ typedef struct ROUTE
char * TCPHost; // For NETROM over TCP
int TCPPort;
- struct NRTCPSTRUCT * TCPSession;
+ struct NRTCPSTRUCT * TCPSession;
+ struct addrinfo * TCPAddress; // Resolved Address
} *PROUTE;
@@ -977,6 +978,15 @@ typedef struct _LINKTABLE
int framesRXed;
int framesTXed;
int framesResent;
+ time_t LastStatusTime;
+ int LastStatusbytesRXed;
+ int LastStatusbytesTXed;
+ int maxQueued;
+ int intervalMaxQueued;
+
+ uint64_t lastPSent; // Time last I frame with P bit sent in mS (for RTT Measurements)
+ int RTT;
+
// Now support compressing L2 Sessions.
// We collect as much data as possible before compressing and re-packetizing
diff --git a/bpqaxip.c b/bpqaxip.c
index 3491bbd..71f0ce1 100644
--- a/bpqaxip.c
+++ b/bpqaxip.c
@@ -444,7 +444,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
From[ConvFromAX25(call, &From[1]) + 1] = 0;
if (strstr(CantReplyList, From) == 0)
{
- if (strlen(CantReplyList) < 500);
+ if (strlen(CantReplyList) < 500)
strcat(CantReplyList, From);
Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]);
}
@@ -557,7 +557,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
From[ConvFromAX25(call, &From[1]) + 1] = 0;
if (strstr(CantReplyList, From) == 0)
{
- if (strlen(CantReplyList) < 500);
+ if (strlen(CantReplyList) < 500)
strcat(CantReplyList, From);
Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]);
}
diff --git a/cMain.c b/cMain.c
index 74b6bc6..1eda80c 100644
--- a/cMain.c
+++ b/cMain.c
@@ -57,7 +57,7 @@ VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD);
void WritePacketLogThread(void * param);
void hookNodeStarted();
void hookNodeRunning();
-void APIL2Trace(struct _MESSAGE * Message, char Dirn);
+void APIL2Trace(struct _MESSAGE * Message, char * Dirn);
#include "configstructs.h"
@@ -1416,12 +1416,15 @@ BOOL Start()
{
ROUTE->TCPHost = Rcfg->tcphost;
ROUTE->TCPPort = Rcfg->tcpport;
+
+ ROUTE->TCPAddress = (struct addrinfo *)zalloc(sizeof(struct addrinfo));
+ ROUTE->TCPAddress->ai_addr = (struct sockaddr *) zalloc(sizeof(struct sockaddr));
}
Rcfg++;
ROUTE++;
}
-
+
// SET UP INFO MESSAGE
ptr2 = &cfg->C_INFOMSG[0];
@@ -2028,7 +2031,7 @@ VOID ReadNodes()
ptr = strtok_s(NULL, seps, &Context); // INP3
if (ptr == NULL) continue;
- if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0); // Not LOCKED ROUTE
+ if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0) // Not LOCKED ROUTE
ROUTE->OtherendsRouteQual = atoi(ptr);
ptr = strtok_s(NULL, seps, &Context); // INP3
@@ -2279,7 +2282,7 @@ VOID TIMERINTERRUPT()
Message = (struct _MESSAGE *)Buffer;
if(NodeAPISocket)
- APIL2Trace(Message, 'T');
+ APIL2Trace(Message, "sent");
Message->PORT |= 0x80; // Set TX Bit
@@ -2394,7 +2397,7 @@ L2Packet:
MQTTKISSRX(Buffer);
if(NodeAPISocket &&PORT->PROTOCOL == 0)
- APIL2Trace(Message, 'R');
+ APIL2Trace(Message, "rcvd");
// Bridge if requested
diff --git a/config.c b/config.c
index bb0b2f2..33213df 100644
--- a/config.c
+++ b/config.c
@@ -635,6 +635,8 @@ BOOL ProcessConfig()
paramok[93]=1; // ONLYVer2point0
paramok[94]=1; // DEBUGINP3
paramok[95]=1; // EnableOARCAPI
+ paramok[96]=1; // OARCAPI
+
for (i=0; i < PARAMLIM; i++)
{
diff --git a/debug/bpq32.pdb b/debug/bpq32.pdb
deleted file mode 100644
index 1e17966..0000000
Binary files a/debug/bpq32.pdb and /dev/null differ
diff --git a/lzhuf32.c b/lzhuf32.c
index c1aea82..961c624 100644
--- a/lzhuf32.c
+++ b/lzhuf32.c
@@ -487,124 +487,124 @@ static void reconst(void)
static void update(int c)
{
- int i, j, l;
+ int i, j, l;
unsigned int k;
- if (freq[R] == MAX_FREQ) {
- reconst();
- }
- c = prnt[c + T];
- do {
- k = ++freq[c];
+ if (freq[R] == MAX_FREQ) {
+ reconst();
+ }
+ c = prnt[c + T];
+ do {
+ k = ++freq[c];
- /* if the order is disturbed, exchange nodes */
+ /* if the order is disturbed, exchange nodes */
+
+ l = c + 1;
- l = c + 1;
-
if ((unsigned)k > freq[l])
{
- while ((unsigned)k > freq[++l]);
- l--;
- freq[c] = freq[l];
- freq[l] = k;
+ while ((unsigned)k > freq[++l]);
+ l--;
+ freq[c] = freq[l];
+ freq[l] = k;
- i = son[c];
- prnt[i] = l;
- if (i < T) prnt[i + 1] = l;
+ i = son[c];
+ prnt[i] = l;
+ if (i < T) prnt[i + 1] = l;
- j = son[l];
- son[l] = i;
+ j = son[l];
+ son[l] = i;
- prnt[j] = c;
- if (j < T) prnt[j + 1] = c;
- son[c] = j;
+ prnt[j] = c;
+ if (j < T) prnt[j + 1] = c;
+ son[c] = j;
- c = l;
- }
- } while ((c = prnt[c]) != 0); /* repeat up to root */
+ c = l;
+ }
+ } while ((c = prnt[c]) != 0); /* repeat up to root */
}
unsigned code, len;
static void EncodeChar(unsigned int c)
{
- unsigned int i;
- int j, k;
-
- i = 0;
- j = 0;
- k = prnt[c + T];
-
- /* travel from leaf to root */
- do {
- i >>= 1;
-
- /* if node's address is odd-numbered, choose bigger brother node */
- if (k & 1) i += 0x8000;
-
- j++;
- } while ((k = prnt[k]) != R);
- Putcode(j, i);
- code = i;
- len = j;
- update(c);
+ unsigned int i;
+ int j, k;
+
+ i = 0;
+ j = 0;
+ k = prnt[c + T];
+
+ /* travel from leaf to root */
+ do {
+ i >>= 1;
+
+ /* if node's address is odd-numbered, choose bigger brother node */
+ if (k & 1) i += 0x8000;
+
+ j++;
+ } while ((k = prnt[k]) != R);
+ Putcode(j, i);
+ code = i;
+ len = j;
+ update(c);
}
static void EncodePosition(unsigned int c)
{
- unsigned int i;
+ unsigned int i;
- /* output upper 6 bits by table lookup */
- i = c >> 6;
- Putcode(p_len[i], (unsigned)p_code[i] << 8);
+ /* output upper 6 bits by table lookup */
+ i = c >> 6;
+ Putcode(p_len[i], (unsigned)p_code[i] << 8);
- /* output lower 6 bits verbatim */
- Putcode(6, (c & 0x3f) << 10);
+ /* output lower 6 bits verbatim */
+ Putcode(6, (c & 0x3f) << 10);
}
static void EncodeEnd(void)
{
- if (putlen) {
- if (crc_fputc(putbuf >> 8) == EOF) {
- Error(wterr);
- }
- codesize++;
- }
+ if (putlen) {
+ if (crc_fputc(putbuf >> 8) == EOF) {
+ Error(wterr);
+ }
+ codesize++;
+ }
}
int DecodeChar(void)
{
- unsigned int c;
+ unsigned int c;
- c = son[R];
+ c = son[R];
- /* travel from root to leaf, */
- /* choosing the smaller child node (son[]) if the read bit is 0, */
- /* the bigger (son[]+1} if 1 */
- while (c < T) {
- c += GetBit();
- c = son[c];
- }
- c -= T;
- update(c);
- return (int)c;
+ /* travel from root to leaf, */
+ /* choosing the smaller child node (son[]) if the read bit is 0, */
+ /* the bigger (son[]+1} if 1 */
+ while (c < T) {
+ c += GetBit();
+ c = son[c];
+ }
+ c -= T;
+ update(c);
+ return (int)c;
}
int DecodePosition(void)
{
- unsigned int i, j, c;
+ unsigned int i, j, c;
- /* recover upper 6 bits from table */
- i = GetByte();
- c = (unsigned)d_code[i] << 6;
- j = d_len[i];
+ /* recover upper 6 bits from table */
+ i = GetByte();
+ c = (unsigned)d_code[i] << 6;
+ j = d_len[i];
- /* read lower 6 bits verbatim */
- j -= 2;
- while (j--) {
- i = (i << 1) + GetBit();
- }
- return (int)(c | (i & 0x3f));
+ /* read lower 6 bits verbatim */
+ j -= 2;
+ while (j--) {
+ i = (i << 1) + GetBit();
+ }
+ return (int)(c | (i & 0x3f));
}
/* compression */
diff --git a/pngwutil.c b/pngwutil.c
index dd7b150..2f42e07 100644
--- a/pngwutil.c
+++ b/pngwutil.c
@@ -350,10 +350,11 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
comp->output_ptr[i]=NULL;
}
if (comp->max_output_ptr != 0)
- png_free(png_ptr, comp->output_ptr);
- comp->output_ptr=NULL;
+ png_free(png_ptr, comp->output_ptr);
+ comp->output_ptr=NULL;
/* write anything left in zbuf */
if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+
png_write_chunk_data(png_ptr, png_ptr->zbuf,
png_ptr->zbuf_size - png_ptr->zstream.avail_out);