mirror of
https://github.com/Brychan22/Simple-DHCP-Server.git
synced 2025-02-13 00:08:55 +13:00
Moved data structures to arrays to minimise utilised memory
Implemented UDPClient.Available() to avoid the blocking call to recvfrom (Closes #1)
This commit is contained in:
parent
99a7014825
commit
cf96c7dae7
@ -102,14 +102,14 @@ unsigned char DHCP::FindPosByMac(Net::MACAddress MAC, DHCP::DHCPEntry* entries,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::vector<unsigned char>> DHCP::ProcessDHCP(std::vector<unsigned char> rxBuffer) {
|
std::vector<std::vector<unsigned char>> DHCP::ProcessDHCP(unsigned char* rxBuffer, unsigned long bufferLength) {
|
||||||
unsigned char txBuffer[Net::TYPICAL_MTU] = {}; // ensure we have base zeros
|
unsigned char txBuffer[Net::TYPICAL_MTU] = {}; // ensure we have base zeros
|
||||||
u_long destAddress = ULLONG_MAX;
|
u_long destAddress = ULLONG_MAX;
|
||||||
if (rxBuffer[236] == DHCP::MAGIC_COOKIE[0] && rxBuffer[237] == DHCP::MAGIC_COOKIE[1] && rxBuffer[238] == DHCP::MAGIC_COOKIE[2] && rxBuffer[239] == DHCP::MAGIC_COOKIE[3]) {
|
if (rxBuffer[236] == DHCP::MAGIC_COOKIE[0] && rxBuffer[237] == DHCP::MAGIC_COOKIE[1] && rxBuffer[238] == DHCP::MAGIC_COOKIE[2] && rxBuffer[239] == DHCP::MAGIC_COOKIE[3]) {
|
||||||
unsigned int position = 240;
|
unsigned int position = 240;
|
||||||
// Find all options
|
// Find all options
|
||||||
std::vector<DHCP::DHCPOption> RXOptions;
|
std::vector<DHCP::DHCPOption> RXOptions;
|
||||||
while (rxBuffer[position] != 0xFF && position < Net::TYPICAL_MTU) {
|
while (rxBuffer[position] != 0xFF && position < bufferLength) {
|
||||||
unsigned char option = rxBuffer[position++];
|
unsigned char option = rxBuffer[position++];
|
||||||
unsigned char dataLength = rxBuffer[position++];
|
unsigned char dataLength = rxBuffer[position++];
|
||||||
DHCP::DHCPOption newOption = DHCP::DHCPOption();
|
DHCP::DHCPOption newOption = DHCP::DHCPOption();
|
||||||
@ -124,7 +124,7 @@ std::vector<std::vector<unsigned char>> DHCP::ProcessDHCP(std::vector<unsigned c
|
|||||||
}
|
}
|
||||||
// Check first option is DHCP
|
// Check first option is DHCP
|
||||||
if (RXOptions[0].option == 53) {
|
if (RXOptions[0].option == 53) {
|
||||||
Net::MACAddress clientMAC = Net::MACAddress((rxBuffer.data() + 28));
|
Net::MACAddress clientMAC = Net::MACAddress((rxBuffer + 28));
|
||||||
unsigned char leaseIndex = DHCP::FindPosByMac(clientMAC, DHCPEntries, maxLeases);
|
unsigned char leaseIndex = DHCP::FindPosByMac(clientMAC, DHCPEntries, maxLeases);
|
||||||
unsigned char clientIP;
|
unsigned char clientIP;
|
||||||
if (leaseIndex == 255) {
|
if (leaseIndex == 255) {
|
||||||
@ -146,7 +146,7 @@ std::vector<std::vector<unsigned char>> DHCP::ProcessDHCP(std::vector<unsigned c
|
|||||||
txBuffer[i] = rxBuffer[i];
|
txBuffer[i] = rxBuffer[i];
|
||||||
}
|
}
|
||||||
// Clear the rxBuffer, we have read all we need
|
// Clear the rxBuffer, we have read all we need
|
||||||
rxBuffer.clear();
|
delete[] rxBuffer;
|
||||||
|
|
||||||
txBuffer[16] = localAddress1;
|
txBuffer[16] = localAddress1;
|
||||||
txBuffer[17] = localAddress2;
|
txBuffer[17] = localAddress2;
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
|
|
||||||
std::vector<unsigned char> Generate_DHCP_Option(unsigned char option, unsigned char clientIP);
|
std::vector<unsigned char> Generate_DHCP_Option(unsigned char option, unsigned char clientIP);
|
||||||
|
|
||||||
std::vector<std::vector<unsigned char>> ProcessDHCP(std::vector<unsigned char> rxBuffer);
|
std::vector<std::vector<unsigned char>> ProcessDHCP(unsigned char* rxBuffer, unsigned long bufferLength);
|
||||||
|
|
||||||
DHCP(unsigned char* deviceAddress, unsigned char* subnetMask, unsigned char maxLeases, unsigned char leaseStart, unsigned int leaseTime, unsigned int* dnsServers, unsigned char dnsServerCount);
|
DHCP(unsigned char* deviceAddress, unsigned char* subnetMask, unsigned char maxLeases, unsigned char leaseStart, unsigned int leaseTime, unsigned int* dnsServers, unsigned char dnsServerCount);
|
||||||
~DHCP();
|
~DHCP();
|
||||||
|
@ -69,29 +69,33 @@ void Net::UdpClient::Socket::Bind(unsigned char* IP, unsigned short Port) {
|
|||||||
Bind(ep);
|
Bind(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> Net::UdpClient::Recieve(IPEndPoint* remote, unsigned short BufferSize) {
|
unsigned char* Net::UdpClient::Recieve(IPEndPoint* remote, unsigned short BufferSize) {
|
||||||
std::vector<unsigned char> recievedBytes;
|
|
||||||
char* buffer = new char[BufferSize];
|
char* buffer = new char[BufferSize];
|
||||||
// As recvfrom is blocking, this space must be reserved in memory pretty much at all times(typically 1480 bytes)
|
|
||||||
int remoteSize = sizeof(remote->socks);
|
int remoteSize = sizeof(remote->socks);
|
||||||
int r = recvfrom(Client.sock, buffer, BufferSize, 0, (SOCKADDR*)&remote->socks, &remoteSize);
|
int r = recvfrom(Client.sock, buffer, BufferSize, 0, (SOCKADDR*)&remote->socks, &remoteSize);
|
||||||
if (r > 0) {
|
return (unsigned char*)buffer;
|
||||||
recievedBytes.resize(r);
|
|
||||||
for (int i = 0; i < r; i++)
|
|
||||||
{
|
|
||||||
recievedBytes[i] = buffer[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] buffer;
|
|
||||||
return recievedBytes;
|
|
||||||
}
|
}
|
||||||
int Net::UdpClient::Send(std::vector<unsigned char> Datagram, int dGramSize, IPEndPoint ep) {
|
int Net::UdpClient::Send(char* Datagram, short DatagramSize, IPEndPoint ep) {
|
||||||
return sendto(Client.sock, (char*)Datagram.data(), dGramSize, 0, (SOCKADDR*)&ep.socks, sizeof(ep.socks));
|
return sendto(Client.sock, Datagram, DatagramSize, 0, (SOCKADDR*)&ep.socks, sizeof(ep.socks));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Net::UdpClient::Send(std::vector<unsigned char> Datagram, int dGramSize, std::vector<unsigned char> DestinationIP, int DestPort) {
|
int Net::UdpClient::Send(std::vector<unsigned char> Datagram, IPEndPoint ep) {
|
||||||
|
return Send((char*)Datagram.data(), Datagram.size(), ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Net::UdpClient::Send(std::vector<unsigned char> Datagram, std::vector<unsigned char> DestinationIP, int DestPort) {
|
||||||
IPEndPoint ep = IPEndPoint(DestinationIP.data(), (u_short)DestPort);
|
IPEndPoint ep = IPEndPoint(DestinationIP.data(), (u_short)DestPort);
|
||||||
return Send(Datagram, dGramSize, ep);
|
return Send(Datagram, ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Net::UdpClient::Available()
|
||||||
|
{
|
||||||
|
unsigned long availableBytes = 0;
|
||||||
|
int result = ioctlsocket(Client.sock, FIONREAD, &availableBytes);
|
||||||
|
if (result != 0) {
|
||||||
|
// Error occured
|
||||||
|
}
|
||||||
|
return availableBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Net::MACAddress::MACAddress(unsigned char c1, unsigned char c2, unsigned char c3, unsigned char c4, unsigned char c5, unsigned char c6)
|
Net::MACAddress::MACAddress(unsigned char c1, unsigned char c2, unsigned char c3, unsigned char c4, unsigned char c5, unsigned char c6)
|
||||||
|
@ -44,10 +44,23 @@ public:
|
|||||||
Socket Client;
|
Socket Client;
|
||||||
UdpClient();
|
UdpClient();
|
||||||
|
|
||||||
std::vector<unsigned char> Recieve(IPEndPoint* remote, unsigned short BufferSize = 1480);
|
unsigned char* Recieve(IPEndPoint* remote, unsigned short BufferSize = 1480);
|
||||||
int Send(std::vector<unsigned char> Datagram, int dGramSize, IPEndPoint ep);
|
int Send(char* Datagram, short DatagramSize, IPEndPoint ep);
|
||||||
|
|
||||||
int Send(std::vector<unsigned char> Datagram, int dGramSize, std::vector<unsigned char> DestinationIP, int DestPort);
|
int Send(std::vector<unsigned char> Datagram, IPEndPoint ep);
|
||||||
|
/// <summary>
|
||||||
|
/// Sends the data in Datagram to the destination IP address & port.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Datagram">A std::vector<u_char> of the data to be sent</param>
|
||||||
|
/// <param name="DestinationIP">The destination IP address (Little Endian)</param>
|
||||||
|
/// <param name="DestPort">The destination port (Little Endian)</param>
|
||||||
|
/// <returns>A value less than zero if an error occured</returns>
|
||||||
|
int Send(std::vector<unsigned char> Datagram, std::vector<unsigned char> DestinationIP, int DestPort);
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of bytes available, or zero if no connection is yet available
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
int Available();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MACAddress {
|
struct MACAddress {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include "Net.h"
|
#include "Net.h"
|
||||||
#include "DHCP.h"
|
#include "DHCP.h"
|
||||||
|
|
||||||
@ -18,17 +19,21 @@ int main()
|
|||||||
Net::UdpClient udpClient = Net::UdpClient();
|
Net::UdpClient udpClient = Net::UdpClient();
|
||||||
udpClient.Client.Bind(Net::IPEndPoint(new unsigned char[] {dhcp.localAddress1, dhcp.localAddress2, dhcp.localAddress3, dhcp.deviceIP}, 67));
|
udpClient.Client.Bind(Net::IPEndPoint(new unsigned char[] {dhcp.localAddress1, dhcp.localAddress2, dhcp.localAddress3, dhcp.deviceIP}, 67));
|
||||||
Net::IPEndPoint remote = Net::IPEndPoint(new unsigned char[] {0, 0, 0, 0}, 0);
|
Net::IPEndPoint remote = Net::IPEndPoint(new unsigned char[] {0, 0, 0, 0}, 0);
|
||||||
|
unsigned long waitingBytes = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
std::vector<unsigned char> buffer = udpClient.Recieve(&remote, 1480);
|
waitingBytes = udpClient.Available();
|
||||||
std::vector<std::vector<unsigned char>> result = dhcp.ProcessDHCP(buffer);
|
if (waitingBytes > 240) { // DHCP requires *at least* 240 bytes, the packet is malformed or incorrect if it is less
|
||||||
if (result.size() == 2) {
|
std::vector<std::vector<unsigned char>> result = dhcp.ProcessDHCP(udpClient.Recieve(&remote, waitingBytes), waitingBytes);
|
||||||
if (remote.Address.Equals(Net::IPAddress::Empty())) {
|
if (result.size() == 2) {
|
||||||
udpClient.Send(result[1], result[1].size(), result[0], 68);
|
if (remote.Address.Equals(Net::IPAddress::Empty())) {
|
||||||
}
|
udpClient.Send(result[1], result[0], 68);
|
||||||
else {
|
}
|
||||||
udpClient.Send(result[1], result[1].size(), remote);
|
else {
|
||||||
|
udpClient.Send(result[1], remote);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Artificial delay
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user