From 1d16df2918530ef07eff06efe1a01a88232fbbc2 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Oct 26 2021 04:39:20 +0000 Subject: speed opetion, fix bugs --- diff --git a/connection.cpp b/connection.cpp index a580cc0..93f14f4 100644 --- a/connection.cpp +++ b/connection.cpp @@ -29,10 +29,10 @@ bool Connection::wantWriteToTcp() const { return tcpSockId >= 0 && (tcpSendQueue.busySize() > 0 || udpRecvQueue.canSentToTcp()); } -Time Connection::whenWriteToUdp() const { - Time t = lastUdpOutputTime + tunnel.udpKeepAliveDuration; +void Connection::whenWriteToUdp(Time &t) const { + if (timeLess(lastUdpOutputTime + tunnel.udpKeepAliveDuration, t)) + t = lastUdpOutputTime + tunnel.udpKeepAliveDuration; udpSendQueue.whenWriteToUdp(t); udpRecvQueue.whenWriteToUdp(t); - return t; } diff --git a/connection.h b/connection.h index daf81ef..b758a0f 100644 --- a/connection.h +++ b/connection.h @@ -38,7 +38,7 @@ public: bool wantReadFromTcp() const; bool wantWriteToTcp() const; - Time whenWriteToUdp() const; + void whenWriteToUdp(Time &t) const; }; diff --git a/main.cpp b/main.cpp index 226d583..9ece38a 100644 --- a/main.cpp +++ b/main.cpp @@ -23,20 +23,27 @@ int main(int argc, char **argv) { // parse args + unsigned long long bytesPerSecond = 0; Address localUdp, remoteUdp, localTcp, remoteTcp; - if (argc == 5) { - parseAddress(argv[2], localUdp); - parseAddress(argv[3], remoteUdp); - parseAddress(argv[4], localTcp); + if (argc == 6) { + sscanf(argv[2], "%llu", &bytesPerSecond); + if (!bytesPerSecond) + { printf("Wrong bytes per second: %llu\n", bytesPerSecond); return 1; } + parseAddress(argv[3], localUdp); + parseAddress(argv[4], remoteUdp); + parseAddress(argv[5], localTcp); if (!localUdp.port || !remoteUdp.port || !localTcp.port) return 1; } else - if (argc == 4) { - parseAddress(argv[2], localUdp); - parseAddress(argv[3], remoteTcp); + if (argc == 5) { + sscanf(argv[2], "%llu", &bytesPerSecond); + if (!bytesPerSecond) + { printf("Wrong bytes per second: %llu\n", bytesPerSecond); return 1; } + parseAddress(argv[3], localUdp); + parseAddress(argv[4], remoteTcp); if (!localUdp.port || !remoteTcp.port) return 1; } else { - printf("Usage: %s keyfile localUdp:port remoteUdp:port localTcp:port\n", argv[0]); - printf(" or: %s keyfile localUdp:port remoteTcp:port\n", argv[0]); + printf("Usage: %s keyfile bytesPerSecond localUdp:port remoteUdp:port localTcp:port\n", argv[0]); + printf(" or: %s keyfile bytesPerSecond localUdp:port remoteTcp:port\n", argv[0]); return 1; } @@ -64,6 +71,8 @@ int main(int argc, char **argv) { Tunnel tunnel; + tunnel.initSpeed(bytesPerSecond); + if ( !tunnel.initUdpServer(localUdp, remoteTcp, key) ) { memset(key, 0, maxSize); free(key); diff --git a/tunnel.cpp b/tunnel.cpp index 38b6093..81705b9 100644 --- a/tunnel.cpp +++ b/tunnel.cpp @@ -12,25 +12,36 @@ Tunnel::Tunnel(): - time(monotonicTime()), - udpSendDuration(1000), - udpPartialSendDuration(10*udpSendDuration), - udpResendDuration(udpSendDuration * PACKETS_COUNT), - udpConfirmDuration(udpResendDuration/8), + time(), // will be set by initTime() called by initSpeed() + udpSendDuration(), // will be + udpPartialSendDuration(), // set + udpResendDuration(), // by + udpConfirmDuration(), // initSpeed() udpSilenceDuration(300000000), udpKeepAliveDuration(udpSilenceDuration/32), timeQwant(1200000000), pollDuration(5000000), udpSockId(-1), tcpSockId(-1), - nextTermSendTime(time + udpConfirmDuration) - { } + nextTermSendTime() // will be set by initTime() called by initSpeed() +{ + initSpeed(1024*1024); +} Tunnel::~Tunnel() { close(); } +void Tunnel::initSpeed(unsigned long long bytesPerSecond) { + udpSendDuration = (1000000ull*PACKET_SIZE + bytesPerSecond/2)/bytesPerSecond; + udpPartialSendDuration = 10*udpSendDuration; + udpResendDuration = udpSendDuration * PACKETS_COUNT; + udpConfirmDuration = udpResendDuration/8; + initTime(); +} + + bool Tunnel::initUdpServer(const Address &address, const Address &remoteTcpAddress, const char *key) { closeUdpServer(); printf("Init UDP server at address: "); address.print(); @@ -178,6 +189,13 @@ void Tunnel::sendUdpPacket(const Address &address, const Packet &packet) { } +void Tunnel::initTime() { + time = monotonicTime(); + nextTermSendTime = time + udpConfirmDuration; + crypt.setTime(globalTime(), timeQwant); +} + + bool Tunnel::iteration() { if (udpSockId < 0) return false; @@ -198,6 +216,7 @@ bool Tunnel::iteration() { e.wantRead = true; } + time = monotonicTime(); Time pollTime = time + pollDuration; for(ConnMap::iterator i = connections.begin(); i != connections.end(); ++i) { Connection &conn = i->second; @@ -209,13 +228,13 @@ bool Tunnel::iteration() { e.wantRead = conn.udpActive && conn.wantReadFromTcp(); e.wantWrite = conn.wantWriteToTcp(); } - if (conn.udpActive) { - Time t = conn.whenWriteToUdp(); - if (timeLess(pollTime, t)) pollTime = t; - } + if (conn.udpActive) + conn.whenWriteToUdp(pollTime); } + if (timeLess(pollTime, time)) pollTime = time; // wait for events + DebugMsg("poll duration: %llu", pollTime - time); poll.wait(pollTime - time); time = monotonicTime(); crypt.setTime(globalTime(), timeQwant); @@ -347,8 +366,7 @@ bool Tunnel::iteration() { void Tunnel::run() { - time = monotonicTime(); - nextTermSendTime = time + udpConfirmDuration; + initTime(); while(iteration()); } diff --git a/tunnel.h b/tunnel.h index bd03119..bf84906 100644 --- a/tunnel.h +++ b/tunnel.h @@ -45,6 +45,8 @@ public: Tunnel(); ~Tunnel(); + void initSpeed(unsigned long long bytesPerSecond); + bool initUdpServer(const Address &address, const Address &remoteTcpAddress, const char *key); bool initTcpServer(const Address &address, const Address &remoteUdpAddress); @@ -54,6 +56,8 @@ public: bool recvUdpPacket(); void sendUdpPacket(const Address &address, const Packet &packet); + + void initTime(); bool iteration(); void run(); diff --git a/udpsendqueue.cpp b/udpsendqueue.cpp index 4e645fe..7f07d4d 100644 --- a/udpsendqueue.cpp +++ b/udpsendqueue.cpp @@ -98,28 +98,34 @@ bool UdpSendQueue::sendUdpSingle() { if (!e && !freeFirst) return false; - if (!e) { + if (!e && !finalEntryAdded) { int size = connection.tcpRecvQueue.busySize(); if (size > PACKET_SIZE) size = PACKET_SIZE; if (size < 0) size = 0; + bool load = true; if (size == 0) { - if (connection.tcpSockId >= 0 || finalEntryAdded) { + if (connection.tcpSockId >= 0) { nextPartialSendTime = time + connection.tunnel.udpPartialSendDuration; - return false; + load = false; } } else { if (size < PACKET_SIZE && timeLess(time, nextPartialSendTime)) - return false; + load = false; } - if ( !(e = allocEntry()) ) - return false; - e->index = nextIndex++; - e->size = size; - if (e->size) connection.tcpRecvQueue.pop(e->data, e->size); else finalEntryAdded = true; + if (load && (e = allocEntry())) { + nextPartialSendTime = time + connection.tunnel.udpPartialSendDuration; + e->index = nextIndex++; + e->size = size; + if (e->size) connection.tcpRecvQueue.pop(e->data, e->size); else finalEntryAdded = true; + DebugMsg("%u, %u, %d - created packet to send by UDP", connection.id.id, e->index, e->size); + } } + if (!e) e = busyFirst; + if (!e) return false; + Packet packet; packet.init(connection.id.id, e->index, CMD_DATA, e->size); if (e->size) memcpy(packet.payload, e->data, e->size); @@ -128,7 +134,7 @@ bool UdpSendQueue::sendUdpSingle() { e->resendTime = time + connection.tunnel.udpResendDuration; nextSendTime += connection.tunnel.udpSendDuration; - nextPartialSendTime = time + connection.tunnel.udpPartialSendDuration; + moveToEnd(e); return true; } @@ -139,8 +145,11 @@ int UdpSendQueue::sendUdp() { while(sendUdpSingle()) { ++sent; if (sent == 100) { - if (timeLess(nextSendTime, connection.tunnel.time)) + if (timeLess(nextSendTime, connection.tunnel.time)) { + DebugMsg( "%u, time correction by %llu after sent %d packets", + connection.id.id, connection.tunnel.time - nextSendTime, sent ); nextSendTime = connection.tunnel.time; + } break; } }