mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-01-05 20:26:32 +00:00
dbf8647d59
Added top & right borders to RawDr. Improved spacing in some debug and compiler reporting. Fixed RawPutChar and EdLite tab width. Fixed Ui missing '0x' prefix syntax highlighter bug. Added 32BitPaint demo.
735 lines
61 KiB
HTML
Executable file
735 lines
61 KiB
HTML
Executable file
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
|
|
<meta name="generator" content="ZealOS V0.08">
|
|
<style type="text/css">
|
|
body {background-color:#000000;}
|
|
.cF0{color:#ffffff;background-color:#000000;}
|
|
.cF1{color:#3465a4;background-color:#000000;}
|
|
.cF2{color:#4e9a06;background-color:#000000;}
|
|
.cF3{color:#06989a;background-color:#000000;}
|
|
.cF4{color:#a24444;background-color:#000000;}
|
|
.cF5{color:#75507b;background-color:#000000;}
|
|
.cF6{color:#ce982f;background-color:#000000;}
|
|
.cF7{color:#bcc0b9;background-color:#000000;}
|
|
.cF8{color:#555753;background-color:#000000;}
|
|
.cF9{color:#729fcf;background-color:#000000;}
|
|
.cFA{color:#82bc49;background-color:#000000;}
|
|
.cFB{color:#34e2e2;background-color:#000000;}
|
|
.cFC{color:#ac3535;background-color:#000000;}
|
|
.cFD{color:#ad7fa8;background-color:#000000;}
|
|
.cFE{color:#fce94f;background-color:#000000;}
|
|
.cFF{color:#000000;background-color:#000000;}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<pre style="font-family:monospace;font-size:12pt">
|
|
<a name="l1"></a><span class=cF2>/***************************************************</span><span class=cF0>
|
|
<a name="l2"></a>
|
|
<a name="l3"></a></span><span class=cF2>UDP Socket Functions</span><span class=cF0>
|
|
<a name="l4"></a>
|
|
<a name="l5"></a></span><span class=cF2>***************************************************/</span><span class=cF0>
|
|
<a name="l6"></a>
|
|
<a name="l7"></a></span><span class=cF1>U0</span><span class=cF0> UDPGlobalsInit()
|
|
<a name="l8"></a>{
|
|
<a name="l9"></a> udp_globals.bound_socket_tree = </span><span class=cF3>NULL</span><span class=cF0>;
|
|
<a name="l10"></a>}
|
|
<a name="l11"></a>
|
|
<a name="l12"></a></span><span class=cF9>I64</span><span class=cF0> UDPPacketAllocate(</span><span class=cF1>U8</span><span class=cF0> **frame_out,
|
|
<a name="l13"></a> </span><span class=cF9>U32</span><span class=cF0> source_ip,
|
|
<a name="l14"></a> </span><span class=cF9>U16</span><span class=cF0> source_port,
|
|
<a name="l15"></a> </span><span class=cF9>U32</span><span class=cF0> destination_ip,
|
|
<a name="l16"></a> </span><span class=cF9>U16</span><span class=cF0> destination_port,
|
|
<a name="l17"></a> </span><span class=cF9>I64</span><span class=cF0> length)
|
|
<a name="l18"></a>{
|
|
<a name="l19"></a> </span><span class=cF1>U8</span><span class=cF0> *udp_frame;
|
|
<a name="l20"></a> </span><span class=cF9>I64</span><span class=cF0> de_index;
|
|
<a name="l21"></a> CUDPHeader *header;
|
|
<a name="l22"></a>
|
|
<a name="l23"></a> de_index = IPV4PacketAllocate(&udp_frame,
|
|
<a name="l24"></a> IP_PROTOCOL_UDP,
|
|
<a name="l25"></a> source_ip,
|
|
<a name="l26"></a> destination_ip,
|
|
<a name="l27"></a> </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPHeader</span><span class=cF7>)</span><span class=cF0> + length);
|
|
<a name="l28"></a> </span><span class=cF1>if</span><span class=cF0> (de_index < </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l29"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l30"></a> NetLog(</span><span class=cF6>"UDP PACKET ALLOCATE: Ethernet Frame Allocate failed."</span><span class=cF0>);
|
|
<a name="l31"></a> </span><span class=cF1>return</span><span class=cF0> de_index;
|
|
<a name="l32"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l33"></a>
|
|
<a name="l34"></a> header = udp_frame;
|
|
<a name="l35"></a>
|
|
<a name="l36"></a> header->source_port = </span><span class=cF5>EndianU16</span><span class=cF0>(source_port);
|
|
<a name="l37"></a> header->destination_port = </span><span class=cF5>EndianU16</span><span class=cF0>(destination_port);
|
|
<a name="l38"></a> header->length = </span><span class=cF5>EndianU16</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPHeader</span><span class=cF7>)</span><span class=cF0> + length);
|
|
<a name="l39"></a> header->checksum = </span><span class=cFE>0</span><span class=cF0>;
|
|
<a name="l40"></a>
|
|
<a name="l41"></a> *frame_out = udp_frame + </span><span class=cF1>sizeof</span><span class=cF0>(CUDPHeader);
|
|
<a name="l42"></a>
|
|
<a name="l43"></a> </span><span class=cF1>return</span><span class=cF0> de_index;
|
|
<a name="l44"></a>}
|
|
<a name="l45"></a>
|
|
<a name="l46"></a></span><span class=cF1>U0</span><span class=cF0> UDPPacketFinish(</span><span class=cF9>I64</span><span class=cF0> de_index)
|
|
<a name="l47"></a>{ </span><span class=cF2>// alias for IPV4PacketFinish, alias for EthernetFrameFinish, alias for driver send packet</span><span class=cF0>
|
|
<a name="l48"></a> IPV4PacketFinish(de_index);
|
|
<a name="l49"></a>}
|
|
<a name="l50"></a>
|
|
<a name="l51"></a></span><span class=cF9>I64</span><span class=cF0> UDPPacketParse(</span><span class=cF9>U16</span><span class=cF0> *source_port_out,
|
|
<a name="l52"></a> </span><span class=cF9>U16</span><span class=cF0> *destination_port_out,
|
|
<a name="l53"></a> </span><span class=cF1>U8</span><span class=cF0> **data_out,
|
|
<a name="l54"></a> </span><span class=cF9>I64</span><span class=cF0> *length_out,
|
|
<a name="l55"></a> CIPV4Packet *packet)
|
|
<a name="l56"></a>{
|
|
<a name="l57"></a>
|
|
<a name="l58"></a> </span><span class=cF2>// check ip protocol? probably redundant</span><span class=cF0>
|
|
<a name="l59"></a>
|
|
<a name="l60"></a> CUDPHeader *header = packet->data;
|
|
<a name="l61"></a>
|
|
<a name="l62"></a> </span><span class=cF2>// TODO: Validate packet length !</span><span class=cF0>
|
|
<a name="l63"></a>
|
|
<a name="l64"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>NetDebug("UDP PACKET PARSE: Caught packet, src port: 0x%0X (B.E.)", header->source_port);</span><span class=cF0>
|
|
<a name="l65"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>NetDebug("UDP PACKET PARSE: Caught packet, dest port: 0x%0X (B.E.)", header->destination_port);</span><span class=cF0>
|
|
<a name="l66"></a>
|
|
<a name="l67"></a>
|
|
<a name="l68"></a> *source_port_out = </span><span class=cF5>EndianU16</span><span class=cF0>(header->source_port);
|
|
<a name="l69"></a> *destination_port_out = </span><span class=cF5>EndianU16</span><span class=cF0>(header->destination_port);
|
|
<a name="l70"></a>
|
|
<a name="l71"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>NetDebug("UDP PACKET PARSE: Source Port output: 0x%0X (L.E.)", *source_port_out);</span><span class=cF0>
|
|
<a name="l72"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>NetDebug("UDP PACKET PARSE: Destination Port Output: 0x%0X (L.E.)", *destination_port_out);</span><span class=cF0>
|
|
<a name="l73"></a>
|
|
<a name="l74"></a> *data_out = packet->data + </span><span class=cF1>sizeof</span><span class=cF0>(CUDPHeader);
|
|
<a name="l75"></a> *length_out = packet->length - </span><span class=cF1>sizeof</span><span class=cF0>(CUDPHeader);
|
|
<a name="l76"></a>
|
|
<a name="l77"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
|
|
<a name="l78"></a>
|
|
<a name="l79"></a>}
|
|
<a name="l80"></a>
|
|
<a name="l81"></a>CUDPSocket *UDPSocket(</span><span class=cF9>U16</span><span class=cF0> domain=AF_UNSPEC)
|
|
<a name="l82"></a>{
|
|
<a name="l83"></a> </span><span class=cF9>U16</span><span class=cF0> type = SOCKET_DATAGRAM;
|
|
<a name="l84"></a> CUDPSocket *udp_socket = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPSocket</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l85"></a>
|
|
<a name="l86"></a> udp_socket->socket = Socket(domain, type);
|
|
<a name="l87"></a>
|
|
<a name="l88"></a> udp_socket->receive_address.family = domain; </span><span class=cF2>// INET, INET6, or unspecified</span><span class=cF0>
|
|
<a name="l89"></a>
|
|
<a name="l90"></a> udp_socket->receive_queue = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPMessageQueue</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l91"></a> </span><span class=cF5>QueueInit</span><span class=cF0>(udp_socket->receive_queue); </span><span class=cF2>// acts as head. add messages to but don't remove head.</span><span class=cF0>
|
|
<a name="l92"></a>
|
|
<a name="l93"></a> </span><span class=cF1>return</span><span class=cF0> udp_socket;
|
|
<a name="l94"></a>
|
|
<a name="l95"></a>}
|
|
<a name="l96"></a>
|
|
<a name="l97"></a></span><span class=cF9>I64</span><span class=cF0> UDPSocketBind(CUDPSocket *udp_socket, CSocketAddressStorage *address_source)
|
|
<a name="l98"></a>{
|
|
<a name="l99"></a> CUDPTreeNode *head = udp_globals.bound_socket_tree;
|
|
<a name="l100"></a> CUDPTreeNode *temp_node;
|
|
<a name="l101"></a> CSocketAddressIPV4 *ipv4_source;
|
|
<a name="l102"></a> CSocketAddressIPV4 *ipv4_receive;
|
|
<a name="l103"></a> CSocketAddressIPV6 *ipv6_source;
|
|
<a name="l104"></a> CSocketAddressIPV6 *ipv6_receive;
|
|
<a name="l105"></a> </span><span class=cF9>U16</span><span class=cF0> port;
|
|
<a name="l106"></a>
|
|
<a name="l107"></a> </span><span class=cF1>if</span><span class=cF0> (!SocketBind</span><span class=cF7>(</span><span class=cF0>udp_socket->socket</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l108"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l109"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: Failed, Socket state-machine must be in READY state."</span><span class=cF0>);
|
|
<a name="l110"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l111"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l112"></a>
|
|
<a name="l113"></a> </span><span class=cF1>if</span><span class=cF0> (udp_socket->bound_to)
|
|
<a name="l114"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l115"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: UDP Socket currently Bound."</span><span class=cF0>);
|
|
<a name="l116"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l117"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l118"></a>
|
|
<a name="l119"></a> </span><span class=cF1>switch</span><span class=cF0> (address_source->family)
|
|
<a name="l120"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l121"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET:
|
|
<a name="l122"></a>
|
|
<a name="l123"></a> </span><span class=cF1>if</span><span class=cF0> (udp_socket->receive_address.family == AF_INET6)
|
|
<a name="l124"></a> {
|
|
<a name="l125"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: Incompatible Address type."</span><span class=cF0>);
|
|
<a name="l126"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l127"></a> }
|
|
<a name="l128"></a>
|
|
<a name="l129"></a> ipv4_source = address_source;
|
|
<a name="l130"></a> ipv4_receive = &udp_socket->receive_address;
|
|
<a name="l131"></a>
|
|
<a name="l132"></a> ipv4_receive->address.address = ipv4_source->address.address; </span><span class=cF2>// bind socket to address in parameter.</span><span class=cF0>
|
|
<a name="l133"></a> ipv4_receive->port = ipv4_source->port; </span><span class=cF2>// ... consistency would say keep in Big Endian ...</span><span class=cF0>
|
|
<a name="l134"></a>
|
|
<a name="l135"></a> port = </span><span class=cF5>EndianU16</span><span class=cF0>(ipv4_source->port); </span><span class=cF2>// port member should be Big Endian, so now we're going L.E (?)</span><span class=cF0>
|
|
<a name="l136"></a>
|
|
<a name="l137"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l138"></a>
|
|
<a name="l139"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET6:
|
|
<a name="l140"></a>
|
|
<a name="l141"></a> </span><span class=cF1>if</span><span class=cF0> (udp_socket->receive_address.family == AF_INET)
|
|
<a name="l142"></a> {
|
|
<a name="l143"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: Incompatible Address type."</span><span class=cF0>);
|
|
<a name="l144"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l145"></a> }
|
|
<a name="l146"></a>
|
|
<a name="l147"></a> ipv6_source = address_source;
|
|
<a name="l148"></a> ipv6_receive = &udp_socket->receive_address;
|
|
<a name="l149"></a> </span><span class=cF2>// ...</span><span class=cF0>
|
|
<a name="l150"></a> </span><span class=cF2>// ...</span><span class=cF0>
|
|
<a name="l151"></a>
|
|
<a name="l152"></a> port = </span><span class=cF5>EndianU16</span><span class=cF0>(ipv6_source->port); </span><span class=cF2>// port member should be Big Endian, so now we're going L.E (?)</span><span class=cF0>
|
|
<a name="l153"></a>
|
|
<a name="l154"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: FIXME, IPV6 UDP BIND"</span><span class=cF0>);
|
|
<a name="l155"></a>
|
|
<a name="l156"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l157"></a>
|
|
<a name="l158"></a> </span><span class=cF1>case</span><span class=cF0> AF_UNSPEC:
|
|
<a name="l159"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: Error, AF_UNSPEC UDP BIND -- param family"</span><span class=cF0>);
|
|
<a name="l160"></a>
|
|
<a name="l161"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l162"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l163"></a>
|
|
<a name="l164"></a> </span><span class=cF2>// at this point, Socket and Address have matching family values</span><span class=cF0>
|
|
<a name="l165"></a>
|
|
<a name="l166"></a> </span><span class=cF1>if</span><span class=cF0> (head)
|
|
<a name="l167"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l168"></a> </span><span class=cF2>// look for our port.</span><span class=cF0>
|
|
<a name="l169"></a> temp_node = UDPTreeNodeFind(port, head);
|
|
<a name="l170"></a>
|
|
<a name="l171"></a> </span><span class=cF1>if</span><span class=cF0> (temp_node)
|
|
<a name="l172"></a> { </span><span class=cF2>// if we find we have bound sockets at port, check address before adding to queue</span><span class=cF0>
|
|
<a name="l173"></a> </span><span class=cF1>switch</span><span class=cF0> (address_source->family)
|
|
<a name="l174"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l175"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET:
|
|
<a name="l176"></a> </span><span class=cF1>if</span><span class=cF0> (UDPTreeNodeQueueIPV4Find</span><span class=cF7>(</span><span class=cF0>ipv4_receive->address.address, temp_node, </span><span class=cF3>TRUE</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l177"></a> {
|
|
<a name="l178"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: Address already in Bound Socket Tree !"</span><span class=cF0>);
|
|
<a name="l179"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l180"></a> }
|
|
<a name="l181"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l182"></a> { </span><span class=cF2>// if no address match, free to add socket to the node queue</span><span class=cF0>
|
|
<a name="l183"></a> UDPTreeNodeQueueAdd(udp_socket, temp_node);
|
|
<a name="l184"></a> }
|
|
<a name="l185"></a>
|
|
<a name="l186"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l187"></a>
|
|
<a name="l188"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET6:
|
|
<a name="l189"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: FIXME, IPV6 UDP BIND"</span><span class=cF0>);
|
|
<a name="l190"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l191"></a>
|
|
<a name="l192"></a> </span><span class=cF1>case</span><span class=cF0> AF_UNSPEC:
|
|
<a name="l193"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: Error, AF_UNSPEC UDP BIND -- found in bound tree"</span><span class=cF0>);
|
|
<a name="l194"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l195"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l196"></a> }
|
|
<a name="l197"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l198"></a> { </span><span class=cF2>// if we get no node back from port search, we didn't find it and are free to add a new node.</span><span class=cF0>
|
|
<a name="l199"></a> temp_node = UDPTreeNodeParamAdd(port, head); </span><span class=cF2>// add new node with port, return its *.</span><span class=cF0>
|
|
<a name="l200"></a> UDPTreeNodeQueueAdd(udp_socket, temp_node);
|
|
<a name="l201"></a> }
|
|
<a name="l202"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l203"></a> </span><span class=cF1>else</span><span class=cF0> </span><span class=cF2>// if no bound sockets, we init the tree as a new node</span><span class=cF0>
|
|
<a name="l204"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l205"></a> udp_globals.bound_socket_tree = head = UDPTreeNodeParamInit(port); </span><span class=cF2>//... shouuuld be in L.E .. ?</span><span class=cF0>
|
|
<a name="l206"></a> UDPTreeNodeQueueAdd(udp_socket, head); </span><span class=cF2>// add the udp socket to the port queue</span><span class=cF0>
|
|
<a name="l207"></a> </span><span class=cF2>// maybe more checks to do before this, dunno rn.</span><span class=cF0>
|
|
<a name="l208"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l209"></a>
|
|
<a name="l210"></a> udp_socket->bound_to = port;
|
|
<a name="l211"></a>
|
|
<a name="l212"></a> </span><span class=cF1>switch</span><span class=cF0> (udp_socket->socket->state)
|
|
<a name="l213"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l214"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_BIND_REQ: </span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>if BIND request success, set BOUND.</span><span class=cF0>
|
|
<a name="l215"></a> udp_socket->socket->state = SOCKET_STATE_BOUND;
|
|
<a name="l216"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l217"></a>
|
|
<a name="l218"></a> </span><span class=cF1>default</span><span class=cF0>:
|
|
<a name="l219"></a> NetErr(</span><span class=cF6>"UDP SOCKET BIND: Failed, Misconfigured Socket state-machine."</span><span class=cF0>);
|
|
<a name="l220"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l221"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l222"></a>
|
|
<a name="l223"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
|
|
<a name="l224"></a>}
|
|
<a name="l225"></a>
|
|
<a name="l226"></a></span><span class=cF9>I64</span><span class=cF0> UDPSocketClose(CUDPSocket *udp_socket)
|
|
<a name="l227"></a>{ </span><span class=cF2>// close, pop, and free the socket from the bound tree.</span><span class=cF0>
|
|
<a name="l228"></a> CUDPTreeNode *head = udp_globals.bound_socket_tree;
|
|
<a name="l229"></a> CUDPTreeNode *node;
|
|
<a name="l230"></a> CUDPTreeQueue *queue;
|
|
<a name="l231"></a> CUDPMessageQueue *message;
|
|
<a name="l232"></a>
|
|
<a name="l233"></a> SocketClose(udp_socket->socket); </span><span class=cF2>// TODO: testing on closing a socket while another task is using it</span><span class=cF0>
|
|
<a name="l234"></a> </span><span class=cF2>// after low-level socket close, even if protocol level socket fails close, it is now disabled (state is close request)</span><span class=cF0>
|
|
<a name="l235"></a>
|
|
<a name="l236"></a> node = UDPTreeNodeFind(udp_socket->bound_to, head);
|
|
<a name="l237"></a>
|
|
<a name="l238"></a> </span><span class=cF1>if</span><span class=cF0> (node)
|
|
<a name="l239"></a> queue = UDPTreeNodeQueueSocketFind(udp_socket, node);
|
|
<a name="l240"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l241"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l242"></a> </span><span class=cF5>Debug</span><span class=cF0>(</span><span class=cF6>"TODO: Didn't find node at socket during UDPSocketClose!\n"</span><span class=cF0>);
|
|
<a name="l243"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l244"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l245"></a>
|
|
<a name="l246"></a> </span><span class=cF1>if</span><span class=cF0> (queue)
|
|
<a name="l247"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l248"></a> UDPTreeNodeQueueSocketSinglePop(udp_socket, node);
|
|
<a name="l249"></a>
|
|
<a name="l250"></a> </span><span class=cF1>if</span><span class=cF0> (node->queue == node->queue->next)
|
|
<a name="l251"></a> { </span><span class=cF2>// if we popped the only queue on the node, remove the node.</span><span class=cF0>
|
|
<a name="l252"></a> </span><span class=cF1>if</span><span class=cF0> (node == head)
|
|
<a name="l253"></a> </span><span class=cF7>{</span><span class=cF0> </span><span class=cF2>// head is the global. if node is the global, change it and add branches.</span><span class=cF0>
|
|
<a name="l254"></a> </span><span class=cF1>if</span><span class=cF0> (node->left)
|
|
<a name="l255"></a> {
|
|
<a name="l256"></a> udp_globals.bound_socket_tree = head = node->left;
|
|
<a name="l257"></a> </span><span class=cF1>if</span><span class=cF0> (node->right)
|
|
<a name="l258"></a> UDPTreeNodeAdd(node->right, head);
|
|
<a name="l259"></a> }
|
|
<a name="l260"></a> </span><span class=cF1>else</span><span class=cF0> </span><span class=cF1>if</span><span class=cF0> (node->right)
|
|
<a name="l261"></a> udp_globals.bound_socket_tree = node->right;
|
|
<a name="l262"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l263"></a> udp_globals.bound_socket_tree = </span><span class=cF3>NULL</span><span class=cF0>;
|
|
<a name="l264"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l265"></a> </span><span class=cF1>else</span><span class=cF0> </span><span class=cF2>// if node is not the global, just pop it from the tree</span><span class=cF0>
|
|
<a name="l266"></a> UDPTreeNodeSinglePop(node->value, head);
|
|
<a name="l267"></a>
|
|
<a name="l268"></a> </span><span class=cF5>Free</span><span class=cF0>(node);
|
|
<a name="l269"></a> }
|
|
<a name="l270"></a>
|
|
<a name="l271"></a> </span><span class=cF5>Free</span><span class=cF0>(udp_socket->socket);
|
|
<a name="l272"></a>
|
|
<a name="l273"></a> message = udp_socket->receive_queue->next;
|
|
<a name="l274"></a> </span><span class=cF1>while</span><span class=cF0> (message != udp_socket->receive_queue)
|
|
<a name="l275"></a> {
|
|
<a name="l276"></a> NetWarn(</span><span class=cF6>"UDP SOCKET CLOSE: Freeing message @ 0x%X"</span><span class=cF0>, message);
|
|
<a name="l277"></a> </span><span class=cF5>Free</span><span class=cF0>(message->data);
|
|
<a name="l278"></a> </span><span class=cF5>QueueRemove</span><span class=cF0>(message);
|
|
<a name="l279"></a> </span><span class=cF5>Free</span><span class=cF0>(message);
|
|
<a name="l280"></a> message = udp_socket->receive_queue->next;
|
|
<a name="l281"></a> }
|
|
<a name="l282"></a>
|
|
<a name="l283"></a> NetWarn(</span><span class=cF6>"UDP SOCKET CLOSE: Freeing message queue & socket."</span><span class=cF0>);
|
|
<a name="l284"></a> </span><span class=cF5>Free</span><span class=cF0>(udp_socket->receive_queue);
|
|
<a name="l285"></a> </span><span class=cF5>Free</span><span class=cF0>(udp_socket);
|
|
<a name="l286"></a> </span><span class=cF5>Free</span><span class=cF0>(queue);
|
|
<a name="l287"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l288"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l289"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l290"></a> </span><span class=cF5>Debug</span><span class=cF0>(</span><span class=cF6>"TODO: Didn't find queue at socket during UDPSocketClose!\n"</span><span class=cF0>);
|
|
<a name="l291"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l292"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l293"></a>
|
|
<a name="l294"></a>
|
|
<a name="l295"></a>
|
|
<a name="l296"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
|
|
<a name="l297"></a>}
|
|
<a name="l298"></a>
|
|
<a name="l299"></a></span><span class=cF2>// UDPSocketConnect (TODO)</span><span class=cF0>
|
|
<a name="l300"></a>
|
|
<a name="l301"></a></span><span class=cF2>// UDPListen (Shrine just has no_warns, not implemented)</span><span class=cF0>
|
|
<a name="l302"></a>
|
|
<a name="l303"></a></span><span class=cF9>I64</span><span class=cF0> UDPSocketReceiveFrom(CUDPSocket *udp_socket, </span><span class=cF1>U8</span><span class=cF0> *buffer, </span><span class=cF9>I64</span><span class=cF0> len, CSocketAddressStorage *address_out)
|
|
<a name="l304"></a>{ </span><span class=cF2>// ommitted I64 addrlen, flags not implemented</span><span class=cF0>
|
|
<a name="l305"></a> CSocketAddressIPV4 *ipv4_socket_addr;
|
|
<a name="l306"></a> CSocketAddressIPV6 *ipv6_socket_addr;
|
|
<a name="l307"></a> CUDPMessageQueue *message;
|
|
<a name="l308"></a>
|
|
<a name="l309"></a> </span><span class=cF1>if</span><span class=cF0> (!SocketReceiveFrom</span><span class=cF7>(</span><span class=cF0>udp_socket->socket</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l310"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l311"></a> NetErr(</span><span class=cF6>"UDP SOCKET RECEIVE FROM: Socket state-machine must be in OPEN or BOUND state."</span><span class=cF0>);
|
|
<a name="l312"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l313"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l314"></a>
|
|
<a name="l315"></a> </span><span class=cF1>if</span><span class=cF0> (len < </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l316"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l317"></a> NetErr(</span><span class=cF6>"UDP SOCKET RECEIVE FROM: Invalid length requested."</span><span class=cF0>);
|
|
<a name="l318"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l319"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l320"></a>
|
|
<a name="l321"></a> </span><span class=cF1>if</span><span class=cF0> (udp_socket->receive_timeout_ms != </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l322"></a> udp_socket->receive_max_timeout = </span><span class=cFB>counts</span><span class=cF0>.jiffies + udp_socket->receive_timeout_ms * </span><span class=cF3>JIFFY_FREQ</span><span class=cF0> / </span><span class=cFE>1000</span><span class=cF0>;
|
|
<a name="l323"></a>
|
|
<a name="l324"></a> message = udp_socket->receive_queue;
|
|
<a name="l325"></a>
|
|
<a name="l326"></a> </span><span class=cF1>while</span><span class=cF0> (message == message->next)
|
|
<a name="l327"></a> </span><span class=cF7>{</span><span class=cF0> </span><span class=cF2>// wait for a message to be added to queue. head is non-message.</span><span class=cF0>
|
|
<a name="l328"></a> </span><span class=cF1>if</span><span class=cF0> (udp_socket->receive_timeout_ms == </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l329"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>; </span><span class=cF2>// if no timeout set and didn't see message, bail early</span><span class=cF0>
|
|
<a name="l330"></a>
|
|
<a name="l331"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cFB>counts</span><span class=cF0>.jiffies > udp_socket->receive_max_timeout)
|
|
<a name="l332"></a> {
|
|
<a name="l333"></a> NetErr(</span><span class=cF6>"UDP SOCKET RECEIVE FROM: Timed out."</span><span class=cF0>);
|
|
<a name="l334"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l335"></a> }
|
|
<a name="l336"></a>
|
|
<a name="l337"></a> </span><span class=cF5>Yield</span><span class=cF0>;
|
|
<a name="l338"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l339"></a>
|
|
<a name="l340"></a> NetLog(</span><span class=cF6>"UDP SOCKET RECEIVE FROM: Saw message in receive queue."</span><span class=cF0>);
|
|
<a name="l341"></a>
|
|
<a name="l342"></a> message = message->next;
|
|
<a name="l343"></a>
|
|
<a name="l344"></a> </span><span class=cF1>if</span><span class=cF0> (address_out)
|
|
<a name="l345"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l346"></a> </span><span class=cF1>switch</span><span class=cF0> (message->from_address.family)
|
|
<a name="l347"></a> {
|
|
<a name="l348"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET:
|
|
<a name="l349"></a> ipv4_socket_addr = address_out;
|
|
<a name="l350"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(ipv4_socket_addr, &message->from_address, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CSocketAddressIPV4</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l351"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l352"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET6:
|
|
<a name="l353"></a> ipv6_socket_addr = address_out;
|
|
<a name="l354"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(ipv6_socket_addr, &message->from_address, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CSocketAddressIPV6</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l355"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l356"></a> </span><span class=cF1>case</span><span class=cF0> AF_UNSPEC:
|
|
<a name="l357"></a> NetWarn(</span><span class=cF6>"UDP Receive From AF_UNSPEC UDPSocket Address Family\n"</span><span class=cF0>);
|
|
<a name="l358"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l359"></a> }
|
|
<a name="l360"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l361"></a>
|
|
<a name="l362"></a>
|
|
<a name="l363"></a> </span><span class=cF1>if</span><span class=cF0> (len >= message->data_length - message->received_length)
|
|
<a name="l364"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l365"></a> NetLog(</span><span class=cF6>"UDP SOCKET RECEIVE FROM: Requested length longer than data. Truncating."</span><span class=cF0>);
|
|
<a name="l366"></a> len = message->data_length - message->received_length;
|
|
<a name="l367"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(buffer, message->data + message->received_length, len);
|
|
<a name="l368"></a>
|
|
<a name="l369"></a> NetWarn(</span><span class=cF6>"UDP SOCKET RECEIVE FROM: Freeing message and removing from queue."</span><span class=cF0>);
|
|
<a name="l370"></a> </span><span class=cF2>// all data pulled, release message</span><span class=cF0>
|
|
<a name="l371"></a> </span><span class=cF5>QueueRemove</span><span class=cF0>(message);
|
|
<a name="l372"></a> </span><span class=cF5>Free</span><span class=cF0>(message->data);
|
|
<a name="l373"></a> </span><span class=cF5>Free</span><span class=cF0>(message);
|
|
<a name="l374"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l375"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l376"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l377"></a> NetLog(</span><span class=cF6>"UDP SOCKET RECEIVE FROM: Requsted length shorter than data at message."</span><span class=cF0>);
|
|
<a name="l378"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(buffer, message->data + message->received_length, len);
|
|
<a name="l379"></a> message->received_length += len;
|
|
<a name="l380"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l381"></a>
|
|
<a name="l382"></a> </span><span class=cF1>return</span><span class=cF0> len;
|
|
<a name="l383"></a>}
|
|
<a name="l384"></a>
|
|
<a name="l385"></a></span><span class=cF9>I64</span><span class=cF0> UDPSocketSendTo(CUDPSocket *udp_socket, </span><span class=cF1>U8</span><span class=cF0> *buffer, </span><span class=cF9>I64</span><span class=cF0> len, CSocketAddressStorage *destination_addr)
|
|
<a name="l386"></a>{
|
|
<a name="l387"></a> CSocketAddressStorage *dest;
|
|
<a name="l388"></a> CSocketAddressIPV4 *ipv4_destination;
|
|
<a name="l389"></a> CSocketAddressIPV6 *ipv6_destination;
|
|
<a name="l390"></a> </span><span class=cF1>U8</span><span class=cF0> *payload_frame;
|
|
<a name="l391"></a> </span><span class=cF9>I64</span><span class=cF0> de_index;
|
|
<a name="l392"></a>
|
|
<a name="l393"></a> </span><span class=cF1>if</span><span class=cF0> (!SocketSendTo</span><span class=cF7>(</span><span class=cF0>udp_socket->socket</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l394"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l395"></a> NetErr(</span><span class=cF6>"UDP SOCKET SEND TO: Socket state-machine must be in OPEN, BOUND or READY state."</span><span class=cF0>);
|
|
<a name="l396"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l397"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l398"></a>
|
|
<a name="l399"></a>
|
|
<a name="l400"></a> </span><span class=cF1>switch</span><span class=cF0> (udp_socket->socket->state)
|
|
<a name="l401"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l402"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_OPEN: </span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>Socket State machine must</span><span class=cF0>
|
|
<a name="l403"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_BOUND: </span><span class=cF2>// be in connected or bound state for send.</span><span class=cF0>
|
|
<a name="l404"></a> dest = &udp_socket->receive_address; </span><span class=cF2>// if already bound, ignore param destination</span><span class=cF0>
|
|
<a name="l405"></a> </span><span class=cF1>break</span><span class=cF0>; </span><span class=cF2>// and use stored address as send address.</span><span class=cF0>
|
|
<a name="l406"></a>
|
|
<a name="l407"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_READY: </span><span class=cF2>// If socket state is initial, attempt to bind it to destination.</span><span class=cF0>
|
|
<a name="l408"></a> NetLog(</span><span class=cF6>"UDP SOCKET SEND TO: Socket unbound. Attempting Bind at address parameter."</span><span class=cF0>);
|
|
<a name="l409"></a> UDPSocketBind(udp_socket, destination_addr);
|
|
<a name="l410"></a> dest = destination_addr;
|
|
<a name="l411"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l412"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l413"></a>
|
|
<a name="l414"></a> </span><span class=cF1>switch</span><span class=cF0> (dest->family)
|
|
<a name="l415"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l416"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET:
|
|
<a name="l417"></a> ipv4_destination = dest;
|
|
<a name="l418"></a>
|
|
<a name="l419"></a> de_index = UDPPacketAllocate(&payload_frame,
|
|
<a name="l420"></a> IPV4AddressGet</span><span class=cF7>()</span><span class=cF0>,
|
|
<a name="l421"></a> </span><span class=cFE>0</span><span class=cF0>,
|
|
<a name="l422"></a> </span><span class=cF5>EndianU32</span><span class=cF7>(</span><span class=cF0>ipv4_destination->address.address</span><span class=cF7>)</span><span class=cF0>,
|
|
<a name="l423"></a> </span><span class=cF5>EndianU16</span><span class=cF7>(</span><span class=cF0>ipv4_destination->port</span><span class=cF7>)</span><span class=cF0>,
|
|
<a name="l424"></a> len); </span><span class=cF2>// is get address parens redundant?</span><span class=cF0>
|
|
<a name="l425"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l426"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET6:
|
|
<a name="l427"></a> ipv6_destination = dest;
|
|
<a name="l428"></a> NetErr(</span><span class=cF6>"UDP SOCKET SEND TO: FIXME, IPV6 not implemented yet"</span><span class=cF0>);
|
|
<a name="l429"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l430"></a> </span><span class=cF1>case</span><span class=cF0> AF_UNSPEC:
|
|
<a name="l431"></a> NetErr(</span><span class=cF6>"UDP SOCKET SEND TO: Error, UDP Send To AF_UNSPEC\n"</span><span class=cF0>);
|
|
<a name="l432"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l433"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l434"></a>
|
|
<a name="l435"></a> </span><span class=cF1>if</span><span class=cF0> (de_index < </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l436"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l437"></a>
|
|
<a name="l438"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(payload_frame, buffer, len); </span><span class=cF2>// copies the data in buffer param into the udp payload frame</span><span class=cF0>
|
|
<a name="l439"></a>
|
|
<a name="l440"></a> UDPPacketFinish(de_index);
|
|
<a name="l441"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
|
|
<a name="l442"></a>}
|
|
<a name="l443"></a>
|
|
<a name="l444"></a></span><span class=cF2>// UDPSocketSetOpt ?</span><span class=cF0>
|
|
<a name="l445"></a>
|
|
<a name="l446"></a></span><span class=cF9>I64</span><span class=cF0> UDPHandler(CIPV4Packet *packet)
|
|
<a name="l447"></a>{ </span><span class=cF2>// TODO: Need either two UDP handlers for IPv4/IPv6, or logic changes if IPV6 is desired.</span><span class=cF0>
|
|
<a name="l448"></a> </span><span class=cF9>U16</span><span class=cF0> source_port;
|
|
<a name="l449"></a> </span><span class=cF9>U16</span><span class=cF0> destination_port;
|
|
<a name="l450"></a> </span><span class=cF1>U8</span><span class=cF0> *data;
|
|
<a name="l451"></a> </span><span class=cF9>I64</span><span class=cF0> length;
|
|
<a name="l452"></a> CUDPTreeNode *head = udp_globals.bound_socket_tree;
|
|
<a name="l453"></a> CUDPTreeNode *node;
|
|
<a name="l454"></a> CUDPTreeQueue *queue;
|
|
<a name="l455"></a> CUDPMessageQueue *messages_head;
|
|
<a name="l456"></a> CUDPMessageQueue *message;
|
|
<a name="l457"></a> CUDPSocket *udp_socket;
|
|
<a name="l458"></a> CSocketAddressIPV4 *ipv4_addr;
|
|
<a name="l459"></a>
|
|
<a name="l460"></a> NetLog(</span><span class=cF6>"UDP HANDLER: Beginning handling UDP Packet."</span><span class=cF0>);
|
|
<a name="l461"></a>
|
|
<a name="l462"></a> </span><span class=cF9>I64</span><span class=cF0> error = UDPPacketParse(&source_port, &destination_port, &data, &length, packet);
|
|
<a name="l463"></a>
|
|
<a name="l464"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>NetDebug("UDP HANDLER: Packet parsed, port to search in bound tree: 0x%0X (L.E...?)", destination_port);</span><span class=cF0>
|
|
<a name="l465"></a>
|
|
<a name="l466"></a> </span><span class=cF1>if</span><span class=cF0> (error < </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l467"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l468"></a> NetErr(</span><span class=cF6>"UDP HANDLER: Packet Parse Error."</span><span class=cF0>);
|
|
<a name="l469"></a> </span><span class=cF1>return</span><span class=cF0> error;
|
|
<a name="l470"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l471"></a>
|
|
<a name="l472"></a> </span><span class=cF1>if</span><span class=cF0> (head)
|
|
<a name="l473"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l474"></a> node = UDPTreeNodeFind(destination_port, head);
|
|
<a name="l475"></a> </span><span class=cF1>if</span><span class=cF0> (node)
|
|
<a name="l476"></a> {
|
|
<a name="l477"></a> queue = UDPTreeNodeQueueIPV4Find(packet->source_ip_address, node); </span><span class=cF2>// TODO: make sure bit order is correct here!!</span><span class=cF0>
|
|
<a name="l478"></a> </span><span class=cF1>if</span><span class=cF0> (queue)
|
|
<a name="l479"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l480"></a> udp_socket = queue->socket;
|
|
<a name="l481"></a> NetLog(</span><span class=cF6>"UDP HANDLER: Port and Address are in bound tree."</span><span class=cF0>);
|
|
<a name="l482"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l483"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l484"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l485"></a> NetWarn(</span><span class=cF6>"UDP HANDLER: Found node for port, but address is not in node queue."</span><span class=cF0>);
|
|
<a name="l486"></a> NetWarn(</span><span class=cF6>" UDP packet dest ip: 0x%0X."</span><span class=cF0>, packet->destination_ip_address);
|
|
<a name="l487"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l488"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l489"></a> }
|
|
<a name="l490"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l491"></a> {
|
|
<a name="l492"></a> NetWarn(</span><span class=cF6>"UDP HANDLER: Node for Port is not in tree."</span><span class=cF0>);
|
|
<a name="l493"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l494"></a> }
|
|
<a name="l495"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l496"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l497"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l498"></a> NetWarn(</span><span class=cF6>"UDP HANDLER: Socket tree is currently empty."</span><span class=cF0>);
|
|
<a name="l499"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l500"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l501"></a> </span><span class=cF2>// at this point, udp_socket is set, otherwise has already returned -1.</span><span class=cF0>
|
|
<a name="l502"></a>
|
|
<a name="l503"></a>
|
|
<a name="l504"></a> NetLog(</span><span class=cF6>"UDP HANDLER: Putting data payload into message queue."</span><span class=cF0>);
|
|
<a name="l505"></a>
|
|
<a name="l506"></a> messages_head = udp_socket->receive_queue;
|
|
<a name="l507"></a>
|
|
<a name="l508"></a> message = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPMessageQueue</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l509"></a> </span><span class=cF5>QueueInsertRev</span><span class=cF0>(message, messages_head);
|
|
<a name="l510"></a>
|
|
<a name="l511"></a> message->data = </span><span class=cF5>CAlloc</span><span class=cF0>(length);
|
|
<a name="l512"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(message->data, data, length);
|
|
<a name="l513"></a> message->data_length = length;
|
|
<a name="l514"></a>
|
|
<a name="l515"></a> ipv4_addr = &message->from_address;
|
|
<a name="l516"></a>
|
|
<a name="l517"></a> ipv4_addr->family = AF_INET;
|
|
<a name="l518"></a> ipv4_addr->port = </span><span class=cF5>EndianU16</span><span class=cF0>(source_port);
|
|
<a name="l519"></a> ipv4_addr->address.address = </span><span class=cF5>EndianU32</span><span class=cF0>(packet->source_ip_address);
|
|
<a name="l520"></a> NetLog(</span><span class=cF6>"UDP HANDLER: Copying packet source IP (BE) to FROM_ADDRESS of UDP Socket: %08X "</span><span class=cF0>, ipv4_addr->address.address);
|
|
<a name="l521"></a>
|
|
<a name="l522"></a> NetLog(</span><span class=cF6>"UDP HANDLER: Data payload succesfully placed in message queue."</span><span class=cF0>);
|
|
<a name="l523"></a>
|
|
<a name="l524"></a> </span><span class=cF1>return</span><span class=cF0> error;
|
|
<a name="l525"></a>}
|
|
<a name="l526"></a>
|
|
<a name="l527"></a></span><span class=cF2>// the socket functions just act on the socket state machine.</span><span class=cF0>
|
|
<a name="l528"></a></span><span class=cF2>// NetErr and return fail vals if socket FSM improperly used.</span><span class=cF0>
|
|
<a name="l529"></a></span><span class=cF2>// Careful with Free()'s.</span><span class=cF0>
|
|
<a name="l530"></a>
|
|
<a name="l531"></a>
|
|
<a name="l532"></a></span><span class=cF1>U0</span><span class=cF0> UDPTreeNodeRep(CUDPTreeNode *node)
|
|
<a name="l533"></a>{
|
|
<a name="l534"></a> CUDPTreeQueue *queue = node->queue->next;
|
|
<a name="l535"></a> CUDPSocket *socket;
|
|
<a name="l536"></a> CSocketAddressIPV4 *ipv4_addr;
|
|
<a name="l537"></a> CSocketAddressIPV6 *ipv6_addr;
|
|
<a name="l538"></a> </span><span class=cF1>U8</span><span class=cF0> *string;
|
|
<a name="l539"></a> CUDPMessageQueue *message;
|
|
<a name="l540"></a>
|
|
<a name="l541"></a> </span><span class=cF6>"Port $YELLOW$%d$FG$ (UDP Node @ $CYAN$0x%X$FG$):\n"</span><span class=cF0>, node->value, node;
|
|
<a name="l542"></a>
|
|
<a name="l543"></a> </span><span class=cF1>while</span><span class=cF0> (queue != node->queue)
|
|
<a name="l544"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l545"></a>
|
|
<a name="l546"></a> socket = queue->socket;
|
|
<a name="l547"></a>
|
|
<a name="l548"></a> </span><span class=cF1>switch</span><span class=cF0> (socket->receive_address.family)
|
|
<a name="l549"></a> {
|
|
<a name="l550"></a>
|
|
<a name="l551"></a> </span><span class=cF1>case</span><span class=cF0> AF_UNSPEC:
|
|
<a name="l552"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l553"></a>
|
|
<a name="l554"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET:
|
|
<a name="l555"></a> ipv4_addr = &socket->receive_address;
|
|
<a name="l556"></a> string = </span><span class=cF5>MStrPrint</span><span class=cF0>(</span><span class=cF6>"%d.%d.%d.%d"</span><span class=cF0>,
|
|
<a name="l557"></a> ipv4_addr->address.address.u8[</span><span class=cFE>3</span><span class=cF0>],
|
|
<a name="l558"></a> ipv4_addr->address.address.u8[</span><span class=cFE>2</span><span class=cF0>],
|
|
<a name="l559"></a> ipv4_addr->address.address.u8[</span><span class=cFE>1</span><span class=cF0>],
|
|
<a name="l560"></a> ipv4_addr->address.address.u8[</span><span class=cFE>0</span><span class=cF0>]); </span><span class=cF2>// todo: kludge, endianness...</span><span class=cF0>
|
|
<a name="l561"></a>
|
|
<a name="l562"></a> </span><span class=cF6>"</span><span class=cF0> </span><span class=cF6>$BROWN$%s$FG$ (UDP Tree Queue @ $CYAN$0x%X$FG$):\n"</span><span class=cF0>, string, queue;
|
|
<a name="l563"></a> </span><span class=cF5>Free</span><span class=cF0>(string);
|
|
<a name="l564"></a>
|
|
<a name="l565"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l566"></a>
|
|
<a name="l567"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET6:
|
|
<a name="l568"></a> ipv6_addr = &socket->receive_address;
|
|
<a name="l569"></a>
|
|
<a name="l570"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l571"></a>
|
|
<a name="l572"></a> </span><span class=cF1>default</span><span class=cF0>:
|
|
<a name="l573"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l574"></a>
|
|
<a name="l575"></a> }
|
|
<a name="l576"></a>
|
|
<a name="l577"></a> </span><span class=cF6>"</span><span class=cF0> </span><span class=cF6>Timeout: %dms\n"</span><span class=cF0>, socket->receive_timeout_ms;
|
|
<a name="l578"></a>
|
|
<a name="l579"></a> message = socket->receive_queue->next;
|
|
<a name="l580"></a> </span><span class=cF1>while</span><span class=cF0> (message != socket->receive_queue)
|
|
<a name="l581"></a> {
|
|
<a name="l582"></a> </span><span class=cF6>"</span><span class=cF0> </span><span class=cF6>Queued Message @ $CYAN$0x%X$FG$:\n"</span><span class=cF0>, message;
|
|
<a name="l583"></a> </span><span class=cF1>switch</span><span class=cF0> (message->from_address.family)
|
|
<a name="l584"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l585"></a> </span><span class=cF1>case</span><span class=cF0> AF_UNSPEC:
|
|
<a name="l586"></a> string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>"AF_UNSPEC"</span><span class=cF0>);
|
|
<a name="l587"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l588"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET:
|
|
<a name="l589"></a> ipv4_addr = &message->from_address;
|
|
<a name="l590"></a> string = NetworkToPresentation(ipv4_addr->family, &ipv4_addr->address);
|
|
<a name="l591"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l592"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET6:
|
|
<a name="l593"></a> string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>"IPV6"</span><span class=cF0>);
|
|
<a name="l594"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l595"></a> </span><span class=cF1>default</span><span class=cF0>:
|
|
<a name="l596"></a> string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>"INVALID"</span><span class=cF0>);
|
|
<a name="l597"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l598"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l599"></a> </span><span class=cF6>"</span><span class=cF0> </span><span class=cF6>From Address:</span><span class=cF0> </span><span class=cF6>$BROWN$%s$FG$\n"</span><span class=cF0>, string;
|
|
<a name="l600"></a> </span><span class=cF6>"</span><span class=cF0> </span><span class=cF6>Data length:</span><span class=cF0> </span><span class=cF6>%d\n"</span><span class=cF0>, message->data_length;
|
|
<a name="l601"></a> </span><span class=cF6>"</span><span class=cF0> </span><span class=cF6>Received data length:</span><span class=cF0> </span><span class=cF6>%d\n"</span><span class=cF0>, message->received_length;
|
|
<a name="l602"></a>
|
|
<a name="l603"></a> </span><span class=cF5>Free</span><span class=cF0>(string);
|
|
<a name="l604"></a>
|
|
<a name="l605"></a> message = message->next;
|
|
<a name="l606"></a> }
|
|
<a name="l607"></a>
|
|
<a name="l608"></a> queue = queue->next;
|
|
<a name="l609"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l610"></a>
|
|
<a name="l611"></a> </span><span class=cF6>"\n"</span><span class=cF0>;
|
|
<a name="l612"></a>}
|
|
<a name="l613"></a>
|
|
<a name="l614"></a></span><span class=cF1>U0</span><span class=cF0> UDPRep()
|
|
<a name="l615"></a>{
|
|
<a name="l616"></a> CUDPTreeNode *node = udp_globals.bound_socket_tree;
|
|
<a name="l617"></a> CUDPRepEntry *head;
|
|
<a name="l618"></a> CUDPRepEntry *entry;
|
|
<a name="l619"></a> CUDPRepEntry *temp_entry;
|
|
<a name="l620"></a>
|
|
<a name="l621"></a> </span><span class=cF6>"$LTBLUE$UDP Report:$FG$\n\n"</span><span class=cF0>;
|
|
<a name="l622"></a>
|
|
<a name="l623"></a> </span><span class=cF1>if</span><span class=cF0> (node)
|
|
<a name="l624"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l625"></a> head = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPRepEntry</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l626"></a> </span><span class=cF5>QueueInit</span><span class=cF0>(head); </span><span class=cF2>// no QueueRemove the head</span><span class=cF0>
|
|
<a name="l627"></a>
|
|
<a name="l628"></a> entry = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPRepEntry</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l629"></a> entry->node = node;
|
|
<a name="l630"></a> </span><span class=cF5>QueueInsert</span><span class=cF0>(entry, head);
|
|
<a name="l631"></a>
|
|
<a name="l632"></a> </span><span class=cF2>// perform depth-first-search while Entry Queue has nodes not fully visited.</span><span class=cF0>
|
|
<a name="l633"></a> </span><span class=cF1>while</span><span class=cF0> (entry != head)
|
|
<a name="l634"></a> {
|
|
<a name="l635"></a> </span><span class=cF1>if</span><span class=cF0> (entry->node->left)
|
|
<a name="l636"></a> </span><span class=cF7>{</span><span class=cF0> </span><span class=cF2>// if node has one, add an Entry for the left branch, continue loop.</span><span class=cF0>
|
|
<a name="l637"></a> temp_entry = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPRepEntry</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l638"></a> temp_entry->node = entry->node->left;
|
|
<a name="l639"></a> </span><span class=cF5>QueueInsertRev</span><span class=cF0>(temp_entry, head);
|
|
<a name="l640"></a>
|
|
<a name="l641"></a> </span><span class=cF2>// if left branch, but no right: toss early, now fully traveled.</span><span class=cF0>
|
|
<a name="l642"></a> </span><span class=cF1>if</span><span class=cF0> (!entry->node->right)
|
|
<a name="l643"></a> {
|
|
<a name="l644"></a> </span><span class=cF5>QueueRemove</span><span class=cF0>(entry);
|
|
<a name="l645"></a> UDPTreeNodeRep(entry->node);
|
|
<a name="l646"></a> </span><span class=cF5>Free</span><span class=cF0>(entry);
|
|
<a name="l647"></a> }
|
|
<a name="l648"></a>
|
|
<a name="l649"></a> entry = temp_entry;
|
|
<a name="l650"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l651"></a> </span><span class=cF1>else</span><span class=cF0> </span><span class=cF1>if</span><span class=cF0> (entry->node->right)
|
|
<a name="l652"></a> </span><span class=cF7>{</span><span class=cF0> </span><span class=cF2>// if no left, but right: add right to queue, pop Entry, Rep, set entry to right.</span><span class=cF0>
|
|
<a name="l653"></a> temp_entry = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPRepEntry</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l654"></a> temp_entry->node = entry->node->right;
|
|
<a name="l655"></a> </span><span class=cF5>QueueInsertRev</span><span class=cF0>(temp_entry, head);
|
|
<a name="l656"></a>
|
|
<a name="l657"></a> </span><span class=cF5>QueueRemove</span><span class=cF0>(entry);
|
|
<a name="l658"></a> UDPTreeNodeRep(entry->node);
|
|
<a name="l659"></a> </span><span class=cF5>Free</span><span class=cF0>(entry);
|
|
<a name="l660"></a>
|
|
<a name="l661"></a> entry = temp_entry;
|
|
<a name="l662"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l663"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l664"></a> </span><span class=cF7>{</span><span class=cF0> </span><span class=cF2>// pop Entry, Rep, if last Entry in Queue has right add it, pop & Rep travelled Entry, entry = right.</span><span class=cF0>
|
|
<a name="l665"></a> </span><span class=cF5>QueueRemove</span><span class=cF0>(entry);
|
|
<a name="l666"></a> UDPTreeNodeRep(entry->node);
|
|
<a name="l667"></a> </span><span class=cF5>Free</span><span class=cF0>(entry);
|
|
<a name="l668"></a>
|
|
<a name="l669"></a> </span><span class=cF1>if</span><span class=cF0> (head->last != head)
|
|
<a name="l670"></a> {
|
|
<a name="l671"></a> temp_entry = head->last;
|
|
<a name="l672"></a>
|
|
<a name="l673"></a> </span><span class=cF1>if</span><span class=cF0> (temp_entry->node->right)
|
|
<a name="l674"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l675"></a> entry = temp_entry;
|
|
<a name="l676"></a>
|
|
<a name="l677"></a> temp_entry = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CUDPRepEntry</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l678"></a> temp_entry->node = entry->node->right;
|
|
<a name="l679"></a> </span><span class=cF5>QueueInsertRev</span><span class=cF0>(temp_entry, head);
|
|
<a name="l680"></a>
|
|
<a name="l681"></a> </span><span class=cF5>QueueRemove</span><span class=cF0>(entry);
|
|
<a name="l682"></a> UDPTreeNodeRep(entry->node);
|
|
<a name="l683"></a> </span><span class=cF5>Free</span><span class=cF0>(entry);
|
|
<a name="l684"></a>
|
|
<a name="l685"></a> entry = temp_entry;
|
|
<a name="l686"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l687"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l688"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l689"></a> </span><span class=cF5>QueueRemove</span><span class=cF0>(temp_entry);
|
|
<a name="l690"></a> UDPTreeNodeRep(temp_entry->node);
|
|
<a name="l691"></a> </span><span class=cF5>Free</span><span class=cF0>(temp_entry);
|
|
<a name="l692"></a>
|
|
<a name="l693"></a> entry = head->last;
|
|
<a name="l694"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l695"></a> }
|
|
<a name="l696"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l697"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l698"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l699"></a> }
|
|
<a name="l700"></a>
|
|
<a name="l701"></a> </span><span class=cF5>Free</span><span class=cF0>(head);
|
|
<a name="l702"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l703"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l704"></a> </span><span class=cF6>"No UDP Sockets currently bound.\n\n"</span><span class=cF0>;
|
|
<a name="l705"></a>}
|
|
<a name="l706"></a>
|
|
<a name="l707"></a>UDPGlobalsInit;</span></pre></body>
|
|
</html>
|