mirror of
https://github.com/norohind/hans.git
synced 2025-05-29 14:49:35 +03:00
finished polling system change
This commit is contained in:
parent
63209c41df
commit
e8d388515f
2
Makefile
2
Makefile
@ -58,7 +58,7 @@ server.o: server.cpp server.h client.h utility.h config.h worker.h auth.h time.h
|
||||
auth.o: auth.cpp auth.h sha1.h utility.h
|
||||
g++ -c auth.cpp $(CFLAGS)
|
||||
|
||||
worker.o: worker.cpp worker.h tun.h exception.h time.h echo.h tun_dev.h
|
||||
worker.o: worker.cpp worker.h tun.h exception.h time.h echo.h tun_dev.h config.h
|
||||
g++ -c worker.cpp $(CFLAGS)
|
||||
|
||||
time.o: time.cpp time.h
|
||||
|
26
client.cpp
26
client.cpp
@ -31,12 +31,16 @@ using namespace std;
|
||||
|
||||
const Worker::TunnelHeader::Magic Client::magic("9967");
|
||||
|
||||
Client::Client(int tunnelMtu, const char *deviceName, uint32_t serverIp, int maxPolls, const char *passphrase, uid_t uid, gid_t gid)
|
||||
Client::Client(int tunnelMtu, const char *deviceName, uint32_t serverIp, int maxPolls,
|
||||
const char *passphrase, uid_t uid, gid_t gid, bool changeEchoId, bool changeEchoSeq)
|
||||
: Worker(tunnelMtu, deviceName, false, uid, gid), auth(passphrase)
|
||||
{
|
||||
this->serverIp = serverIp;
|
||||
this->maxPolls = maxPolls;
|
||||
this->nextEchoId = Utility::rand();
|
||||
this->changeEchoId = changeEchoId;
|
||||
this->changeEchoSeq = changeEchoSeq;
|
||||
this->nextEchoSequence = Utility::rand();
|
||||
|
||||
state = STATE_CLOSED;
|
||||
}
|
||||
@ -48,7 +52,7 @@ Client::~Client()
|
||||
|
||||
void Client::sendConnectionRequest()
|
||||
{
|
||||
Server::ClientConnectData *connectData = (Server::ClientConnectData *)payloadBuffer();
|
||||
Server::ClientConnectData *connectData = (Server::ClientConnectData *)echoSendPayloadBuffer();
|
||||
connectData->maxPolls = maxPolls;
|
||||
|
||||
syslog(LOG_DEBUG, "sending connection request");
|
||||
@ -70,11 +74,11 @@ void Client::sendChallengeResponse(int dataLength)
|
||||
|
||||
vector<char> challenge;
|
||||
challenge.resize(dataLength);
|
||||
memcpy(&challenge[0], payloadBuffer(), dataLength);
|
||||
memcpy(&challenge[0], echoReceivePayloadBuffer(), dataLength);
|
||||
|
||||
Auth::Response response = auth.getResponse(challenge);
|
||||
|
||||
memcpy(payloadBuffer(), (char *)&response, sizeof(Auth::Response));
|
||||
memcpy(echoSendPayloadBuffer(), (char *)&response, sizeof(Auth::Response));
|
||||
sendEchoToServer(TunnelHeader::TYPE_CHALLENGE_RESPONSE, sizeof(Auth::Response));
|
||||
|
||||
setTimeout(5000);
|
||||
@ -123,7 +127,7 @@ bool Client::handleEchoData(const TunnelHeader &header, int dataLength, uint32_t
|
||||
|
||||
syslog(LOG_INFO, "connection established");
|
||||
|
||||
tun->setIp(ntohl(*(uint32_t *)payloadBuffer()));
|
||||
tun->setIp(ntohl(*(uint32_t *)echoReceivePayloadBuffer()));
|
||||
state = STATE_ESTABLISHED;
|
||||
|
||||
dropPrivileges();
|
||||
@ -157,10 +161,12 @@ void Client::sendEchoToServer(int type, int dataLength)
|
||||
if (maxPolls == 0 && state == STATE_ESTABLISHED)
|
||||
setTimeout(KEEP_ALIVE_INTERVAL);
|
||||
|
||||
sendEcho(magic, type, dataLength, serverIp, false, nextEchoId, 0);
|
||||
sendEcho(magic, type, dataLength, serverIp, false, nextEchoId, nextEchoSequence);
|
||||
|
||||
if (maxPolls > 0)
|
||||
if (changeEchoId)
|
||||
nextEchoId = nextEchoId + 38543; // some random prime
|
||||
if (changeEchoSeq)
|
||||
nextEchoSequence = nextEchoSequence + 38543; // some random prime
|
||||
}
|
||||
|
||||
void Client::startPolling()
|
||||
@ -179,6 +185,12 @@ void Client::startPolling()
|
||||
|
||||
void Client::handleDataFromServer(int dataLength)
|
||||
{
|
||||
if (dataLength == 0)
|
||||
{
|
||||
syslog(LOG_WARNING, "received empty data packet");
|
||||
return;
|
||||
}
|
||||
|
||||
sendToTun(dataLength);
|
||||
|
||||
if (maxPolls != 0)
|
||||
|
6
client.h
6
client.h
@ -28,7 +28,8 @@
|
||||
class Client : public Worker
|
||||
{
|
||||
public:
|
||||
Client(int tunnelMtu, const char *deviceName, uint32_t serverIp, int maxPolls, const char *passphrase, uid_t uid, gid_t gid);
|
||||
Client(int tunnelMtu, const char *deviceName, uint32_t serverIp, int maxPolls,
|
||||
const char *passphrase, uid_t uid, gid_t gid, bool changeEchoId, bool changeEchoSeq);
|
||||
virtual ~Client();
|
||||
|
||||
virtual void run();
|
||||
@ -62,7 +63,10 @@ protected:
|
||||
int maxPolls;
|
||||
int pollTimeoutNr;
|
||||
|
||||
bool changeEchoId, changeEchoSeq;
|
||||
|
||||
uint16_t nextEchoId;
|
||||
uint16_t nextEchoSequence;
|
||||
|
||||
State state;
|
||||
};
|
||||
|
3
config.h
3
config.h
@ -23,3 +23,6 @@
|
||||
#define POLL_INTERVAL 2000
|
||||
|
||||
#define CHALLENGE_SIZE 20
|
||||
|
||||
//#define DEBUG_ONLY(a) a
|
||||
#define DEBUG_ONLY(a)
|
||||
|
17
echo.cpp
17
echo.cpp
@ -31,13 +31,16 @@ Echo::Echo(int maxPayloadSize)
|
||||
throw Exception("creating icmp socket", true);
|
||||
|
||||
bufferSize = maxPayloadSize + headerSize();
|
||||
buffer = new char[bufferSize];
|
||||
sendBuffer = new char[bufferSize];
|
||||
receiveBuffer = new char[bufferSize];
|
||||
}
|
||||
|
||||
Echo::~Echo()
|
||||
{
|
||||
close(fd);
|
||||
delete[] buffer;
|
||||
|
||||
delete[] sendBuffer;
|
||||
delete[] receiveBuffer;
|
||||
}
|
||||
|
||||
int Echo::headerSize()
|
||||
@ -54,15 +57,15 @@ void Echo::send(int payloadLength, uint32_t realIp, bool reply, uint16_t id, uin
|
||||
if (payloadLength + sizeof(IpHeader) + sizeof(EchoHeader) > bufferSize)
|
||||
throw Exception("packet too big");
|
||||
|
||||
EchoHeader *header = (EchoHeader *)(buffer + sizeof(IpHeader));
|
||||
EchoHeader *header = (EchoHeader *)(sendBuffer + sizeof(IpHeader));
|
||||
header->type = reply ? 0: 8;
|
||||
header->code = 0;
|
||||
header->id = htons(id);
|
||||
header->seq = htons(seq);
|
||||
header->chksum = 0;
|
||||
header->chksum = icmpChecksum(buffer + sizeof(IpHeader), payloadLength + sizeof(EchoHeader));
|
||||
header->chksum = icmpChecksum(sendBuffer + sizeof(IpHeader), payloadLength + sizeof(EchoHeader));
|
||||
|
||||
int result = sendto(fd, buffer + sizeof(IpHeader), payloadLength + sizeof(EchoHeader), 0, (struct sockaddr *)&target, sizeof(struct sockaddr_in));
|
||||
int result = sendto(fd, sendBuffer + sizeof(IpHeader), payloadLength + sizeof(EchoHeader), 0, (struct sockaddr *)&target, sizeof(struct sockaddr_in));
|
||||
if (result == -1)
|
||||
throw Exception("sendto", true);
|
||||
}
|
||||
@ -72,14 +75,14 @@ int Echo::receive(uint32_t &realIp, bool &reply, uint16_t &id, uint16_t &seq)
|
||||
struct sockaddr_in source;
|
||||
int source_addr_len = sizeof(struct sockaddr_in);
|
||||
|
||||
int dataLength = recvfrom(fd, buffer, bufferSize, 0, (struct sockaddr *)&source, (socklen_t *)&source_addr_len);
|
||||
int dataLength = recvfrom(fd, receiveBuffer, bufferSize, 0, (struct sockaddr *)&source, (socklen_t *)&source_addr_len);
|
||||
if (dataLength == -1)
|
||||
throw Exception("recvfrom", true);
|
||||
|
||||
if (dataLength < sizeof(IpHeader) + sizeof(EchoHeader))
|
||||
return -1;
|
||||
|
||||
EchoHeader *header = (EchoHeader *)(buffer + sizeof(IpHeader));
|
||||
EchoHeader *header = (EchoHeader *)(receiveBuffer + sizeof(IpHeader));
|
||||
if ((header->type != 0 && header->type != 8) || header->code != 0)
|
||||
return -1;
|
||||
|
||||
|
5
echo.h
5
echo.h
@ -34,7 +34,8 @@ public:
|
||||
void send(int payloadLength, uint32_t realIp, bool reply, uint16_t id, uint16_t seq);
|
||||
int receive(uint32_t &realIp, bool &reply, uint16_t &id, uint16_t &seq);
|
||||
|
||||
char *payloadBuffer() { return buffer + headerSize(); }
|
||||
char *sendPayloadBuffer() { return sendBuffer + headerSize(); }
|
||||
char *receivePayloadBuffer() { return receiveBuffer + headerSize(); }
|
||||
|
||||
static int headerSize();
|
||||
protected:
|
||||
@ -51,7 +52,7 @@ protected:
|
||||
|
||||
int fd;
|
||||
int bufferSize;
|
||||
char *buffer;
|
||||
char *sendBuffer, *receiveBuffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
32
main.cpp
32
main.cpp
@ -43,20 +43,17 @@ void usage()
|
||||
" -c server Connect to a server.\n"
|
||||
" -f Run in foreground.\n"
|
||||
" -r Respond to ordinary pings. Only in server mode.\n"
|
||||
" Use this when you disable echo replies of your operating system, which is a good idea.\n"
|
||||
" -p password Use a password.\n"
|
||||
" -u username Set the user under which the program should run.\n"
|
||||
" -d device Use the given tun device.\n"
|
||||
" -m mtu Use this mtu to calculate the tunnel mtu.\n"
|
||||
" The generated ICMP packets will not be bigger than this value.\n"
|
||||
" Has to be the same on client and server.\n"
|
||||
" In most cases you don't want to set this. Defaults to 1500.\n"
|
||||
" Has to be the same on client and server. Defaults to 1500.\n"
|
||||
" -w polls Number of echo requests the client sends to the server for polling.\n"
|
||||
" If your network allows unlimited echo replies set this to 0 to disable polling.\n"
|
||||
" The default value of 10 is regarded as pretty high.\n"
|
||||
" Set this to a lower value if you experience packet loss through the tunnel.\n"
|
||||
" Set this to 1 in extreme cases, when your network allows only one echo reply per request.\n"
|
||||
" A low value will decrease the performance of the tunnel.\n");
|
||||
" 0 disables polling. Defaults to 10.\n"
|
||||
" -i Change the echo id for every packet.\n"
|
||||
" -q Change the echo sequence number for every packet.\n"
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -74,11 +71,13 @@ int main(int argc, char *argv[])
|
||||
bool answerPing = false;
|
||||
uid_t uid = 0;
|
||||
gid_t gid = 0;
|
||||
|
||||
bool changeEchoId = false;
|
||||
bool changeEchoSeq = false;
|
||||
|
||||
openlog(argv[0], LOG_PERROR, LOG_DAEMON);
|
||||
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, "fru:d:p:s:c:m:w:")) != -1)
|
||||
while ((c = getopt(argc, argv, "fru:d:p:s:c:m:w:qi")) != -1)
|
||||
{
|
||||
switch(c) {
|
||||
case 'f':
|
||||
@ -101,6 +100,8 @@ int main(int argc, char *argv[])
|
||||
case 's':
|
||||
isServer = true;
|
||||
network = ntohl(inet_addr(optarg));
|
||||
if (network == INADDR_NONE)
|
||||
printf("invalid network\n");
|
||||
break;
|
||||
case 'm':
|
||||
mtu = atoi(optarg);
|
||||
@ -111,6 +112,12 @@ int main(int argc, char *argv[])
|
||||
case 'r':
|
||||
answerPing = true;
|
||||
break;
|
||||
case 'q':
|
||||
changeEchoSeq = true;
|
||||
break;
|
||||
case 'i':
|
||||
changeEchoId = true;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return 1;
|
||||
@ -128,7 +135,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if ((isClient == isServer) ||
|
||||
(isServer && network == INADDR_NONE) ||
|
||||
(maxPolls < 0 || maxPolls > 255))
|
||||
(maxPolls < 0 || maxPolls > 255) ||
|
||||
(isServer && (changeEchoSeq || changeEchoId)))
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
@ -173,7 +181,7 @@ int main(int argc, char *argv[])
|
||||
serverIp = *(uint32_t *)he->h_addr;
|
||||
}
|
||||
|
||||
worker = new Client(mtu, device, ntohl(serverIp), maxPolls, password, uid, gid);
|
||||
worker = new Client(mtu, device, ntohl(serverIp), maxPolls, password, uid, gid, changeEchoId, changeEchoSeq);
|
||||
}
|
||||
|
||||
if (!foreground)
|
||||
|
46
server.cpp
46
server.cpp
@ -28,9 +28,6 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
//#define DEBUG_ONLY(a) a
|
||||
#define DEBUG_ONLY(a)
|
||||
|
||||
const Worker::TunnelHeader::Magic Server::magic("9973");
|
||||
|
||||
Server::Server(int tunnelMtu, const char *deviceName, const char *passphrase, uint32_t network, bool answerEcho, uid_t uid, gid_t gid, int pollTimeout)
|
||||
@ -49,13 +46,13 @@ Server::~Server()
|
||||
|
||||
}
|
||||
|
||||
void Server::handleUnknownClient(const TunnelHeader &header, int dataLength, uint32_t realIp, uint16_t echoId)
|
||||
void Server::handleUnknownClient(const TunnelHeader &header, int dataLength, uint32_t realIp, uint16_t echoId, uint16_t echoSeq)
|
||||
{
|
||||
ClientData client;
|
||||
client.realIp = realIp;
|
||||
client.maxPolls = 1;
|
||||
|
||||
pollReceived(&client, echoId);
|
||||
pollReceived(&client, echoId, echoSeq);
|
||||
|
||||
if (header.type != TunnelHeader::TYPE_CONNECTION_REQUEST || dataLength != sizeof(ClientConnectData))
|
||||
{
|
||||
@ -64,7 +61,7 @@ void Server::handleUnknownClient(const TunnelHeader &header, int dataLength, uin
|
||||
return;
|
||||
}
|
||||
|
||||
ClientConnectData *connectData = (ClientConnectData *)payloadBuffer();
|
||||
ClientConnectData *connectData = (ClientConnectData *)echoReceivePayloadBuffer();
|
||||
|
||||
client.maxPolls = connectData->maxPolls;
|
||||
client.state = ClientData::STATE_NEW;
|
||||
@ -93,7 +90,7 @@ void Server::sendChallenge(ClientData *client)
|
||||
{
|
||||
syslog(LOG_DEBUG, "sending challenge to: %s\n", Utility::formatIp(client->realIp).c_str());
|
||||
|
||||
memcpy(payloadBuffer(), &client->challenge[0], client->challenge.size());
|
||||
memcpy(echoSendPayloadBuffer(), &client->challenge[0], client->challenge.size());
|
||||
sendEchoToClient(client, TunnelHeader::TYPE_CHALLENGE, client->challenge.size());
|
||||
|
||||
client->state = ClientData::STATE_CHALLENGE_SENT;
|
||||
@ -117,7 +114,7 @@ void Server::checkChallenge(ClientData *client, int length)
|
||||
{
|
||||
Auth::Response rightResponse = auth.getResponse(client->challenge);
|
||||
|
||||
if (length != sizeof(Auth::Response) || memcmp(&rightResponse, payloadBuffer(), length) != 0)
|
||||
if (length != sizeof(Auth::Response) || memcmp(&rightResponse, echoReceivePayloadBuffer(), length) != 0)
|
||||
{
|
||||
syslog(LOG_DEBUG, "wrong challenge response\n");
|
||||
|
||||
@ -127,7 +124,7 @@ void Server::checkChallenge(ClientData *client, int length)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t *ip = (uint32_t *)payloadBuffer();
|
||||
uint32_t *ip = (uint32_t *)echoSendPayloadBuffer();
|
||||
*ip = htonl(client->tunnelIp);
|
||||
|
||||
sendEchoToClient(client, TunnelHeader::TYPE_CONNECTION_ACCEPT, sizeof(uint32_t));
|
||||
@ -154,11 +151,11 @@ bool Server::handleEchoData(const TunnelHeader &header, int dataLength, uint32_t
|
||||
ClientData *client = getClientByRealIp(realIp);
|
||||
if (client == NULL)
|
||||
{
|
||||
handleUnknownClient(header, dataLength, realIp, id);
|
||||
handleUnknownClient(header, dataLength, realIp, id, seq);
|
||||
return true;
|
||||
}
|
||||
|
||||
pollReceived(client, id);
|
||||
pollReceived(client, id, seq);
|
||||
|
||||
switch (header.type)
|
||||
{
|
||||
@ -186,6 +183,13 @@ bool Server::handleEchoData(const TunnelHeader &header, int dataLength, uint32_t
|
||||
case TunnelHeader::TYPE_DATA:
|
||||
if (client->state == ClientData::STATE_ESTABLISHED)
|
||||
{
|
||||
if (dataLength == 0)
|
||||
{
|
||||
syslog(LOG_WARNING, "received empty data packet");
|
||||
throw 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
sendToTun(dataLength);
|
||||
return true;
|
||||
}
|
||||
@ -230,19 +234,19 @@ void Server::handleTunData(int dataLength, uint32_t sourceIp, uint32_t destIp)
|
||||
sendEchoToClient(client, TunnelHeader::TYPE_DATA, dataLength);
|
||||
}
|
||||
|
||||
void Server::pollReceived(ClientData *client, uint16_t echoId)
|
||||
void Server::pollReceived(ClientData *client, uint16_t echoId, uint16_t echoSeq)
|
||||
{
|
||||
unsigned int maxSavedPolls = client->maxPolls != 0 ? client->maxPolls : 1;
|
||||
|
||||
client->pollIds.push(echoId);
|
||||
client->pollIds.push(ClientData::EchoId(echoId, echoSeq));
|
||||
if (client->pollIds.size() > maxSavedPolls)
|
||||
client->pollIds.pop();
|
||||
DEBUG_ONLY(printf("poll (%d) -> %d\n", echoId, client->pollIds.size()));
|
||||
DEBUG_ONLY(printf("poll -> %d\n", client->pollIds.size()));
|
||||
|
||||
if (client->pendingPackets.size() > 0)
|
||||
{
|
||||
Packet &packet = client->pendingPackets.front();
|
||||
memcpy(payloadBuffer(), &packet.data[0], packet.data.size());
|
||||
memcpy(echoSendPayloadBuffer(), &packet.data[0], packet.data.size());
|
||||
client->pendingPackets.pop();
|
||||
|
||||
DEBUG_ONLY(printf("pending packet: %d bytes\n", packet.data.size()));
|
||||
@ -256,22 +260,20 @@ void Server::sendEchoToClient(ClientData *client, int type, int dataLength)
|
||||
{
|
||||
if (client->maxPolls == 0)
|
||||
{
|
||||
sendEcho(magic, type, dataLength, client->realIp, true, client->pollIds.front(), 0);
|
||||
sendEcho(magic, type, dataLength, client->realIp, true, client->pollIds.front().id, client->pollIds.front().seq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client->pollIds.size() != 0)
|
||||
{
|
||||
uint16_t id = client->pollIds.front();
|
||||
ClientData::EchoId echoId = client->pollIds.front();
|
||||
client->pollIds.pop();
|
||||
|
||||
DEBUG_ONLY(printf("sending (%d) -> %d\n", id, client->pollIds.size()));
|
||||
sendEcho(magic, type, dataLength, client->realIp, true, id, 0);
|
||||
DEBUG_ONLY(printf("sending -> %d\n", client->pollIds.size()));
|
||||
sendEcho(magic, type, dataLength, client->realIp, true, echoId.id, echoId.seq);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_ONLY(printf("queuing -> %d\n", client->pollIds.size()));
|
||||
|
||||
if (client->pendingPackets.size() == MAX_BUFFERED_PACKETS)
|
||||
{
|
||||
client->pendingPackets.pop();
|
||||
@ -284,7 +286,7 @@ void Server::sendEchoToClient(ClientData *client, int type, int dataLength)
|
||||
Packet &packet = client->pendingPackets.back();
|
||||
packet.type = type;
|
||||
packet.data.resize(dataLength);
|
||||
memcpy(&packet.data[0], payloadBuffer(), dataLength);
|
||||
memcpy(&packet.data[0], echoReceivePayloadBuffer(), dataLength);
|
||||
}
|
||||
|
||||
void Server::releaseTunnelIp(uint32_t tunnelIp)
|
||||
|
14
server.h
14
server.h
@ -57,13 +57,21 @@ protected:
|
||||
STATE_ESTABLISHED
|
||||
};
|
||||
|
||||
struct EchoId
|
||||
{
|
||||
EchoId(uint16_t id, uint16_t seq) { this->id = id; this->seq = seq; }
|
||||
|
||||
uint16_t id;
|
||||
uint16_t seq;
|
||||
};
|
||||
|
||||
uint32_t realIp;
|
||||
uint32_t tunnelIp;
|
||||
|
||||
std::queue<Packet> pendingPackets;
|
||||
|
||||
int maxPolls;
|
||||
std::queue<uint16_t> pollIds;
|
||||
std::queue<EchoId> pollIds;
|
||||
Time lastActivity;
|
||||
|
||||
State state;
|
||||
@ -82,7 +90,7 @@ protected:
|
||||
|
||||
void serveTun(ClientData *client);
|
||||
|
||||
void handleUnknownClient(const TunnelHeader &header, int dataLength, uint32_t realIp, uint16_t echoId);
|
||||
void handleUnknownClient(const TunnelHeader &header, int dataLength, uint32_t realIp, uint16_t echoId, uint16_t echoSeq);
|
||||
void removeClient(ClientData *client);
|
||||
|
||||
void sendChallenge(ClientData *client);
|
||||
@ -91,7 +99,7 @@ protected:
|
||||
|
||||
void sendEchoToClient(ClientData *client, int type, int dataLength);
|
||||
|
||||
void pollReceived(ClientData *client, uint16_t echoId);
|
||||
void pollReceived(ClientData *client, uint16_t echoId, uint16_t echoSeq);
|
||||
|
||||
uint32_t reserveTunnelIp();
|
||||
void releaseTunnelIp(uint32_t tunnelIp);
|
||||
|
20
worker.cpp
20
worker.cpp
@ -20,6 +20,7 @@
|
||||
#include "worker.h"
|
||||
#include "tun.h"
|
||||
#include "exception.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
@ -78,16 +79,18 @@ void Worker::sendEcho(const TunnelHeader::Magic &magic, int type, int length, ui
|
||||
if (length > payloadBufferSize())
|
||||
throw Exception("packet too big");
|
||||
|
||||
TunnelHeader *header = (TunnelHeader *)echo->payloadBuffer();
|
||||
TunnelHeader *header = (TunnelHeader *)echo->sendPayloadBuffer();
|
||||
header->magic = magic;
|
||||
header->type = type;
|
||||
|
||||
DEBUG_ONLY(printf("sending: type %d, length %d, id %d, seq %d\n", type, length, id, seq));
|
||||
|
||||
echo->send(length + sizeof(TunnelHeader), realIp, reply, id, seq);
|
||||
}
|
||||
|
||||
void Worker::sendToTun(int length)
|
||||
{
|
||||
tun->write(payloadBuffer(), length);
|
||||
tun->write(echoReceivePayloadBuffer(), length);
|
||||
}
|
||||
|
||||
void Worker::setTimeout(Time delta)
|
||||
@ -145,10 +148,19 @@ void Worker::run()
|
||||
bool valid = dataLength >= sizeof(TunnelHeader);
|
||||
|
||||
if (valid)
|
||||
valid = handleEchoData(*(TunnelHeader *)(echo->payloadBuffer()), dataLength - sizeof(TunnelHeader), ip, reply, id, seq);
|
||||
{
|
||||
TunnelHeader header = *(TunnelHeader *)echo->receivePayloadBuffer(); // make a copy!
|
||||
|
||||
DEBUG_ONLY(printf("received: type %d, length %d, id %d, seq %d\n", header.type, dataLength - sizeof(TunnelHeader), id, seq));
|
||||
|
||||
valid = handleEchoData(header, dataLength - sizeof(TunnelHeader), ip, reply, id, seq);
|
||||
}
|
||||
|
||||
if (!valid && !reply && answerEcho)
|
||||
{
|
||||
memcpy(echo->sendPayloadBuffer(), echo->receivePayloadBuffer(), dataLength);
|
||||
echo->send(dataLength, ip, true, id, seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +169,7 @@ void Worker::run()
|
||||
{
|
||||
uint32_t sourceIp, destIp;
|
||||
|
||||
int dataLength = tun->read(payloadBuffer(), sourceIp, destIp);
|
||||
int dataLength = tun->read(echoSendPayloadBuffer(), sourceIp, destIp);
|
||||
|
||||
if (dataLength == 0)
|
||||
throw Exception("tunnel closed");
|
||||
|
8
worker.h
8
worker.h
@ -68,15 +68,17 @@ protected:
|
||||
}; // size = 5
|
||||
|
||||
virtual bool handleEchoData(const TunnelHeader &header, int dataLength, uint32_t realIp, bool reply, uint16_t id, uint16_t seq) { return true; }
|
||||
virtual void handleTunData(int dataLength, uint32_t sourceIp, uint32_t destIp) { }
|
||||
virtual void handleTunData(int dataLength, uint32_t sourceIp, uint32_t destIp) { } // to echoSendPayloadBuffer
|
||||
virtual void handleTimeout() { }
|
||||
|
||||
void sendEcho(const TunnelHeader::Magic &magic, int type, int length, uint32_t realIp, bool reply, uint16_t id, uint16_t seq);
|
||||
void sendToTun(int length);
|
||||
void sendToTun(int length); // from echoReceivePayloadBuffer
|
||||
|
||||
void setTimeout(Time delta);
|
||||
|
||||
char *payloadBuffer() { return echo->payloadBuffer() + sizeof(TunnelHeader); }
|
||||
char *echoSendPayloadBuffer() { return echo->sendPayloadBuffer() + sizeof(TunnelHeader); }
|
||||
char *echoReceivePayloadBuffer() { return echo->receivePayloadBuffer() + sizeof(TunnelHeader); }
|
||||
|
||||
int payloadBufferSize() { return tunnelMtu; }
|
||||
|
||||
void dropPrivileges();
|
||||
|
Loading…
x
Reference in New Issue
Block a user