115 lines
2.2 KiB
Go
115 lines
2.2 KiB
Go
package peer
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"net/netip"
|
|
"runtime/debug"
|
|
"vppn/fasttime"
|
|
)
|
|
|
|
func (peer *Peer) ifReader() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
fmt.Println("stacktrace from panic: \n" + string(debug.Stack()))
|
|
}
|
|
}()
|
|
|
|
var (
|
|
n int
|
|
destIP byte
|
|
router = peer.router
|
|
route *route
|
|
iface = peer.iface
|
|
nonce = Nonce{
|
|
SourceIP: peer.ip,
|
|
PacketType: PACKET_TYPE_DATA,
|
|
StreamID: STREAM_DATA,
|
|
}
|
|
err error
|
|
now uint64
|
|
counterTS uint64
|
|
counter uint64
|
|
packet = make([]byte, BUFFER_SIZE)
|
|
encrypted = make([]byte, BUFFER_SIZE)
|
|
nonceBuf = make([]byte, NONCE_SIZE)
|
|
toSend []byte
|
|
signingKey = peer.signPrivKey
|
|
|
|
reqPool = make(chan udpWriteReq, 1024)
|
|
writeChan = make(chan udpWriteReq, 1024)
|
|
)
|
|
|
|
for range cap(reqPool) {
|
|
reqPool <- udpWriteReq{Packet: make([]byte, BUFFER_SIZE)}
|
|
}
|
|
|
|
go udpWriter(writeChan, peer.conn, reqPool)
|
|
|
|
for {
|
|
n, err = iface.Read(packet[:BUFFER_SIZE])
|
|
if err != nil {
|
|
log.Fatalf("Failed to read from interface: %v", err)
|
|
}
|
|
|
|
if n < 20 {
|
|
log.Printf("Dropping small packet: %d", n)
|
|
continue
|
|
}
|
|
|
|
packet = packet[:n]
|
|
|
|
destIP = packet[19]
|
|
route = router.GetRoute(destIP)
|
|
if route == nil {
|
|
log.Printf("Dropping packet for non-existent IP: %d", destIP)
|
|
continue
|
|
}
|
|
|
|
now = uint64(fasttime.Now())
|
|
if counterTS < now {
|
|
counterTS = now
|
|
counter = now << 30
|
|
}
|
|
|
|
counter++
|
|
|
|
nonce.Counter = counter
|
|
nonce.ViaIP = route.ViaIP
|
|
nonce.DestIP = destIP
|
|
|
|
MarshalNonce(nonce, nonceBuf)
|
|
|
|
encrypted = encryptPacket(route.EncSharedKey, nonceBuf, packet, encrypted)
|
|
|
|
if route.ViaIP != 0 {
|
|
toSend = signPacket(signingKey, encrypted, packet)
|
|
} else {
|
|
toSend = encrypted
|
|
}
|
|
|
|
req := <-reqPool
|
|
req.Addr = route.Addr
|
|
req.Packet = req.Packet[:len(toSend)]
|
|
copy(req.Packet, toSend)
|
|
|
|
writeChan <- req
|
|
}
|
|
}
|
|
|
|
type udpWriteReq struct {
|
|
Addr netip.AddrPort
|
|
Packet []byte
|
|
}
|
|
|
|
func udpWriter(in chan udpWriteReq, conn *net.UDPConn, reqPool chan udpWriteReq) {
|
|
var err error
|
|
for req := range in {
|
|
if _, err = conn.WriteToUDPAddrPort(req.Packet, req.Addr); err != nil {
|
|
log.Fatalf("Failed to write UDP packet: %v", err)
|
|
}
|
|
reqPool <- req
|
|
}
|
|
}
|