func startTransports(tt tuntap.Device) { defer tt.Close() tcpt, err := transports.NewTCPTransport("0.0.0.0") if err != nil { log.Printf("Error starting TCP transport: %s\n", err) return } udpt, err := transports.NewUDPTransport("0.0.0.0") if err != nil { log.Printf("Error starting UDP transport: %s\n", err) return } // Repeatedly accept clients. tcp_ch := tcpt.AcceptChannel() udp_ch := udpt.AcceptChannel() var client transports.PacketClient for { // TODO: have some way of stopping this select { case client = <-tcp_ch: case client = <-udp_ch: } go handleNewClient(tt, client) } }
// Authenticate and then handle the client. func handleNewClient(tt tuntap.Device, client transports.PacketClient) { log.Printf("Accepted new client (reliable = %t)\n", client.IsReliable()) // Set up encryption. enc_client, err := transports.NewEncryptedPacketClient(client, "foobar") if err != nil { log.Printf("Could not initialize encryption: %s\n", err) client.Close() return } defer enc_client.Close() recv_ch := enc_client.RecvChannel() send_ch := enc_client.SendChannel() for { select { case from_client := <-recv_ch: log.Printf("client --> tuntap (%d bytes)\n", len(from_client)) err = tt.Write(from_client) if err != nil { log.Printf("Error writing: %s\n", err) } case from_tuntap := <-tt.RecvChannel(): log.Printf("tuntap --> client (%d bytes)\n", len(from_tuntap)) send_ch <- from_tuntap case <-tt.EOFChannel(): log.Println("EOF received from TUN/TAP device, exiting...") return } } }
func startClient(tt tuntap.Device, hpserver string) { defer tt.Close() log.Printf("Holepunching with server %s...\n", hpserver) methods := strings.Split(method, ",") if len(methods) == 1 && methods[0] == "all" { methods = []string{"tcp", "udp", "icmp", "dns"} } var conn transports.PacketClient var err error for _, m := range methods { var curr_conn transports.PacketClient err = nil switch m { case "tcp": curr_conn, err = transports.NewTCPPacketClient(hpserver) case "udp": curr_conn, err = transports.NewUDPPacketClient(hpserver) default: log.Printf("Unknown method: %s\n", m) continue } if err != nil { log.Printf("Error creating transport '%s': %s\n", m, err) continue } // Set up encryption. enc_conn, err := transports.NewEncryptedPacketClient(curr_conn, "foobar") if err != nil { log.Printf("Could not initialize encryption: %s\n", err) curr_conn.Close() continue } // Encryption is valid, which means that we're authenticated. conn = enc_conn } if conn == nil { log.Printf("Could not create connection to server, exiting...\n") return } log.Printf("Connected to server (reliable = %t)\n", conn.IsReliable()) recv_ch := conn.RecvChannel() send_ch := conn.SendChannel() defer conn.Close() for { // TODO: some way of stopping this select { case from_server := <-recv_ch: log.Printf("server --> tuntap (%d bytes)\n", len(from_server)) tt.Write(from_server) case from_tuntap := <-tt.RecvChannel(): log.Printf("tuntap --> server (%d bytes)\n", len(from_tuntap)) send_ch <- from_tuntap case <-tt.EOFChannel(): log.Println("EOF received from TUN/TAP device, exiting...") return } } }