void UDP_SendPacketTo(tUDPChannel *Channel, int AddrType, const void *Address, Uint16 Port, const void *Data, size_t Length);
// --- Client Channels
tVFS_Node *UDP_Channel_Init(tInterface *Interface);
-Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint64 UDP_Channel_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer);
+size_t UDP_Channel_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags);
+size_t UDP_Channel_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags);
int UDP_Channel_IOCtl(tVFS_Node *Node, int ID, void *Data);
void UDP_Channel_Close(tVFS_Node *Node);
// --- Helpers
{
tUDPHeader *hdr = Buffer;
- Log_Debug("UDP", "hdr->SourcePort = %i", ntohs(hdr->SourcePort));
- Log_Debug("UDP", "hdr->DestPort = %i", ntohs(hdr->DestPort));
- Log_Debug("UDP", "hdr->Length = %i", ntohs(hdr->Length));
- Log_Debug("UDP", "hdr->Checksum = 0x%x", ntohs(hdr->Checksum));
+ Log_Debug("UDP", "%i bytes :%i->:%i (Cksum 0x%04x)",
+ ntohs(hdr->Length), ntohs(hdr->SourcePort), ntohs(hdr->Length), ntohs(hdr->Checksum));
// Check registered connections
Mutex_Acquire(&glUDP_Channels);
*/
void UDP_SendPacketTo(tUDPChannel *Channel, int AddrType, const void *Address, Uint16 Port, const void *Data, size_t Length)
{
- tUDPHeader *hdr;
+ tUDPHeader hdr;
if(Channel->Interface && Channel->Interface->Type != AddrType) return ;
{
case 4:
// Create the packet
- hdr = malloc(sizeof(tUDPHeader)+Length);
- hdr->SourcePort = htons( Channel->LocalPort );
- hdr->DestPort = htons( Port );
- hdr->Length = htons( sizeof(tUDPHeader) + Length );
- hdr->Checksum = 0; // Checksum can be zero on IPv4
- memcpy(hdr->Data, Data, Length);
+ hdr.SourcePort = htons( Channel->LocalPort );
+ hdr.DestPort = htons( Port );
+ hdr.Length = htons( sizeof(tUDPHeader) + Length );
+ hdr.Checksum = 0; // Checksum can be zero on IPv4
// Pass on the the IPv4 Layer
+ tIPStackBuffer *buffer = IPStack_Buffer_CreateBuffer(2 + IPV4_BUFFERS);
+ IPStack_Buffer_AppendSubBuffer(buffer, Length, 0, Data, NULL, NULL);
+ IPStack_Buffer_AppendSubBuffer(buffer, sizeof(hdr), 0, &hdr, NULL, NULL);
// TODO: What if Channel->Interface is NULL here?
- IPv4_SendPacket(Channel->Interface, *(tIPv4*)Address, IP4PROT_UDP, 0, sizeof(tUDPHeader)+Length, hdr);
- // Free allocated packet
- free(hdr);
+ IPv4_SendPacket(Channel->Interface, *(tIPv4*)Address, IP4PROT_UDP, 0, buffer);
+ IPStack_Buffer_DestroyBuffer(buffer);
break;
}
}
/**
* \brief Read from the channel file (wait for a packet)
*/
-Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+size_t UDP_Channel_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags)
{
tUDPChannel *chan = Node->ImplPtr;
tUDPPacket *pack;
for(;;)
{
- VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "UDP_Channel_Read");
+ tTime timeout_z = 0, *timeout = (Flags & VFS_IOFLAG_NOBLOCK) ? &timeout_z : NULL;
+ int rv = VFS_SelectNode(Node, VFS_SELECT_READ, timeout, "UDP_Channel_Read");
+ if( rv ) {
+ errno = (Flags & VFS_IOFLAG_NOBLOCK) ? EWOULDBLOCK : EINTR;
+ }
SHORTLOCK(&chan->lQueue);
if(chan->Queue == NULL) {
SHORTREL(&chan->lQueue);
/**
* \brief Write to the channel file (send a packet)
*/
-Uint64 UDP_Channel_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer)
+size_t UDP_Channel_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)
{
tUDPChannel *chan = Node->ImplPtr;
const tUDPEndpoint *ep;
const void *data;
int ofs;
- if(chan->LocalPort == 0) return 0;
+
+ if(chan->LocalPort == 0) {
+ Log_Notice("UDP", "Write to channel %p with zero local port", chan);
+ return 0;
+ }
ep = Buffer;
ofs = 2 + 2 + IPStack_GetAddressSize( ep->AddrType );
UDP_SendPacketTo(chan, ep->AddrType, &ep->Addr, ep->Port, data, (size_t)Length - ofs);
- return 0;
+ return Length;
}
/**