Implement UDPRep to report info on currently bound sockets.

Clean up ARPRep some.
Fix NetworkToPresentation returning bad string.
Fix UDP Chat not closing bound socket.
Fix UDPSocketBind unintentional fall-through.
Add another Test for binding UDP sockets.
This commit is contained in:
TomAwezome 2021-02-27 22:33:34 -05:00
parent bc30fdc12f
commit 91f380b0b6
7 changed files with 255 additions and 6 deletions

View file

@ -224,7 +224,7 @@ U0 ARPRep()
address = EndianU32(Str2I64(temp_hash->str, 16)(U32));
" IP Address: $FG,6$%d.%d.%d.%d$FG$\n",
(&address)(U8 *)[0], (&address)(U8 *)[1], (&address)(U8 *)[2], (&address)(U8 *)[3]; // todo: kludge
address.u8[0], address.u8[1], address.u8[2], address.u8[3]; // todo: kludge
" MAC Address: $FG,6$";$FG$

View file

@ -267,7 +267,7 @@ U8 *NetworkToPresentation(I64 address_family, CIPAddressStorage *source)
{ // converts socket address to IP string, our inet_ntop. Taking Shrine approach of function returns U8* .
U8 *ip_string;
U8 *ip_string = NULL;
CIPV4Address *ipv4_source;
CIPV4Address *ipv6_source;
@ -277,12 +277,13 @@ U8 *NetworkToPresentation(I64 address_family, CIPAddressStorage *source)
ipv4_source = source;
StrPrint(ip_string, "%d.%d.%d.%d",
ip_string = MStrPrint("%d.%d.%d.%d",
ipv4_source->address.u8[0],
ipv4_source->address.u8[1],
ipv4_source->address.u8[2],
ipv4_source->address.u8[3]);
break;
case AF_INET6:
ipv6_source = source;

View file

@ -112,6 +112,9 @@ U0 Chat()
}
Free(sock_addr);
UDPSocketClose(udp_socket);
}
Chat;

View file

@ -17,21 +17,23 @@ U0 UDPSocketTest()
UDPSocketBind(u1, i1);
"Before remove first socket\n";
ClassRep(udp_globals.bound_socket_tree,, 9);
UDPRep;
"\n";
UDPSocketClose(u0);
"After remove first socket\n";
ClassRep(udp_globals.bound_socket_tree,, 9);
UDPRep;
"\n";
UDPSocketClose(u1);
"After both sockets removed\n";
ClassRep(udp_globals.bound_socket_tree,, 9);
UDPRep;
"\n";
Free(i0);
Free(i1);
}
UDPSocketTest;

View file

@ -0,0 +1,93 @@
U0 UDPSocketTest()
{
"Before any sockets added:\n";
UDPRep;
CUDPSocket *u0 = UDPSocket(AF_INET);
CUDPSocket *u1 = UDPSocket(AF_INET);
CUDPSocket *u2 = UDPSocket(AF_INET);
CUDPSocket *u3 = UDPSocket(AF_INET);
CUDPSocket *u4 = UDPSocket(AF_INET);
CUDPSocket *u5 = UDPSocket(AF_INET);
CSocketAddressIPV4 *i0 = CAlloc(sizeof(CSocketAddressIPV4));
CSocketAddressIPV4 *i1 = CAlloc(sizeof(CSocketAddressIPV4));
CSocketAddressIPV4 *i2 = CAlloc(sizeof(CSocketAddressIPV4));
CSocketAddressIPV4 *i3 = CAlloc(sizeof(CSocketAddressIPV4));
CSocketAddressIPV4 *i4 = CAlloc(sizeof(CSocketAddressIPV4));
CSocketAddressIPV4 *i5 = CAlloc(sizeof(CSocketAddressIPV4));
i0->port = EndianU16(30);
i0->family = AF_INET;
i0->address.address = 0xDEADBEEF;
i1->port = EndianU16(25);
i1->family = AF_INET;
i1->address.address = 0xF00DBABE;
i2->port = EndianU16(35);
i2->family = AF_INET;
i2->address.address = 0xC0C0D0D0;
i3->port = EndianU16(20);
i3->family = AF_INET;
i3->address.address = 0xF007BA11;
i4->port = EndianU16(28);
i4->family = AF_INET;
i4->address.address = 0x0B0E5EED;
i5->port = EndianU16(37);
i5->family = AF_INET;
i5->address.address = 0x00ABCDEF;
UDPSocketBind(u0, i0);
UDPSocketBind(u1, i1);
UDPSocketBind(u2, i2);
UDPSocketBind(u3, i3);
UDPSocketBind(u4, i4);
UDPSocketBind(u5, i5);
"All sockets now bound. Currently bound:\n";
UDPRep;
"\n";
UDPSocketClose(u0);
"After remove first socket\n";
UDPRep;
"\n";
UDPSocketClose(u1);
"After remove second socket\n";
UDPRep;
"\n";
UDPSocketClose(u2);
"After remove third socket\n";
UDPRep;
"\n";
UDPSocketClose(u3);
"After remove fourth socket\n";
UDPRep;
"\n";
UDPSocketClose(u4);
"After remove fifth socket\n";
UDPRep;
"\n";
UDPSocketClose(u5);
"After remove sixth socket\n";
UDPRep;
"\n";
Free(i0);
Free(i1);
Free(i2);
Free(i3);
Free(i4);
Free(i5);
}
UDPSocketTest;

View file

@ -439,6 +439,8 @@ I64 UDPSocketBind(CUDPSocket *udp_socket, CSocketAddressStorage *address_source)
UDPTreeNodeQueueAdd(udp_socket, temp_node);
}
break;
case AF_INET6:
Debug("TODO: IPV6 UDP BIND");
break;
@ -789,4 +791,152 @@ I64 UDPHandler(CIPV4Packet *packet)
// NetErr and return fail vals if socket FSM improperly used.
// Careful with Free()'s.
class CUDPRepEntry:CQueue
{
CUDPTreeNode *node;
};
U0 UDPTreeNodeRep(CUDPTreeNode *node)
{
CUDPTreeQueue *queue = node->queue->next;
CUDPSocket *socket;
CSocketAddressIPV4 *ipv4_addr;
CSocketAddressIPV6 *ipv6_addr;
U8 *string;
"Port $$YELLOW$$%d$$FG$$:\n", node->port;
while (queue != node->queue)
{
socket = queue->socket;
switch (socket->receive_address.family)
{
case AF_UNSPEC:
break;
case AF_INET:
ipv4_addr = &socket->receive_address;
string = MStrPrint("%d.%d.%d.%d$FG$",
ipv4_addr->address.address.u8[3],
ipv4_addr->address.address.u8[2],
ipv4_addr->address.address.u8[1],
ipv4_addr->address.address.u8[0]); // todo: kludge, endianness...
" $$LTGREEN$$%s$$FG$$\n", string;
Free(string);
break;
case AF_INET6:
ipv6_addr = &socket->receive_address;
break;
default:
break;
}
queue = queue->next;
}
"\n";
}
U0 UDPRep()
{
CUDPTreeNode *node = udp_globals.bound_socket_tree;
CUDPRepEntry *head;
CUDPRepEntry *entry;
CUDPRepEntry *temp_entry;
if (node)
{
head = CAlloc(sizeof(CUDPRepEntry));
QueueInit(head); // no QueueRemove the head
entry = CAlloc(sizeof(CUDPRepEntry));
entry->node = node;
QueueInsert(entry, head);
// perform depth-first-search while Entry Queue has nodes not fully visited.
while (entry != head)
{
if (entry->node->left)
{ // if node has one, add an Entry for the left branch, continue loop.
temp_entry = CAlloc(sizeof(CUDPRepEntry));
temp_entry->node = entry->node->left;
QueueInsertRev(temp_entry, head);
// if left branch, but no right: toss early, now fully traveled.
if (!entry->node->right)
{
QueueRemove(entry);
UDPTreeNodeRep(entry->node);
Free(entry);
}
entry = temp_entry;
}
else if (entry->node->right)
{ // if no left, but right: add right to queue, pop Entry, Rep, set entry to right.
temp_entry = CAlloc(sizeof(CUDPRepEntry));
temp_entry->node = entry->node->right;
QueueInsertRev(temp_entry, head);
QueueRemove(entry);
UDPTreeNodeRep(entry->node);
Free(entry);
entry = temp_entry;
}
else
{ // pop Entry, Rep, if last Entry in Queue has right add it, pop & Rep travelled Entry, entry = right.
QueueRemove(entry);
UDPTreeNodeRep(entry->node);
Free(entry);
if (head->last != head)
{
temp_entry = head->last;
if (temp_entry->node->right)
{
entry = temp_entry;
temp_entry = CAlloc(sizeof(CUDPRepEntry));
temp_entry->node = entry->node->right;
QueueInsertRev(temp_entry, head);
QueueRemove(entry);
UDPTreeNodeRep(entry->node);
Free(entry);
entry = temp_entry;
}
else
{
QueueRemove(temp_entry);
UDPTreeNodeRep(temp_entry->node);
Free(temp_entry);
entry = head->last;
}
}
else
break;
}
}
Free(head);
}
else
"No UDP Sockets currently bound.\n";
}
UDPGlobalsInit;