package peer import ( "fmt" "io" "log" "runtime/debug" "vppn/fasttime" ) func (peer *Peer) netReader() { defer func() { if r := recover(); r != nil { fmt.Println("stacktrace from panic: \n" + string(debug.Stack())) } }() var ( n int //srcAddr *net.UDPAddr nonce Nonce packet = make([]byte, BUFFER_SIZE) decrypted = make([]byte, BUFFER_SIZE) toWrite []byte route *route ok bool err error conn = peer.conn ip = peer.ip counters = [2][256]uint64{} // Counter by stream and IP. ifaceChan = make(chan []byte, 1024) reqPool = make(chan []byte, 1024) ) for range cap(reqPool) { reqPool <- make([]byte, BUFFER_SIZE) } go ifWriter(ifaceChan, peer.iface, reqPool) NEXT_PACKET: n, _, err = conn.ReadFromUDPAddrPort(packet[:BUFFER_SIZE]) if err != nil { log.Fatalf("Failed to read UDP packet: %v", err) } if n < NONCE_SIZE { log.Printf("Dropping short UDP packet: %d", n) goto NEXT_PACKET } packet = packet[:n] ParseNonceBytes(packet[n-NONCE_SIZE:], &nonce) // Drop after 8 seconds. if CounterTimestamp(nonce.Counter) < fasttime.Now()-8 { log.Printf("Dropping old packet: %d", CounterTimestamp(nonce.Counter)) goto NEXT_PACKET } if nonce.StreamID > 1 { log.Printf("Dropping invalid stream ID: %v", nonce) goto NEXT_PACKET } // Check source counter. if nonce.Counter <= counters[nonce.StreamID][nonce.SourceIP] { log.Printf("Dropping packet with bad counter: %v", nonce) goto NEXT_PACKET } counters[nonce.StreamID][nonce.SourceIP] = nonce.Counter route = peer.router.GetRoute(nonce.SourceIP) if route == nil { log.Printf("Dropping packet without route: %v", nonce) goto NEXT_PACKET } switch ip { case nonce.DestIP: goto DECRYPT case nonce.ViaIP: goto VALIDATE_SIGNATURE default: log.Printf("Bad packet: %v", nonce) goto NEXT_PACKET } DECRYPT: decrypted, ok = decryptPacket(route.EncSharedKey, packet, decrypted) if !ok { log.Printf("Failed to decrypt packet: %v", nonce) goto NEXT_PACKET } switch nonce.StreamID { case STREAM_DATA: goto WRITE_IFACE_DATA case STREAM_ROUTING: goto WRITE_ROUTING_PACKET default: log.Printf("Invalid stream ID: %d", nonce.StreamID) goto NEXT_PACKET } WRITE_IFACE_DATA: //toWrite = toWrite[:len(decrypted)] //copy(toWrite, decrypted) toWrite = <-reqPool ifaceChan <- append(toWrite[:0], decrypted...) goto NEXT_PACKET WRITE_ROUTING_PACKET: //peer.processRoutingPacket(decrypted) //peer.routeManager.ProcessPacket(decrypted) goto NEXT_PACKET VALIDATE_SIGNATURE: // We don't forward twice. if route.Mediator { log.Printf("Dropping double-forward packet: %v", nonce) goto NEXT_PACKET } decrypted, ok = openPacket(route.SignPubKey, packet, decrypted) if !ok { log.Printf("Failed to open signed packet: %v", nonce) goto NEXT_PACKET } if _, err = conn.WriteToUDPAddrPort(decrypted, route.Addr); err != nil { log.Fatalf("Failed to forward packet: %v", err) } goto NEXT_PACKET } func ifWriter(in chan []byte, iface io.ReadWriteCloser, out chan []byte) { var err error for packet := range in { if _, err = iface.Write(packet); err != nil { log.Printf("Size: %d", len(packet)) log.Fatalf("Failed to write to interface: %v", err) } out <- packet } }