FreeNOS
UDPSocket.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Niek Linnenbank
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <FreeNOS/System.h>
19 #include <ByteOrder.h>
20 #include <Randomizer.h>
21 #include "Ethernet.h"
22 #include "UDP.h"
23 #include "UDPSocket.h"
24 
26  UDP *udp,
27  const ProcessID pid)
28  : NetworkSocket(inode, udp->getMaximumPacketSize(), pid)
29  , m_udp(udp)
30  , m_port(0)
31  , m_queue(udp->getMaximumPacketSize())
32 {
33 }
34 
36 {
37 }
38 
39 const u16 UDPSocket::getPort() const
40 {
41  return m_port;
42 }
43 
45  Size & size,
46  const Size offset)
47 {
48  DEBUG("");
49 
51  if (!pkt)
52  {
54  }
55 
56  IPV4::Header *ipHdr = (IPV4::Header *)(pkt->data + sizeof(Ethernet::Header));
57  UDP::Header *udpHdr = (UDP::Header *)(pkt->data + sizeof(Ethernet::Header) + sizeof(IPV4::Header));
59  Size payloadSize = pkt->size - sizeof(Ethernet::Header)
60  - sizeof(IPV4::Header)
61  - sizeof(UDP::Header);
62 
63  // Fill socket info
64  info.address = readBe32(&ipHdr->source);
65  info.port = readBe16(&udpHdr->sourcePort);
66  buffer.write(&info, sizeof(info));
67 
68  // Fill payload
69  Size sz = size > payloadSize ? payloadSize : size;
70  buffer.write(udpHdr+1, sz, sizeof(info));
71  m_queue.release(pkt);
72  size = sz + sizeof(info);
73 
74  return FileSystem::Success;
75 }
76 
78  Size & size,
79  const Size offset)
80 {
81  DEBUG("");
82 
83  // Read socket info and action
85  buffer.read(&dest, sizeof(dest));
86 
87  // Handle the socket operation
88  switch (dest.action)
89  {
91  {
92  MemoryBlock::copy(&m_info, &dest, sizeof(m_info));
93 
94  if (m_info.port == 0)
95  {
96  Randomizer rand;
97  m_info.port = rand.next() % 65535;
98  }
99 
100  DEBUG("addr =" << m_info.address << " port = " << m_info.port);
101  return m_udp->bind(this, m_info.port);
102  }
103 
105  return m_udp->sendPacket(&m_info, &dest, buffer, size - sizeof(dest), sizeof(dest));
106 
108  {
109  NetworkClient::PacketInfo packetInfo;
110  FileSystemMessage msg;
111  IOBuffer io;
112  Size packetOffset = 0;
113 
114  // Read the first packet info to find the base address for all packets.
115  //
116  // Note that it is assumed here that all packet buffers
117  // originate from the same base address and that each new packet
118  // starts after NetworkQueue::PayloadBufferSize bytes.
119  buffer.read(&packetInfo, sizeof(packetInfo), sizeof(dest));
120 
121  // Prepare dummy filesystem message for the I/O buffer
122  msg.from = buffer.getMessage()->from;
124  msg.buffer = (char *)packetInfo.address;
126  io.setMessage(&msg);
127 
128  // read the array of PacketInfo structs that describe
129  // all the packets that need to be transferred
130  for (Size i = sizeof(dest); i < size; i += sizeof(NetworkClient::PacketInfo))
131  {
132  buffer.read(&packetInfo, sizeof(packetInfo), i);
133  DEBUG("packet[" << ((i - sizeof(dest)) / sizeof(NetworkClient::PacketInfo)) <<
134  "] size = " << packetInfo.size << " offset = " << packetOffset);
135 
136  const FileSystem::Result r = m_udp->sendPacket(&m_info, &dest, io, packetInfo.size, packetOffset);
137  if (r != FileSystem::Success)
138  {
139  ERROR("failed to send packet: result = " << (int) r);
140  return r;
141  }
142 
143  packetOffset += NetworkQueue::PayloadBufferSize;
144  }
145 
146  return FileSystem::Success;
147  }
148 
149  default:
151  }
152 }
153 
154 bool UDPSocket::canRead() const
155 {
156  return m_queue.hasData();
157 }
158 
160 {
161  DEBUG("");
162 
164  if (!buf)
165  {
166  ERROR("udp socket queue full");
167  return FileSystem::IOError;
168  }
169 
170  buf->size = pkt->size;
171  MemoryBlock::copy(buf->data, pkt->data, pkt->size);
172  m_queue.push(buf);
173 
174  return FileSystem::Success;
175 }
UDPSocket::~UDPSocket
virtual ~UDPSocket()
Destructor.
Definition: UDPSocket.cpp:35
MemoryBlock::copy
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Definition: MemoryBlock.cpp:36
NetworkClient::PacketInfo
Describes a single packet.
Definition: NetworkClient.h:79
readBe32
const u32 readBe32(const void *data)
Read 32-bit big endian integer.
Definition: ByteOrder.h:384
UDP::Header
struct UDP::Header Header
Packet header format.
UDP::sendPacket
FileSystem::Result sendPacket(const NetworkClient::SocketInfo *src, const NetworkClient::SocketInfo *dest, IOBuffer &buffer, const Size size, const Size offset)
Send packet.
Definition: UDP.cpp:137
readBe16
const u16 readBe16(const void *data)
Read 16-bit big endian integer.
Definition: ByteOrder.h:398
FileSystemMessage::buffer
char * buffer
Points to a buffer for I/O.
Definition: FileSystemMessage.h:41
IOBuffer::getMessage
const FileSystemMessage * getMessage() const
Get filesystem message.
Definition: IOBuffer.cpp:120
NetworkQueue::pop
Packet * pop()
Retrieve packet with data.
Definition: NetworkQueue.cpp:98
UDP.h
NetworkClient::SocketInfo::address
IPV4::Address address
Definition: NetworkClient.h:67
Ethernet.h
FileSystem::WriteFile
@ WriteFile
Definition: FileSystem.h:40
PAGESIZE
#define PAGESIZE
ARM uses 4K pages.
Definition: ARMConstant.h:97
NetworkQueue::MaxPackets
static const Size MaxPackets
Maximum number of packets available.
Definition: NetworkQueue.h:45
IPV4::Header::source
Address source
Definition: IPV4.h:76
UDP
User Datagram Protocol (UDP)
Definition: UDP.h:41
ProcessID
u32 ProcessID
Process Identification Number.
Definition: Types.h:140
NetworkQueue::Packet::data
u8 * data
Definition: NetworkQueue.h:53
NetworkQueue::release
void release(Packet *packet)
Put unused packet back.
Definition: NetworkQueue.cpp:87
FileSystemMessage
FileSystem IPC message.
Definition: FileSystemMessage.h:37
IPV4::Header
struct IPV4::Header Header
IP network packet header.
FileSystem::IOError
@ IOError
Definition: FileSystem.h:58
NetworkQueue::Packet::size
Size size
Definition: NetworkQueue.h:52
NetworkQueue::hasData
bool hasData() const
Check if data packets are available.
Definition: NetworkQueue.cpp:112
FileSystem::Success
@ Success
Definition: FileSystem.h:54
NetworkClient::PacketInfo::address
Address address
Definition: NetworkClient.h:81
NetworkClient::SocketInfo::port
u16 port
Definition: NetworkClient.h:68
NetworkQueue::get
Packet * get()
Get unused packet.
Definition: NetworkQueue.cpp:72
UDPSocket::process
virtual FileSystem::Result process(const NetworkQueue::Packet *pkt)
Process incoming network packet.
Definition: UDPSocket.cpp:159
FileSystem::NotSupported
@ NotSupported
Definition: FileSystem.h:61
IOBuffer::setMessage
void setMessage(const FileSystemMessage *msg)
Set filesystem message.
Definition: IOBuffer.cpp:63
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
NetworkQueue::push
void push(Packet *packet)
Enqueue packet with data.
Definition: NetworkQueue.cpp:93
Randomizer.h
UDPSocket::m_port
u16 m_port
Local port.
Definition: UDPSocket.h:117
NetworkSocket::m_info
NetworkClient::SocketInfo m_info
Socket connection.
Definition: NetworkSocket.h:85
u16
unsigned short u16
Unsigned 16-bit number.
Definition: Types.h:56
UDP::Header
Packet header format.
Definition: UDP.h:52
IOBuffer
Abstract Input/Output buffer.
Definition: IOBuffer.h:37
Randomizer::next
ulong next()
Get next randomized value.
Definition: Randomizer.cpp:27
ByteOrder.h
u32
unsigned int u32
Unsigned 32-bit number.
Definition: Types.h:53
UDP::Header::sourcePort
u16 sourcePort
Definition: UDP.h:54
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
UDP::bind
FileSystem::Result bind(UDPSocket *sock, const u16 port)
Bind to UDP port.
Definition: UDP.cpp:188
UDPSocket::write
virtual FileSystem::Result write(IOBuffer &buffer, Size &size, const Size offset)
Send UDP data.
Definition: UDPSocket.cpp:77
Ethernet::Header
Ethernet network packet header.
Definition: Ethernet.h:64
NetworkClient::SendSingle
@ SendSingle
Definition: NetworkClient.h:55
Randomizer
Produces random integers using the Linear congruential generator algorithm.
Definition: Randomizer.h:36
NetworkSocket
Network socket represents a single logical connection on a protocol.
Definition: NetworkSocket.h:37
IPV4::Header
IP network packet header.
Definition: IPV4.h:66
UDPSocket::UDPSocket
UDPSocket(const u32 inode, UDP *udp, const ProcessID pid)
Constructor.
Definition: UDPSocket.cpp:25
UDPSocket::read
virtual FileSystem::Result read(IOBuffer &buffer, Size &size, const Size offset)
Receive UDP data.
Definition: UDPSocket.cpp:44
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
NetworkClient::SocketInfo
Socket information.
Definition: NetworkClient.h:65
FileSystem::Result
Result
Result code for filesystem Actions.
Definition: FileSystem.h:52
FileSystem::RetryAgain
@ RetryAgain
Definition: FileSystem.h:57
UDPSocket::m_queue
NetworkQueue m_queue
Incoming packet queue.
Definition: UDPSocket.h:120
ChannelMessage::from
ProcessID from
Source process of the message.
Definition: ChannelMessage.h:54
FileSystemMessage::action
FileSystem::Action action
Action to perform.
Definition: FileSystemMessage.h:39
NetworkQueue::PayloadBufferSize
static const Size PayloadBufferSize
Size of payload memory buffer.
Definition: NetworkQueue.h:42
UDPSocket::canRead
virtual bool canRead() const
Check if the File has data ready for reading.
Definition: UDPSocket.cpp:154
IOBuffer::read
FileSystem::Result read(void *buffer, const Size size, const Size offset=ZERO)
Read bytes from the I/O buffer.
Definition: IOBuffer.cpp:156
Ethernet::Header
struct Ethernet::Header Header
Ethernet network packet header.
IOBuffer::write
FileSystem::Result write(const void *buffer, const Size size, const Size offset=ZERO)
Write bytes to the I/O buffer.
Definition: IOBuffer.cpp:180
NetworkQueue::Packet
Represents a network packet.
Definition: NetworkQueue.h:50
UDPSocket::getPort
const u16 getPort() const
Get associated local port.
Definition: UDPSocket.cpp:39
UDPSocket.h
UDPSocket::m_udp
UDP * m_udp
UDP protocol instance.
Definition: UDPSocket.h:114
NetworkClient::SocketInfo::action
u16 action
Definition: NetworkClient.h:69
NetworkClient::SendMultiple
@ SendMultiple
Definition: NetworkClient.h:56
FileSystemMessage::size
Size size
Size of the buffer.
Definition: FileSystemMessage.h:42
NetworkClient::PacketInfo::size
Size size
Definition: NetworkClient.h:82
NetworkClient::Listen
@ Listen
Definition: NetworkClient.h:54