1 //**************************************************************************
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2.020 Ketmar Dark
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
25 //**************************************************************************
26 #include "../gamedefs.h"
27 #include "net_local.h"
30 static const char *cli_Port
= nullptr;
31 //static int cli_Listen = 0;
33 /*static*/ bool cliRegister_netmain_args
=
34 VParsedArgs::RegisterStringOption("-port", "explicitly set your host port (default is 26000)", &cli_Port
)
35 /*&& VParsedArgs::RegisterFlagSet("-listen", nullptr, &cli_Listen)*/;
38 static VCvarS
net_ui_last_join_address("net_ui_last_join_address", "127.0.0.1", "Last server address for manual connection (used in UI).", CVAR_Archive
|CVAR_NoShadow
);
41 // ////////////////////////////////////////////////////////////////////////// //
42 class VNetwork
: public VNetworkLocal
{
44 VNetPollProcedure SlistSendProcedure
;
45 VNetPollProcedure SlistPollProcedure
;
46 VNetPollProcedure MasterListSendProcedure
;
47 VNetPollProcedure MasterListPollProcedure
;
54 double SlistStartTime
;
59 VNetPollProcedure
*PollProcedureList
;
64 virtual ~VNetwork () override
;
66 virtual void Init () override
;
67 virtual void Shutdown () override
;
68 virtual VSocketPublic
*Connect (const char *) override
;
69 virtual VSocketPublic
*CheckNewConnections (bool rconOnly
) override
;
70 virtual void Poll () override
;
71 virtual void StartSearch (bool) override
;
72 virtual slist_t
*GetSlist () override
;
73 virtual void UpdateMaster () override
;
74 virtual void QuitMaster () override
;
76 // API only for network drivers!
77 virtual void SchedulePollProcedure (VNetPollProcedure
*, double) override
;
80 virtual void Slist () override
;
83 static void Slist_Send (void *);
84 static void Slist_Poll (void *);
87 static void MasterList_Send (void *);
88 static void MasterList_Poll (void *);
89 void MasterList_Send ();
90 void MasterList_Poll ();
91 void PrintSlistHeader ();
93 void PrintSlistTrailer ();
97 // ////////////////////////////////////////////////////////////////////////// //
98 VNetworkPublic
*GNet
= nullptr;
100 VCvarS
VNetworkLocal::HostName("hostname", "UNNAMED", "Name of this host.", CVAR_PreInit
|CVAR_NoShadow
);
102 VNetDriver
*VNetworkLocal::Drivers
[MAX_NET_DRIVERS
];
103 int VNetworkLocal::NumDrivers
= 0;
105 VNetLanDriver
*VNetworkLocal::LanDrivers
[MAX_NET_DRIVERS
];
106 int VNetworkLocal::NumLanDrivers
= 0;
109 //==========================================================================
111 // VNetworkPublic::Create
113 //==========================================================================
114 VNetworkPublic
*VNetworkPublic::Create () {
115 return new VNetwork();
119 //==========================================================================
121 // VNetworkPublic::VNetworkPublic
123 //==========================================================================
124 VNetworkPublic::VNetworkPublic ()
125 : UnreliableMessagesSent(0)
126 , UnreliableMessagesReceived(0)
130 , receivedDuplicateCount(0)
131 , shortPacketCount(0)
132 , droppedDatagrams(0)
136 , minimalSentPacket(0)
137 , maximalSentPacket(0)
138 , CheckUserAbortCB(nullptr)
139 , CheckUserAbortUData(nullptr)
145 //==========================================================================
147 // VNetworkPublic::UpdateNetTime
149 //==========================================================================
150 void VNetworkPublic::UpdateNetTime () noexcept
{
151 CurrNetTime
= Sys_Time();
155 //==========================================================================
157 // VNetworkPublic::GetNetTime
159 //==========================================================================
160 double VNetworkPublic::GetNetTime () noexcept
{
161 if (CurrNetTime
< 0) UpdateNetTime();
166 //==========================================================================
168 // VNetworkPublic::UpdateSentStats
170 //==========================================================================
171 void VNetworkPublic::UpdateSentStats (vuint32 length
) noexcept
{
174 if (!minimalSentPacket
|| minimalSentPacket
> length
) minimalSentPacket
= length
;
175 if (maximalSentPacket
< length
) maximalSentPacket
= length
;
180 //==========================================================================
182 // VNetworkPublic::UpdateReceivedStats
184 //==========================================================================
185 void VNetworkPublic::UpdateReceivedStats (vuint32 length
) noexcept
{
186 bytesReceived
+= length
;
190 //==========================================================================
192 // VNetworkPublic::UpdateRejectedStats
194 //==========================================================================
195 void VNetworkPublic::UpdateRejectedStats (vuint32 length
) noexcept
{
196 bytesRejected
+= length
;
200 //==========================================================================
202 // VNetworkLocal::VNetworkLocal
204 //==========================================================================
205 VNetworkLocal::VNetworkLocal ()
207 , ActiveSockets(nullptr)
210 , DefaultHostPort(26000)
216 memset((void *)HostCache
, 0, sizeof(HostCache
));
220 //==========================================================================
222 // VNetwork::VNetwork
224 //==========================================================================
226 : SlistSendProcedure(Slist_Send
, this)
227 , SlistPollProcedure(Slist_Poll
, this)
228 , MasterListSendProcedure(MasterList_Send
, this)
229 , MasterListPollProcedure(MasterList_Poll
, this)
230 , SlistInProgress(false)
235 , SlistStartTime(0.0)
237 , PollProcedureList(nullptr)
242 //==========================================================================
244 // VNetwork::~VNetwork
246 //==========================================================================
247 VNetwork::~VNetwork () {
252 //==========================================================================
256 //==========================================================================
257 void VNetwork::Init () {
258 const char *p
= cli_Port
;
260 DefaultHostPort
= VStr::atoi(p
);
261 if (DefaultHostPort
< 1 || DefaultHostPort
> 65535) DefaultHostPort
= 26000;
263 HostPort
= DefaultHostPort
;
266 //if (cli_Listen || cls.state == ca_dedicated) Listening = true;
271 // initialise all the drivers
272 for (int i
= 0; i
< NumDrivers
; ++i
) {
273 Drivers
[i
]->Net
= this;
274 if (Drivers
[i
]->Init() != -1) {
275 Drivers
[i
]->initialised
= true;
276 if (Listening
) Drivers
[i
]->Listen(true);
280 if (developer
&& *MyIpAddress
) GCon
->Logf(NAME_DevNet
, "TCP/IP address %s", MyIpAddress
);
284 //==========================================================================
286 // VNetwork::Shutdown
288 //==========================================================================
289 void VNetwork::Shutdown () {
290 while (ActiveSockets
) {
291 delete ActiveSockets
;
292 ActiveSockets
= nullptr;
295 // shutdown the drivers
296 for (int i
= 0; i
< NumDrivers
; ++i
) {
297 if (Drivers
[i
]->initialised
) {
298 Drivers
[i
]->Shutdown();
299 Drivers
[i
]->initialised
= false;
305 //==========================================================================
309 //==========================================================================
310 void VNetwork::Poll () {
312 const double ctt
= GetNetTime();
313 for (VNetPollProcedure
*pp
= PollProcedureList
; pp
; pp
= pp
->next
) {
314 if (pp
->nextTime
> ctt
) break;
315 PollProcedureList
= pp
->next
;
316 pp
->procedure(pp
->arg
);
321 //==========================================================================
323 // VNetwork::SchedulePollProcedure
325 //==========================================================================
326 void VNetwork::SchedulePollProcedure (VNetPollProcedure
*proc
, double timeOffset
) {
327 VNetPollProcedure
*pp
, *prev
;
329 proc
->nextTime
= Sys_Time()+timeOffset
;
330 for (pp
= PollProcedureList
, prev
= nullptr; pp
; pp
= pp
->next
) {
331 if (pp
->nextTime
>= proc
->nextTime
) break;
335 if (prev
== nullptr) {
336 proc
->next
= PollProcedureList
;
337 PollProcedureList
= proc
;
345 //==========================================================================
349 //==========================================================================
350 void VNetwork::Slist () {
351 if (SlistInProgress
) return;
354 GCon
->Log(NAME_DevNet
, "Looking for k8vavoom servers");
359 SlistInProgress
= true;
360 SlistStartTime
= Sys_Time();
362 SchedulePollProcedure(&SlistSendProcedure
, 0.0);
363 SchedulePollProcedure(&SlistPollProcedure
, 0.1);
369 //==========================================================================
371 // VNetwork::Slist_Send
373 //==========================================================================
374 void VNetwork::Slist_Send (void *Arg
) {
375 ((VNetwork
*)Arg
)->Slist_Send();
379 //==========================================================================
381 // VNetwork::Slist_Poll
383 //==========================================================================
384 void VNetwork::Slist_Poll (void *Arg
) {
385 ((VNetwork
*)Arg
)->Slist_Poll();
389 //==========================================================================
391 // VNetwork::Slist_Send
393 //==========================================================================
394 void VNetwork::Slist_Send () {
395 for (int i
= 0; i
< NumDrivers
; ++i
) {
396 if (!SlistLocal
&& i
== 0) continue;
397 if (Drivers
[i
]->initialised
== false) continue;
398 Drivers
[i
]->SearchForHosts(true, SlistMaster
);
401 if ((Sys_Time()-SlistStartTime
) < 0.5) SchedulePollProcedure(&SlistSendProcedure
, 0.75);
405 //==========================================================================
407 // VNetwork::Slist_Poll
409 //==========================================================================
410 void VNetwork::Slist_Poll () {
411 for (int i
= 0; i
< NumDrivers
; ++i
) {
412 if (!SlistLocal
&& i
== 0) continue;
413 if (Drivers
[i
]->initialised
== false) continue;
414 Drivers
[i
]->SearchForHosts(false, SlistMaster
);
417 if (!SlistSilent
) PrintSlist();
419 if ((Sys_Time()-SlistStartTime
) < 1.5) {
420 SchedulePollProcedure(&SlistPollProcedure
, 0.1);
424 if (!SlistSilent
) PrintSlistTrailer();
425 SlistInProgress
= false;
432 //==========================================================================
434 // VNetwork::MasterList
436 //==========================================================================
437 void VNetwork::MasterList () {
438 if (SlistInProgress
) return;
441 GCon
->Log(NAME_DevNet
, "Looking for k8vavoom servers");
446 SlistInProgress
= true;
447 SlistStartTime
= Sys_Time();
449 SchedulePollProcedure(&MasterListSendProcedure
, 0.0);
450 SchedulePollProcedure(&MasterListPollProcedure
, 0.1);
456 //==========================================================================
458 // VNetwork::MasterList_Send
460 //==========================================================================
461 void VNetwork::MasterList_Send (void *Arg
) {
462 ((VNetwork
*)Arg
)->MasterList_Send();
466 //==========================================================================
468 // VNetwork::MasterList_Poll
470 //==========================================================================
471 void VNetwork::MasterList_Poll (void *Arg
) {
472 ((VNetwork
*)Arg
)->MasterList_Poll();
476 //==========================================================================
478 // VNetwork::MasterList_Send
480 //==========================================================================
481 void VNetwork::MasterList_Send () {
482 for (int i
= 0; i
< NumDrivers
; ++i
) {
483 if (Drivers
[i
]->initialised
== false) continue;
484 Drivers
[i
]->QueryMaster(true);
487 if ((Sys_Time()-SlistStartTime
) < 0.5) SchedulePollProcedure(&MasterListSendProcedure
, 0.75);
491 //==========================================================================
493 // VNetwork::MasterList_Poll
495 //==========================================================================
496 void VNetwork::MasterList_Poll () {
497 // check for reply from master server
498 bool GotList
= false;
499 for (int i
= 0; i
< NumDrivers
; ++i
) {
500 if (Drivers
[i
]->initialised
== false) continue;
501 if (Drivers
[i
]->QueryMaster(false)) GotList
= true;
504 // if no reply, try again
505 if (!GotList
&& (Sys_Time()-SlistStartTime
) < 1.5) {
506 SchedulePollProcedure(&MasterListPollProcedure
, 0.1);
510 // close socket for communicating with master server
511 for (int i
= 0; i
< NumDrivers
; ++i
) {
512 if (Drivers
[i
]->initialised
) Drivers
[i
]->EndQueryMaster();
515 // if we got list, server info command has been sent to all servers, so start listening for their replies
517 SlistStartTime
= Sys_Time();
518 SchedulePollProcedure(&SlistPollProcedure
, 0.1);
522 // could not connect to the master server
524 GCon
->Log(NAME_DevNet
, "Could not connect to the master server.");
527 SlistInProgress
= false;
534 //==========================================================================
536 // VNetwork::PrintSlistHeader
538 //==========================================================================
539 void VNetwork::PrintSlistHeader () {
540 GCon
->Log(NAME_DevNet
, "Server Map Users");
541 GCon
->Log(NAME_DevNet
, "--------------- --------------- -----");
546 //==========================================================================
548 // VNetwork::PrintSlist
550 //==========================================================================
551 void VNetwork::PrintSlist () {
553 for (n
= SlistLastShown
; n
< HostCacheCount
; ++n
) {
554 if (HostCache
[n
].MaxUsers
) {
555 GCon
->Logf(NAME_DevNet
, "%-15s %-15s %2d/%2d", *HostCache
[n
].Name
, *HostCache
[n
].Map
, HostCache
[n
].Users
, HostCache
[n
].MaxUsers
);
557 GCon
->Logf(NAME_DevNet
, "%-15s %-15s", *HostCache
[n
].Name
, *HostCache
[n
].Map
);
564 //==========================================================================
566 // VNetwork::PrintSlistTrailer
568 //==========================================================================
569 void VNetwork::PrintSlistTrailer () {
570 if (HostCacheCount
) {
571 GCon
->Log(NAME_DevNet
, "== end list ==");
573 GCon
->Log(NAME_DevNet
, "No k8vavoom servers found.");
575 GCon
->Log(NAME_DevNet
, "");
579 //==========================================================================
581 // VNetwork::StartSearch
583 //==========================================================================
584 void VNetwork::StartSearch (bool Master
) {
587 GCon
->Logf(NAME_DevNet
, "VNetwork::StartSearch: Master=%d", (int)Master
);
596 //==========================================================================
598 // VNetwork::GetSlist
600 //==========================================================================
601 slist_t
*VNetwork::GetSlist () {
603 if (HostCacheCount
> 1) {
604 vuint8 temp
[sizeof(hostcache_t
)];
605 for (int i
= 0; i
< HostCacheCount
; ++i
) {
606 for (int j
= i
+1; j
< HostCacheCount
; ++j
) {
607 if (HostCache
[j
].Name
.Cmp(HostCache
[i
].Name
) < 0) {
608 memcpy(&temp
, (void *)(&HostCache
[j
]), sizeof(hostcache_t
));
609 memcpy((void *)(&HostCache
[j
]), (void *)(&HostCache
[i
]), sizeof(hostcache_t
));
610 memcpy((void *)(&HostCache
[i
]), &temp
, sizeof(hostcache_t
));
616 memset(ReturnReason
, 0, sizeof(ReturnReason
));
619 if (SlistInProgress
) {
620 slist
.Flags
|= slist_t::SF_InProgress
;
622 slist
.Flags
&= ~slist_t::SF_InProgress
;
624 slist
.Count
= HostCacheCount
;
625 slist
.Cache
= HostCache
;
626 slist
.ReturnReason
= ReturnReason
;
631 //==========================================================================
635 //==========================================================================
636 VSocketPublic
*VNetwork::Connect (const char *InHost
) {
639 int numdrivers
= NumDrivers
;
642 if (host
.IsNotEmpty()) {
643 if (host
== "local") {
648 if (HostCacheCount
) {
649 for (n
= 0; n
< HostCacheCount
; ++n
) {
650 if (HostCache
[n
].Name
.ICmp(host
) == 0) {
651 host
= HostCache
[n
].CName
;
655 if (n
< HostCacheCount
) goto JustDoIt
;
659 SlistSilent
= host
.IsNotEmpty();
662 while (SlistInProgress
&& !CheckForUserAbort()) {
666 if (host
.IsEmpty()) {
667 if (HostCacheCount
!= 1) return nullptr;
668 host
= HostCache
[0].CName
;
669 GCon
->Log(NAME_DevNet
, "Connecting to");
670 GCon
->Logf(NAME_DevNet
, "%s @ %s", *HostCache
[0].Name
, *host
);
673 if (HostCacheCount
) {
674 for (n
= 0; n
< HostCacheCount
; ++n
) {
675 if (HostCache
[n
].Name
.ICmp(host
) == 0) {
676 host
= HostCache
[n
].CName
;
683 for (int i
= 0; i
< numdrivers
; ++i
) {
684 if (Drivers
[i
]->initialised
== false) continue;
685 ret
= Drivers
[i
]->Connect(*host
);
689 if (host
.IsNotEmpty()) {
699 //==========================================================================
701 // VNetwork::CheckNewConnections
703 //==========================================================================
704 VSocketPublic
*VNetwork::CheckNewConnections (bool rconOnly
) {
705 for (int i
= 0; i
< NumDrivers
; ++i
) {
706 if (Drivers
[i
]->initialised
== false) continue;
707 if (i
&& Listening
== false) continue;
708 VSocket
*ret
= Drivers
[i
]->CheckNewConnections(rconOnly
);
715 //==========================================================================
717 // VNetwork::UpdateMaster
719 //==========================================================================
720 void VNetwork::UpdateMaster () {
721 for (int i
= 0; i
< NumDrivers
; ++i
) {
722 if (!Drivers
[i
]->initialised
) continue;
723 Drivers
[i
]->UpdateMaster();
728 //==========================================================================
730 // VNetwork::QuitMaster
732 //==========================================================================
733 void VNetwork::QuitMaster () {
734 for (int i
= 0; i
< NumDrivers
; ++i
) {
735 if (!Drivers
[i
]->initialised
) continue;
736 Drivers
[i
]->QuitMaster();
741 //==========================================================================
743 // VSocketPublic::u64str
745 //==========================================================================
746 VStr
VSocketPublic::u64str (vuint64 v
, bool comatose
) noexcept
{
747 if (!v
) return VStr("0");
749 unsigned dpos
= (unsigned)sizeof(buf
);
750 int digitsPut
= (comatose
? 0 : 666);
753 if (digitsPut
== 3) {
759 buf
[--dpos
] = '0'+(int)(v
%10);
762 return VStr(buf
+dpos
);
766 //==========================================================================
768 // VSocketPublic::DumpStats
770 //==========================================================================
771 void VSocketPublic::DumpStats () {
772 if (bytesSent
|bytesReceived
|bytesRejected
) {
774 GCon
->Logf(NAME_DevNet
, "Closing stats for %s: %s bytes sent, %s bytes received (%s rejected)", *Address
, *u64str(bytesSent
), *u64str(bytesReceived
), *u64str(bytesRejected
));
776 GCon
->Logf(NAME_DevNet
, "Closing stats for %s: %s bytes sent, %s bytes received", *Address
, *u64str(bytesSent
), *u64str(bytesReceived
));
782 //==========================================================================
784 // VSocketPublic::UpdateSentStats
786 //==========================================================================
787 void VSocketPublic::UpdateSentStats (vuint32 length
) noexcept
{
790 if (!minimalSentPacket
|| minimalSentPacket
> length
) minimalSentPacket
= length
;
791 if (maximalSentPacket
< length
) maximalSentPacket
= length
;
796 //==========================================================================
798 // VSocketPublic::UpdateReceivedStats
800 //==========================================================================
801 void VSocketPublic::UpdateReceivedStats (vuint32 length
) noexcept
{
802 bytesReceived
+= length
;
806 //==========================================================================
808 // VSocketPublic::UpdateRejectedStats
810 //==========================================================================
811 void VSocketPublic::UpdateRejectedStats (vuint32 length
) noexcept
{
812 bytesRejected
+= length
;
816 //==========================================================================
820 //==========================================================================
821 VSocket::VSocket (VNetDriver
*Drv
) : Driver(Drv
) {
822 // add it to active list
823 Next
= Driver
->Net
->ActiveSockets
;
824 Driver
->Net
->ActiveSockets
= this;
826 Driver
->Net
->UpdateNetTime();
827 ConnectTime
= Driver
->Net
->GetNetTime();
828 Address
= "UNSET ADDRESS";
829 LastMessageTime
= ConnectTime
;
833 //==========================================================================
837 //==========================================================================
838 VSocket::~VSocket () {
839 // remove it from active list
840 if (this == Driver
->Net
->ActiveSockets
) {
841 Driver
->Net
->ActiveSockets
= Driver
->Net
->ActiveSockets
->Next
;
843 VSocket
*s
= nullptr;
844 for (s
= Driver
->Net
->ActiveSockets
; s
; s
= s
->Next
) {
845 if (s
->Next
== this) {
846 s
->Next
= this->Next
;
850 if (!s
) Sys_Error("NET_FreeQSocket: not active");
855 //==========================================================================
857 // VSocket::UpdateSentStats
859 //==========================================================================
860 void VSocket::UpdateSentStats (vuint32 length
) noexcept
{
861 VSocketPublic::UpdateSentStats(length
);
862 if (Driver
&& Driver
->Net
) Driver
->Net
->UpdateSentStats(length
);
866 //==========================================================================
868 // VSocket::UpdateReceivedStats
870 //==========================================================================
871 void VSocket::UpdateReceivedStats (vuint32 length
) noexcept
{
872 VSocketPublic::UpdateReceivedStats(length
);
873 if (Driver
&& Driver
->Net
) Driver
->Net
->UpdateReceivedStats(length
);
877 //==========================================================================
879 // VSocket::UpdateRejectedStats
881 //==========================================================================
882 void VSocket::UpdateRejectedStats (vuint32 length
) noexcept
{
883 VSocketPublic::UpdateRejectedStats(length
);
884 if (Driver
&& Driver
->Net
) Driver
->Net
->UpdateRejectedStats(length
);
888 //==========================================================================
890 // VNetDriver::VNetDriver
892 //==========================================================================
893 VNetDriver::VNetDriver (int Level
, const char *AName
) : name(AName
), initialised(false) {
894 VNetwork::Drivers
[Level
] = this;
895 if (VNetwork::NumDrivers
<= Level
) VNetwork::NumDrivers
= Level
+1;
899 //==========================================================================
901 // VNetLanDriver::VNetLanDriver
903 //==========================================================================
904 VNetLanDriver::VNetLanDriver (int Level
, const char *AName
)
908 , MasterQuerySocket(-1)
909 , net_acceptsocket(-1)
910 , net_controlsocket(-1)
911 , net_broadcastsocket(-1)
914 memset(&broadcastaddr
, 0, sizeof(broadcastaddr
));
915 VNetwork::LanDrivers
[Level
] = this;
916 if (VNetwork::NumLanDrivers
<= Level
) VNetwork::NumLanDrivers
= Level
+1;
920 //==========================================================================
922 // VNetUtils::TVMsecs
924 //==========================================================================
925 void VNetUtils::TVMsecs (timeval
*dest
, int msecs
) noexcept
{
927 if (msecs
< 0) msecs
= 0;
928 dest
->tv_sec
= msecs
/1000;
929 dest
->tv_usec
= msecs
%1000;
930 dest
->tv_usec
*= 1000;
934 //==========================================================================
938 // start with 0, continuous
940 //==========================================================================
941 vuint32
VNetUtils::CRC32C (vuint32 crc32
, const void *buf
, size_t length
) noexcept
{
942 return crc32cBuffer(crc32
, buf
, length
);
946 //==========================================================================
948 // VNetUtils::ChaCha20XCrypt
950 // encrypts or decrypts a full message
951 // cypher is symmetric, so `ciphertextdata` and `plaintextdata`
952 // can point to the same address
954 //==========================================================================
955 void VNetUtils::ChaCha20XCrypt (const vuint8 keydata
[ChaCha20KeySize
], const vuint32 nonce
,
956 void *ciphertextdata
, const void *plaintextdata
, vuint32 msglen
) noexcept
959 memset(noncebuf
, 0, sizeof(noncebuf
));
960 noncebuf
[0] = nonce
&0xffu
;
961 noncebuf
[1] = (nonce
>>8)&0xffu
;
962 noncebuf
[2] = (nonce
>>16)&0xffu
;
963 noncebuf
[3] = (nonce
>>24)&0xffu
;
966 (void)crypto_chacha20_djb((uint8_t *)ciphertextdata
, (const uint8_t *)plaintextdata
, msglen
, keydata
, noncebuf
, 0/*ctr*/);
970 //==========================================================================
972 // VNetUtils::GenerateKey
974 //==========================================================================
975 void VNetUtils::GenerateKey (vuint8 key
[ChaCha20KeySize
]) noexcept
{
977 vuint32 *dest = (vuint32 *)key;
978 for (int f = 0; f < ChaCha20KeySize/4; ++f) *dest++ = GenRandomU32();
980 prng_randombytes(key
, ChaCha20KeySize
);
984 //==========================================================================
986 // VNetUtils::DerivePublicKey
988 // derive public key from secret one
990 //==========================================================================
991 void VNetUtils::DerivePublicKey (vuint8 mypk
[ChaCha20KeySize
], const vuint8 mysk
[ChaCha20KeySize
]) {
992 //curve25519_donna_public(mypk, mysk);
993 crypto_x25519_public_key(mypk
, mysk
);
997 //==========================================================================
999 // VNetUtils::DeriveSharedKey
1001 // derive shared secret from our secret and their public
1003 //==========================================================================
1004 void VNetUtils::DeriveSharedKey (vuint8 sharedk
[ChaCha20KeySize
], const vuint8 mysk
[ChaCha20KeySize
], const vuint8 theirpk
[ChaCha20KeySize
]) {
1005 //curve25519_donna_shared(sharedk, mysk, theirpk);
1006 crypto_x25519(sharedk
, mysk
, theirpk
);
1010 //==========================================================================
1012 // VNetUtils::EncryptInfoPacket
1014 // WARNING! cannot do it in-place
1015 // needs 24 extra bytes (key, nonce, crc)
1016 // returns new length or -1 on error
1018 //==========================================================================
1019 int VNetUtils::EncryptInfoPacket (void *destbuf
, const void *srcbuf
, int srclen
, const vuint8 key
[ChaCha20KeySize
]) noexcept
{
1020 if (srclen
< 0) return -1;
1021 if (!destbuf
) return -1;
1022 if (srclen
> 0 && !srcbuf
) return -1;
1023 //const vuint32 nonce = GenRandomU32();
1025 prng_randombytes(&nonce
, sizeof(nonce
));
1026 vuint8
*dest
= (vuint8
*)destbuf
;
1028 memcpy(dest
, key
, ChaCha20KeySize
);
1030 dest
[ChaCha20KeySize
+0] = nonce
&0xffU
;
1031 dest
[ChaCha20KeySize
+1] = (nonce
>>8)&0xffU
;
1032 dest
[ChaCha20KeySize
+2] = (nonce
>>16)&0xffU
;
1033 dest
[ChaCha20KeySize
+3] = (nonce
>>24)&0xffU
;
1035 const vuint32 crc32
= CRC32C(0, srcbuf
, (unsigned)srclen
);
1036 dest
[ChaCha20KeySize
+4] = crc32
&0xffU
;
1037 dest
[ChaCha20KeySize
+5] = (crc32
>>8)&0xffU
;
1038 dest
[ChaCha20KeySize
+6] = (crc32
>>16)&0xffU
;
1039 dest
[ChaCha20KeySize
+7] = (crc32
>>24)&0xffU
;
1041 if (srclen
) memcpy(dest
+ChaCha20HeaderSize
, srcbuf
, (unsigned)srclen
);
1042 // encrypt crc32 and data
1043 ChaCha20XCrypt(key
, nonce
, dest
+ChaCha20KeySize
+ChaCha20NonceSize
, dest
+ChaCha20KeySize
+ChaCha20NonceSize
, (unsigned)(srclen
+ChaCha20CheckSumSize
));
1044 return srclen
+ChaCha20HeaderSize
;
1048 //==========================================================================
1050 // VNetUtils::DecryptInfoPacket
1052 // it can decrypt in-place
1053 // returns new length or -1 on error
1056 //==========================================================================
1057 int VNetUtils::DecryptInfoPacket (vuint8 key
[ChaCha20KeySize
], void *destbuf
, const void *srcbuf
, int srclen
) noexcept
{
1058 if (srclen
< ChaCha20HeaderSize
) return -1;
1059 if (!destbuf
) return -1;
1060 if (!srcbuf
) return -1;
1061 srclen
-= ChaCha20KeySize
+ChaCha20NonceSize
; // key and nonce
1062 const vuint8
*src
= (const vuint8
*)srcbuf
;
1063 vuint8
*dest
= (vuint8
*)destbuf
;
1065 memcpy(key
, srcbuf
, ChaCha20KeySize
);
1068 ((vuint32
)src
[ChaCha20KeySize
+0])|
1069 (((vuint32
)src
[ChaCha20KeySize
+1])<<8)|
1070 (((vuint32
)src
[ChaCha20KeySize
+2])<<16)|
1071 (((vuint32
)src
[ChaCha20KeySize
+3])<<24);
1073 ChaCha20XCrypt(key
, nonce
, dest
, src
+ChaCha20KeySize
+ChaCha20NonceSize
, (unsigned)srclen
);
1074 // calculate and check crc32
1075 srclen
-= ChaCha20CheckSumSize
;
1076 vassert(srclen
>= 0);
1077 vuint32 crc32
= CRC32C(0, dest
+ChaCha20CheckSumSize
, (unsigned)srclen
);
1078 if ((crc32
&0xff) != dest
[0] ||
1079 ((crc32
>>8)&0xff) != dest
[1] ||
1080 ((crc32
>>16)&0xff) != dest
[2] ||
1081 ((crc32
>>24)&0xff) != dest
[3])
1086 // copy decrypted data
1087 if (srclen
> 0) memcpy(dest
, dest
+ChaCha20CheckSumSize
, (unsigned)srclen
);
1093 #if defined(CLIENT) && defined(SERVER) /* I think like this */
1094 //==========================================================================
1098 //==========================================================================
1100 VNetwork
*Net
= (VNetwork
*)GNet
;
1101 if (Args
.length() != 2) {
1102 GCon
->Logf(NAME_DevNet
, "\"listen\" is \"%d\"", Net
->Listening
? 1 : 0);
1105 Net
->Listening
= (VStr::atoi(*Args
[1]) ? true : false);
1106 for (int i
= 0; i
< VNetwork::NumDrivers
; ++i
) {
1107 if (VNetwork::Drivers
[i
]->initialised
== false) continue;
1108 VNetwork::Drivers
[i
]->Listen(Net
->Listening
);
1114 //==========================================================================
1118 //==========================================================================
1122 VNetwork
*Net
= (VNetwork
*)GNet
;
1123 if (Args
.length() != 2) {
1124 GCon
->Logf(NAME_DevNet
, "\"port\" is \"%d\"", Net
->HostPort
);
1128 n
= VStr::atoi(*Args
[1]);
1129 if (n
< 1 || n
> 65534) {
1130 GCon
->Log(NAME_Error
, "Bad value, must be between 1 and 65534");
1134 Net
->DefaultHostPort
= n
;
1137 if (Net
->Listening
) {
1138 // force a change to the new port
1139 GCmdBuf
<< "listen 0\n";
1140 GCmdBuf
<< "listen 1\n";
1145 //==========================================================================
1149 //==========================================================================
1151 ((VNetwork
*)GNet
)->Slist();
1155 //==========================================================================
1157 // COMMAND MasterList
1159 //==========================================================================
1160 COMMAND(MasterList
) {
1161 ((VNetwork
*)GNet
)->MasterList();