2019-01-02 01:55:51 +01:00
/ * SPDX - License - Identifier : MIT
2018-05-03 15:04:00 +02:00
*
2021-01-28 17:52:15 +01:00
* Copyright ( C ) 2017 - 2021 WireGuard LLC . All Rights Reserved .
2018-05-03 15:04:00 +02:00
* /
2019-03-03 04:04:41 +01:00
package device
2017-07-01 23:29:22 +02:00
import (
"bytes"
"encoding/binary"
2021-01-08 14:25:37 +01:00
"errors"
2021-08-16 20:58:15 +02:00
"fmt"
2017-07-01 23:29:22 +02:00
"net"
2021-08-21 16:54:24 +02:00
"strconv"
2017-07-01 23:29:22 +02:00
"sync"
"sync/atomic"
"time"
2019-05-14 09:09:52 +02:00
"golang.org/x/crypto/chacha20poly1305"
2021-01-08 14:25:37 +01:00
2021-08-20 19:32:50 +02:00
"github.com/KusakabeSi/EtherGuardVPN/config"
2021-08-16 02:43:17 +02:00
"github.com/KusakabeSi/EtherGuardVPN/conn"
2021-08-16 20:58:15 +02:00
"github.com/KusakabeSi/EtherGuardVPN/path"
"github.com/KusakabeSi/EtherGuardVPN/tap"
2017-07-01 23:29:22 +02:00
)
type QueueHandshakeElement struct {
2017-10-07 22:35:23 +02:00
msgType uint32
packet [ ] byte
2019-11-07 17:13:05 +01:00
endpoint conn . Endpoint
2017-10-07 22:35:23 +02:00
buffer * [ MaxMessageSize ] byte
2017-07-01 23:29:22 +02:00
}
type QueueInboundElement struct {
2019-01-03 19:04:00 +01:00
sync . Mutex
2017-11-14 16:27:53 +01:00
buffer * [ MaxMessageSize ] byte
packet [ ] byte
counter uint64
2018-05-13 18:23:40 +02:00
keypair * Keypair
2019-11-07 17:13:05 +01:00
endpoint conn . Endpoint
2017-07-01 23:29:22 +02:00
}
2020-12-05 00:36:21 +01:00
// clearPointers clears elem fields that contain pointers.
// This makes the garbage collector's life easier and
// avoids accidentally keeping other objects around unnecessarily.
// It also reduces the possible collateral damage from use-after-free bugs.
func ( elem * QueueInboundElement ) clearPointers ( ) {
elem . buffer = nil
elem . packet = nil
elem . keypair = nil
elem . endpoint = nil
}
2018-05-07 22:27:03 +02:00
/ * Called when a new authenticated message has been received
*
* NOTE : Not thread safe , but called by sequential receiver !
* /
func ( peer * Peer ) keepKeyFreshReceiving ( ) {
2018-05-20 06:50:07 +02:00
if peer . timers . sentLastMinuteHandshake . Get ( ) {
2018-05-07 22:27:03 +02:00
return
}
2018-05-13 23:14:43 +02:00
keypair := peer . keypairs . Current ( )
2019-06-03 21:46:46 +02:00
if keypair != nil && keypair . isInitiator && time . Since ( keypair . created ) > ( RejectAfterTime - KeepaliveTimeout - RekeyTimeout ) {
2018-05-20 06:50:07 +02:00
peer . timers . sentLastMinuteHandshake . Set ( true )
2018-05-07 22:27:03 +02:00
peer . SendHandshakeInitiation ( false )
}
}
2017-12-01 23:37:26 +01:00
/ * Receives incoming datagrams for the device
*
* Every time the bind is updated a new routine is started for
* IPv4 and IPv6 ( separately )
* /
2021-03-31 22:55:18 +02:00
func ( device * Device ) RoutineReceiveIncoming ( recv conn . ReceiveFunc ) {
2021-04-10 01:21:35 +02:00
recvName := recv . PrettyName ( )
2018-05-01 16:59:13 +02:00
defer func ( ) {
2021-04-10 01:21:35 +02:00
device . log . Verbosef ( "Routine: receive incoming %s - stopped" , recvName )
2021-01-12 02:34:02 +01:00
device . queue . decryption . wg . Done ( )
2021-01-29 18:24:45 +01:00
device . queue . handshake . wg . Done ( )
2018-05-20 06:19:29 +02:00
device . net . stopping . Done ( )
2018-05-01 16:59:13 +02:00
} ( )
2021-04-10 01:21:35 +02:00
device . log . Verbosef ( "Routine: receive incoming %s - started" , recvName )
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
// receive datagrams until conn is closed
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
buffer := device . GetMessageBuffer ( )
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
var (
2021-01-08 14:25:37 +01:00
err error
size int
endpoint conn . Endpoint
deathSpiral int
2017-12-01 00:03:06 +01:00
)
2017-10-07 22:35:23 +02:00
2017-12-01 00:03:06 +01:00
for {
2021-03-31 22:55:18 +02:00
size , endpoint , err = recv ( buffer [ : ] )
2017-08-04 16:15:53 +02:00
2017-12-01 00:03:06 +01:00
if err != nil {
2018-09-16 21:50:58 +02:00
device . PutMessageBuffer ( buffer )
2021-02-16 21:05:25 +01:00
if errors . Is ( err , net . ErrClosed ) {
2021-01-08 14:25:37 +01:00
return
}
2021-05-07 12:21:21 +02:00
device . log . Verbosef ( "Failed to receive %s packet: %v" , recvName , err )
2021-03-30 21:36:59 +02:00
if neterr , ok := err . ( net . Error ) ; ok && ! neterr . Temporary ( ) {
return
}
2021-01-08 14:25:37 +01:00
if deathSpiral < 10 {
deathSpiral ++
time . Sleep ( time . Second / 3 )
2021-04-12 13:50:58 +02:00
buffer = device . GetMessageBuffer ( )
2021-01-08 14:25:37 +01:00
continue
}
2017-12-01 00:03:06 +01:00
return
}
2021-01-08 14:25:37 +01:00
deathSpiral = 0
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
if size < MinMessageSize {
continue
}
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
// check size of packet
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
packet := buffer [ : size ]
msgType := binary . LittleEndian . Uint32 ( packet [ : 4 ] )
2017-08-04 16:15:53 +02:00
2017-12-01 00:03:06 +01:00
var okay bool
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
switch msgType {
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
// check if transport
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
case MessageTransportType :
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
// check size
2017-07-01 23:29:22 +02:00
2018-09-20 14:28:53 +02:00
if len ( packet ) < MessageTransportSize {
2017-12-01 00:03:06 +01:00
continue
}
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
// lookup key pair
2017-08-07 15:25:04 +02:00
2017-12-01 00:03:06 +01:00
receiver := binary . LittleEndian . Uint32 (
packet [ MessageTransportOffsetReceiver : MessageTransportOffsetCounter ] ,
)
2018-05-13 18:23:40 +02:00
value := device . indexTable . Lookup ( receiver )
keypair := value . keypair
if keypair == nil {
2017-12-01 00:03:06 +01:00
continue
}
2017-07-01 23:29:22 +02:00
2018-05-13 19:50:58 +02:00
// check keypair expiry
2017-07-01 23:29:22 +02:00
2018-05-13 18:23:40 +02:00
if keypair . created . Add ( RejectAfterTime ) . Before ( time . Now ( ) ) {
2017-12-01 00:03:06 +01:00
continue
}
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
// create work element
peer := value . peer
2018-09-22 06:29:02 +02:00
elem := device . GetInboundElement ( )
elem . packet = packet
elem . buffer = buffer
elem . keypair = keypair
elem . endpoint = endpoint
elem . counter = 0
2019-01-03 19:04:00 +01:00
elem . Mutex = sync . Mutex { }
elem . Lock ( )
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
// add to decryption queues
2018-01-26 22:52:32 +01:00
if peer . isRunning . Get ( ) {
2021-02-09 15:09:50 +01:00
peer . queue . inbound . c <- elem
2021-01-12 02:21:16 +01:00
device . queue . decryption . c <- elem
buffer = device . GetMessageBuffer ( )
2020-12-22 18:52:53 +01:00
} else {
device . PutInboundElement ( elem )
2018-01-26 22:52:32 +01:00
}
2017-12-01 00:03:06 +01:00
continue
2017-07-01 23:29:22 +02:00
2017-12-01 00:03:06 +01:00
// otherwise it is a fixed size & handshake related packet
2017-08-07 15:25:04 +02:00
2017-12-01 00:03:06 +01:00
case MessageInitiationType :
okay = len ( packet ) == MessageInitiationSize
2017-08-07 15:25:04 +02:00
2017-12-01 00:03:06 +01:00
case MessageResponseType :
okay = len ( packet ) == MessageResponseSize
2017-08-07 15:25:04 +02:00
2017-12-01 00:03:06 +01:00
case MessageCookieReplyType :
okay = len ( packet ) == MessageCookieReplySize
2018-05-05 02:20:52 +02:00
default :
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "Received message with unknown type" )
2017-12-01 00:03:06 +01:00
}
2017-08-07 15:25:04 +02:00
2017-12-01 00:03:06 +01:00
if okay {
2021-01-29 18:24:45 +01:00
select {
case device . queue . handshake . c <- QueueHandshakeElement {
msgType : msgType ,
buffer : buffer ,
packet : packet ,
endpoint : endpoint ,
} :
2018-09-16 21:50:58 +02:00
buffer = device . GetMessageBuffer ( )
2021-01-29 18:24:45 +01:00
default :
2018-09-16 21:50:58 +02:00
}
2017-08-07 15:25:04 +02:00
}
2017-07-01 23:29:22 +02:00
}
}
2021-05-07 12:21:21 +02:00
func ( device * Device ) RoutineDecryption ( id int ) {
2017-07-01 23:29:22 +02:00
var nonce [ chacha20poly1305 . NonceSize ] byte
2021-01-19 20:10:05 +01:00
2021-05-07 12:21:21 +02:00
defer device . log . Verbosef ( "Routine: decryption worker %d - stopped" , id )
device . log . Verbosef ( "Routine: decryption worker %d - started" , id )
2017-07-06 15:43:55 +02:00
2021-01-12 02:34:02 +01:00
for elem := range device . queue . decryption . c {
// split message into fields
counter := elem . packet [ MessageTransportOffsetCounter : MessageTransportOffsetContent ]
content := elem . packet [ MessageTransportOffsetContent : ]
2017-09-09 15:03:01 +02:00
2021-01-12 02:34:02 +01:00
// decrypt and release to consumer
var err error
elem . counter = binary . LittleEndian . Uint64 ( counter )
// copy counter to nonce
binary . LittleEndian . PutUint64 ( nonce [ 0x4 : 0xc ] , elem . counter )
elem . packet , err = elem . keypair . receive . Open (
content [ : 0 ] ,
nonce [ : ] ,
content ,
nil ,
)
if err != nil {
2021-01-17 18:49:39 +01:00
elem . packet = nil
2017-07-01 23:29:22 +02:00
}
2021-01-12 02:34:02 +01:00
elem . Unlock ( )
2017-07-01 23:29:22 +02:00
}
}
2017-12-01 23:37:26 +01:00
/ * Handles incoming packets related to handshake
2017-07-01 23:29:22 +02:00
* /
2021-05-07 12:21:21 +02:00
func ( device * Device ) RoutineHandshake ( id int ) {
2021-02-09 19:26:45 +01:00
defer func ( ) {
2021-05-07 12:21:21 +02:00
device . log . Verbosef ( "Routine: handshake worker %d - stopped" , id )
2021-02-09 19:26:45 +01:00
device . queue . encryption . wg . Done ( )
} ( )
2021-05-07 12:21:21 +02:00
device . log . Verbosef ( "Routine: handshake worker %d - started" , id )
2017-07-01 23:29:22 +02:00
2021-01-29 18:24:45 +01:00
for elem := range device . queue . handshake . c {
2018-05-01 16:59:13 +02:00
2017-08-07 15:25:04 +02:00
// handle cookie fields and ratelimiting
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
switch elem . msgType {
2017-07-08 09:23:10 +02:00
2017-08-07 15:25:04 +02:00
case MessageCookieReplyType :
2017-08-14 17:09:25 +02:00
// unmarshal packet
2017-08-07 15:25:04 +02:00
var reply MessageCookieReply
reader := bytes . NewReader ( elem . packet )
err := binary . Read ( reader , binary . LittleEndian , & reply )
if err != nil {
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "Failed to decode cookie reply" )
2021-01-29 18:24:45 +01:00
goto skip
2017-07-08 09:23:10 +02:00
}
2017-08-14 17:09:25 +02:00
2018-01-26 22:52:32 +01:00
// lookup peer from index
2017-08-14 17:09:25 +02:00
2018-05-13 18:23:40 +02:00
entry := device . indexTable . Lookup ( reply . Receiver )
2018-01-26 22:52:32 +01:00
2017-08-14 17:09:25 +02:00
if entry . peer == nil {
2021-01-29 18:24:45 +01:00
goto skip
2017-08-14 17:09:25 +02:00
}
2018-01-26 22:52:32 +01:00
// consume reply
if peer := entry . peer ; peer . isRunning . Get ( ) {
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "Receiving cookie response from %s" , elem . endpoint . DstToString ( ) )
2018-12-19 00:35:53 +01:00
if ! peer . cookieGenerator . ConsumeReply ( & reply ) {
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "Could not decrypt invalid cookie response" )
2018-12-19 00:35:53 +01:00
}
2018-01-26 22:52:32 +01:00
}
2021-01-29 18:24:45 +01:00
goto skip
2017-07-08 09:23:10 +02:00
2017-08-07 15:25:04 +02:00
case MessageInitiationType , MessageResponseType :
2017-07-08 09:23:10 +02:00
2018-05-13 23:14:43 +02:00
// check mac fields and maybe ratelimit
2017-07-08 09:23:10 +02:00
2018-05-13 23:14:43 +02:00
if ! device . cookieChecker . CheckMAC1 ( elem . packet ) {
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "Received packet with invalid mac1" )
2021-01-29 18:24:45 +01:00
goto skip
2017-07-08 09:23:10 +02:00
}
2017-11-17 17:25:45 +01:00
// endpoints destination address is the source of the datagram
2017-08-11 16:18:20 +02:00
if device . IsUnderLoad ( ) {
2017-10-08 22:03:32 +02:00
// verify MAC2 field
2018-05-13 23:14:43 +02:00
if ! device . cookieChecker . CheckMAC2 ( elem . packet , elem . endpoint . DstToBytes ( ) ) {
device . SendHandshakeCookie ( & elem )
2021-01-29 18:24:45 +01:00
goto skip
2017-08-07 15:25:04 +02:00
}
2017-08-11 16:18:20 +02:00
2017-10-08 22:03:32 +02:00
// check ratelimiter
2018-02-02 16:40:14 +01:00
if ! device . rate . limiter . Allow ( elem . endpoint . DstIP ( ) ) {
2021-01-29 18:24:45 +01:00
goto skip
2017-08-07 15:25:04 +02:00
}
2017-07-11 18:48:29 +02:00
}
2017-08-07 15:25:04 +02:00
default :
2021-01-26 23:05:48 +01:00
device . log . Errorf ( "Invalid packet ended up in the handshake queue" )
2021-01-29 18:24:45 +01:00
goto skip
2017-08-07 15:25:04 +02:00
}
2017-07-08 09:23:10 +02:00
2017-12-01 23:37:26 +01:00
// handle handshake initiation/response content
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
switch elem . msgType {
case MessageInitiationType :
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
// unmarshal
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
var msg MessageInitiation
reader := bytes . NewReader ( elem . packet )
err := binary . Read ( reader , binary . LittleEndian , & msg )
if err != nil {
2021-01-26 23:05:48 +01:00
device . log . Errorf ( "Failed to decode initiation message" )
2021-01-29 18:24:45 +01:00
goto skip
2017-08-07 15:25:04 +02:00
}
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
// consume initiation
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
peer := device . ConsumeMessageInitiation ( & msg )
if peer == nil {
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "Received invalid initiation message from %s" , elem . endpoint . DstToString ( ) )
2021-01-29 18:24:45 +01:00
goto skip
2017-08-07 15:25:04 +02:00
}
2017-08-04 16:15:53 +02:00
2017-08-07 15:25:04 +02:00
// update timers
2017-08-04 16:15:53 +02:00
2018-05-07 22:27:03 +02:00
peer . timersAnyAuthenticatedPacketTraversal ( )
peer . timersAnyAuthenticatedPacketReceived ( )
2017-07-07 13:47:09 +02:00
2017-08-07 15:25:04 +02:00
// update endpoint
2018-05-26 02:59:26 +02:00
peer . SetEndpointFromPacket ( elem . endpoint )
2017-07-13 21:29:22 +02:00
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "%v - Received handshake initiation" , peer )
2019-06-11 18:13:52 +02:00
atomic . AddUint64 ( & peer . stats . rxBytes , uint64 ( len ( elem . packet ) ) )
2018-04-20 07:13:40 +02:00
2018-05-13 23:14:43 +02:00
peer . SendHandshakeResponse ( )
2017-07-14 14:25:18 +02:00
2017-08-07 15:25:04 +02:00
case MessageResponseType :
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
// unmarshal
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
var msg MessageResponse
reader := bytes . NewReader ( elem . packet )
err := binary . Read ( reader , binary . LittleEndian , & msg )
if err != nil {
2021-01-26 23:05:48 +01:00
device . log . Errorf ( "Failed to decode response message" )
2021-01-29 18:24:45 +01:00
goto skip
2017-08-07 15:25:04 +02:00
}
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
// consume response
2017-07-01 23:29:22 +02:00
2017-08-07 15:25:04 +02:00
peer := device . ConsumeMessageResponse ( & msg )
if peer == nil {
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "Received invalid response message from %s" , elem . endpoint . DstToString ( ) )
2021-01-29 18:24:45 +01:00
goto skip
2017-08-07 15:25:04 +02:00
}
2017-07-27 23:45:37 +02:00
2017-11-14 16:27:53 +01:00
// update endpoint
2018-05-26 02:59:26 +02:00
peer . SetEndpointFromPacket ( elem . endpoint )
2017-11-14 16:27:53 +01:00
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "%v - Received handshake response" , peer )
2019-06-11 18:13:52 +02:00
atomic . AddUint64 ( & peer . stats . rxBytes , uint64 ( len ( elem . packet ) ) )
2017-09-20 09:26:08 +02:00
2017-08-07 15:25:04 +02:00
// update timers
2017-08-04 16:15:53 +02:00
2018-05-07 22:27:03 +02:00
peer . timersAnyAuthenticatedPacketTraversal ( )
peer . timersAnyAuthenticatedPacketReceived ( )
2017-08-04 16:15:53 +02:00
2018-05-13 19:50:58 +02:00
// derive keypair
2017-07-01 23:29:22 +02:00
2018-05-13 23:14:43 +02:00
err = peer . BeginSymmetricSession ( )
if err != nil {
2021-01-26 23:05:48 +01:00
device . log . Errorf ( "%v - Failed to derive keypair: %v" , peer , err )
2021-01-29 18:24:45 +01:00
goto skip
2018-05-07 22:27:03 +02:00
}
2018-05-13 23:14:43 +02:00
peer . timersSessionDerived ( )
2018-05-07 22:27:03 +02:00
peer . timersHandshakeComplete ( )
peer . SendKeepalive ( )
2017-08-07 15:25:04 +02:00
}
2021-01-29 18:24:45 +01:00
skip :
device . PutMessageBuffer ( elem . buffer )
2017-07-01 23:29:22 +02:00
}
}
func ( peer * Peer ) RoutineSequentialReceiver ( ) {
device := peer . device
2021-08-16 20:58:15 +02:00
var peer_out * Peer
2018-04-18 20:29:48 +02:00
defer func ( ) {
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "%v - Routine: sequential receiver - stopped" , peer )
2021-01-29 14:54:11 +01:00
peer . stopping . Done ( )
2018-02-04 19:18:44 +01:00
} ( )
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "%v - Routine: sequential receiver - started" , peer )
2018-02-02 16:40:14 +01:00
2021-02-09 15:09:50 +01:00
for elem := range peer . queue . inbound . c {
2021-02-08 22:02:52 +01:00
if elem == nil {
return
}
2021-08-21 16:54:24 +02:00
var EgHeader path . EgHeader
2021-01-29 14:54:11 +01:00
var err error
2021-08-20 19:32:50 +02:00
var src_nodeID config . Vertex
var dst_nodeID config . Vertex
var packet_type path . Usage
should_process := false
2021-08-16 20:58:15 +02:00
should_receive := false
should_transfer := false
2019-03-21 21:43:04 +01:00
elem . Lock ( )
2021-01-17 18:49:39 +01:00
if elem . packet == nil {
// decryption failed
2021-01-29 14:54:11 +01:00
goto skip
2019-03-21 21:43:04 +01:00
}
2017-07-10 12:09:19 +02:00
2019-03-21 21:43:04 +01:00
if ! elem . keypair . replayFilter . ValidateCounter ( elem . counter , RejectAfterMessages ) {
2021-01-29 14:54:11 +01:00
goto skip
2019-03-21 21:43:04 +01:00
}
2017-07-08 23:51:26 +02:00
2019-03-21 21:43:04 +01:00
peer . SetEndpointFromPacket ( elem . endpoint )
if peer . ReceivedWithKeypair ( elem . keypair ) {
peer . timersHandshakeComplete ( )
2021-01-27 18:13:53 +01:00
peer . SendStagedPackets ( )
2019-03-21 21:43:04 +01:00
}
2017-07-01 23:29:22 +02:00
2019-03-21 21:43:04 +01:00
peer . keepKeyFreshReceiving ( )
peer . timersAnyAuthenticatedPacketTraversal ( )
peer . timersAnyAuthenticatedPacketReceived ( )
2019-06-11 18:13:52 +02:00
atomic . AddUint64 ( & peer . stats . rxBytes , uint64 ( len ( elem . packet ) + MinMessageSize ) )
2017-07-01 23:29:22 +02:00
2019-03-21 21:43:04 +01:00
if len ( elem . packet ) == 0 {
2021-01-26 23:05:48 +01:00
device . log . Verbosef ( "%v - Receiving keepalive packet" , peer )
2021-01-29 14:54:11 +01:00
goto skip
2019-03-21 21:43:04 +01:00
}
peer . timersDataReceived ( )
2017-07-08 09:23:10 +02:00
2021-08-23 18:39:04 +02:00
if len ( elem . packet ) <= path . EgHeaderLen {
device . log . Errorf ( "Invalid EgHeader from peer %v" , peer )
goto skip
}
2021-08-21 16:54:24 +02:00
EgHeader , err = path . NewEgHeader ( elem . packet [ 0 : path . EgHeaderLen ] ) // EG header
src_nodeID = EgHeader . GetSrc ( )
dst_nodeID = EgHeader . GetDst ( )
elem . packet = elem . packet [ : EgHeader . GetPacketLength ( ) + path . EgHeaderLen ] // EG header + true packet
packet_type = EgHeader . GetUsage ( )
2021-08-20 19:32:50 +02:00
if device . IsSuperNode {
peer . LastPingReceived = time . Now ( )
switch dst_nodeID {
2021-08-25 10:13:53 +02:00
case config . ControlMessage :
2021-08-20 19:32:50 +02:00
should_process = true
2021-08-25 10:13:53 +02:00
case config . SuperNodeMessage :
2021-08-20 19:32:50 +02:00
should_process = true
default :
device . log . Errorf ( "Invalid dst_nodeID received. Check your code for bug" )
}
2021-08-16 20:58:15 +02:00
} else {
2021-08-20 19:32:50 +02:00
switch dst_nodeID {
2021-08-25 10:13:53 +02:00
case config . Boardcast :
2021-08-20 19:32:50 +02:00
should_receive = true
should_transfer = true
2021-08-25 10:13:53 +02:00
case config . PingMessage :
2021-08-20 19:32:50 +02:00
peer . LastPingReceived = time . Now ( )
should_process = true
2021-08-25 10:13:53 +02:00
case config . SuperNodeMessage :
2021-08-20 19:32:50 +02:00
should_process = true
2021-08-25 10:13:53 +02:00
case config . ControlMessage :
2021-08-21 16:54:24 +02:00
packet := elem . packet [ path . EgHeaderLen : ] //true packet
2021-08-20 19:32:50 +02:00
if device . CheckNoDup ( packet ) {
should_process = true
should_transfer = true
} else {
should_process = false
should_transfer = false
2021-08-25 10:13:53 +02:00
if device . LogLevel . LogTransit {
2021-08-25 13:54:13 +02:00
fmt . Printf ( "Transit: Duplicate packet received from %d through %d , src_nodeID = %d . Dropeed.\n" , peer . ID , device . ID , src_nodeID )
2021-08-20 19:32:50 +02:00
}
}
case device . ID :
if packet_type == path . NornalPacket {
should_receive = true
} else {
should_process = true
}
default :
2021-08-25 11:18:54 +02:00
if device . graph . Next ( device . ID , dst_nodeID ) != nil {
2021-08-20 19:32:50 +02:00
should_transfer = true
} else {
device . log . Verbosef ( "No route to peer ID %v" , dst_nodeID )
}
}
2019-03-21 21:43:04 +01:00
}
2021-08-20 19:32:50 +02:00
if should_transfer {
2021-08-21 16:54:24 +02:00
l2ttl := EgHeader . GetTTL ( )
2021-08-16 20:58:15 +02:00
if l2ttl == 0 {
device . log . Verbosef ( "TTL is 0 %v" , dst_nodeID )
} else {
2021-08-21 16:54:24 +02:00
EgHeader . SetTTL ( l2ttl - 1 )
2021-08-25 10:13:53 +02:00
if dst_nodeID == config . Boardcast { //Regular transfer algorithm
2021-08-20 19:32:50 +02:00
device . TransitBoardcastPacket ( src_nodeID , peer . ID , elem . packet , MessageTransportOffsetContent )
2021-08-25 10:13:53 +02:00
} else if dst_nodeID == config . ControlMessage { // Control Message will try send to every know node regardless the connectivity
2021-08-20 19:32:50 +02:00
skip_list := make ( map [ config . Vertex ] bool )
skip_list [ src_nodeID ] = true //Don't send to conimg peer and source peer
skip_list [ peer . ID ] = true
device . SpreadPacket ( skip_list , elem . packet , MessageTransportOffsetContent )
} else {
2021-08-25 11:18:54 +02:00
next_id := device . graph . Next ( device . ID , dst_nodeID )
if next_id != nil {
peer_out = device . peers . IDMap [ * next_id ]
if device . LogLevel . LogTransit {
2021-08-25 13:54:13 +02:00
fmt . Printf ( "Transit: Transfer packet from %d through %d to %d\n" , peer . ID , device . ID , peer_out . ID )
2021-08-25 11:18:54 +02:00
}
device . SendPacket ( peer_out , elem . packet , MessageTransportOffsetContent )
2021-08-16 20:58:15 +02:00
}
}
}
2020-09-22 00:17:16 +02:00
}
2021-08-16 20:58:15 +02:00
2021-08-20 19:32:50 +02:00
if should_process {
if packet_type != path . NornalPacket {
2021-08-25 10:13:53 +02:00
if device . LogLevel . LogControl {
2021-08-21 16:54:24 +02:00
if peer . GetEndpointDstStr ( ) != "" {
2021-08-25 13:54:13 +02:00
fmt . Println ( "Control: Received MID:" + strconv . Itoa ( int ( EgHeader . GetMessageID ( ) ) ) + " From:" + peer . GetEndpointDstStr ( ) + " " + device . sprint_received ( packet_type , elem . packet [ path . EgHeaderLen : ] ) )
2021-08-21 16:54:24 +02:00
}
}
2021-08-23 18:39:04 +02:00
err = device . process_received ( packet_type , peer , elem . packet [ path . EgHeaderLen : ] )
2021-08-21 16:54:24 +02:00
if err != nil {
device . log . Errorf ( err . Error ( ) )
}
2021-08-16 20:58:15 +02:00
}
2021-08-20 19:32:50 +02:00
}
if should_receive { // Write message to tap device
if packet_type == path . NornalPacket {
2021-08-25 10:13:53 +02:00
if device . LogLevel . LogNormal {
2021-08-25 13:54:13 +02:00
fmt . Println ( "Normal: Reveived Normal packet From:" + peer . GetEndpointDstStr ( ) + " SrcID:" + src_nodeID . ToString ( ) + " DstID:" + dst_nodeID . ToString ( ) + " Len:" + strconv . Itoa ( len ( elem . packet ) ) )
2021-08-25 10:13:53 +02:00
}
2021-08-23 18:39:04 +02:00
if len ( elem . packet ) <= path . EgHeaderLen + 12 {
device . log . Errorf ( "Invalid normal packet from peer %v" , peer )
goto skip
}
2021-08-20 19:32:50 +02:00
src_macaddr := tap . GetSrcMacAddr ( elem . packet [ path . EgHeaderLen : ] )
2021-08-24 10:43:55 +02:00
if ! tap . IsNotUnicast ( src_macaddr ) {
2021-08-23 10:35:17 +02:00
device . l2fib . Store ( src_macaddr , src_nodeID ) // Write to l2fib table
}
2021-08-20 19:32:50 +02:00
_ , err = device . tap . device . Write ( elem . buffer [ : MessageTransportOffsetContent + len ( elem . packet ) ] , MessageTransportOffsetContent + path . EgHeaderLen )
if err != nil && ! device . isClosed ( ) {
device . log . Errorf ( "Failed to write packet to TUN device: %v" , err )
}
if len ( peer . queue . inbound . c ) == 0 {
err = device . tap . device . Flush ( )
if err != nil {
peer . device . log . Errorf ( "Unable to flush packets: %v" , err )
}
2021-08-16 20:58:15 +02:00
}
2019-07-01 15:23:24 +02:00
}
2019-03-21 21:43:04 +01:00
}
2021-08-16 20:58:15 +02:00
2021-01-29 14:54:11 +01:00
skip :
device . PutMessageBuffer ( elem . buffer )
device . PutInboundElement ( elem )
2017-07-01 23:29:22 +02:00
}
}