142 lines
2.6 KiB
Go
142 lines
2.6 KiB
Go
package peer
|
|
|
|
import (
|
|
"log"
|
|
"net/netip"
|
|
"sync/atomic"
|
|
)
|
|
|
|
type connReader struct {
|
|
conn udpReader
|
|
iface ifWriter
|
|
sender encryptedPacketSender
|
|
super controlMsgHandler
|
|
localIP byte
|
|
routes [256]*atomic.Pointer[peerRoute]
|
|
|
|
buf []byte
|
|
decBuf []byte
|
|
dupChecks [256]*dupCheck
|
|
}
|
|
|
|
func newConnReader(
|
|
conn udpReader,
|
|
ifWriter ifWriter,
|
|
sender encryptedPacketSender,
|
|
super controlMsgHandler,
|
|
localIP byte,
|
|
routes [256]*atomic.Pointer[peerRoute],
|
|
) *connReader {
|
|
return &connReader{
|
|
conn: conn,
|
|
iface: ifWriter,
|
|
sender: sender,
|
|
super: super,
|
|
localIP: localIP,
|
|
routes: routes,
|
|
buf: make([]byte, bufferSize),
|
|
decBuf: make([]byte, bufferSize),
|
|
dupChecks: func() (out [256]*dupCheck) {
|
|
for i := range out {
|
|
out[i] = newDupCheck(0)
|
|
}
|
|
return
|
|
}(),
|
|
}
|
|
}
|
|
|
|
func (r *connReader) Run() {
|
|
for {
|
|
r.handleNextPacket()
|
|
}
|
|
}
|
|
|
|
func (r *connReader) logf(s string, args ...any) {
|
|
log.Printf("[ConnReader] "+s, args...)
|
|
}
|
|
|
|
func (r *connReader) handleNextPacket() {
|
|
buf := r.buf[:bufferSize]
|
|
n, remoteAddr, err := r.conn.ReadFromUDPAddrPort(buf)
|
|
if err != nil {
|
|
log.Fatalf("Failed to read from UDP port: %v", err)
|
|
}
|
|
|
|
if n < headerSize {
|
|
return
|
|
}
|
|
|
|
remoteAddr = netip.AddrPortFrom(remoteAddr.Addr().Unmap(), remoteAddr.Port())
|
|
|
|
buf = buf[:n]
|
|
h, ok := parseHeader(buf)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
route := r.routes[h.SourceIP].Load()
|
|
|
|
switch h.StreamID {
|
|
case controlStreamID:
|
|
r.handleControlPacket(route, remoteAddr, h, buf)
|
|
|
|
case dataStreamID:
|
|
r.handleDataPacket(route, h, buf)
|
|
|
|
default:
|
|
r.logf("Unknown stream ID: %d", h.StreamID)
|
|
}
|
|
}
|
|
|
|
func (r *connReader) handleControlPacket(
|
|
route *peerRoute,
|
|
addr netip.AddrPort,
|
|
h header,
|
|
enc []byte,
|
|
) {
|
|
if route.ControlCipher == nil {
|
|
return
|
|
}
|
|
|
|
if h.DestIP != r.localIP {
|
|
r.logf("Incorrect destination IP on control packet: %d", h.DestIP)
|
|
return
|
|
}
|
|
|
|
msg, err := decryptControlPacket(route, addr, h, enc, r.decBuf)
|
|
if err != nil {
|
|
r.logf("Failed to decrypt control packet: %v", err)
|
|
return
|
|
}
|
|
|
|
r.super.HandleControlMsg(msg)
|
|
}
|
|
|
|
func (r *connReader) handleDataPacket(route *peerRoute, h header, enc []byte) {
|
|
if !route.Up {
|
|
r.logf("Not connected (recv).")
|
|
return
|
|
}
|
|
|
|
data, err := decryptDataPacket(route, h, enc, r.decBuf)
|
|
if err != nil {
|
|
r.logf("Failed to decrypt data packet: %v", err)
|
|
return
|
|
}
|
|
|
|
if h.DestIP == r.localIP {
|
|
if _, err := r.iface.Write(data); err != nil {
|
|
log.Fatalf("Failed to write to interface: %v", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
destRoute := r.routes[h.DestIP].Load()
|
|
if !destRoute.Up {
|
|
r.logf("Not connected (relay): %d", destRoute.IP)
|
|
return
|
|
}
|
|
|
|
r.sender.SendEncryptedDataPacket(data, destRoute)
|
|
}
|