func NewDHTNode(outputChan chan string, port int) *Node { var err error node := &Node{ info: &ContactInfo{ Id: GenerateNodeId(), }, } // new routing table node.routing = NewRouting(node) // init udp network connection. node.network = new(Network) udpAddr := new(net.UDPAddr) udpAddr.Port = port if node.network.conn, err = net.ListenUDP("udp", udpAddr); err != nil { panic(err.Error()) } laddr := node.network.conn.LocalAddr().(*net.UDPAddr) node.info.IP = laddr.IP node.info.Port = laddr.Port // new KRPC node.krpc = NewKRPC() // output channel node.output = outputChan return node }
/* Starts a UDP listener which will forward received data back to the application using the supplied channel. The listener ID is returned along with a boolean indication of success (true) or failure. The uid is the user created session id string that is used to send buffers that are not related to a session_data struct. */ func (this *Cmgr) Listen_udp(port int, data2usr chan *Sess_data) (uid string, err error) { var addr net.UDPAddr uid = "" addr.IP = net.IPv4(0, 0, 0, 0) addr.Port = port uconn, err := net.ListenUDP("udp", &addr) if err != nil { err = fmt.Errorf("unable to create a udp listener on port: %d; %s", port, err) return } uid = fmt.Sprintf("u%d", this.ucount) // successful bind to port this.ucount += 1 cp := new(connection) cp.conn = nil cp.uconn = uconn cp.data2usr = data2usr // session data written to the channel cp.id = uid // user assigned session id this.clist[uid] = cp // hash for write to session go this.conn_reader(cp) // start reader; will discard if data2usr is nil this.clist[uid] = cp return }
func (dhtNode *DhtNode) FindNode(node *KNode) { var id Id if node.Id != nil { id = node.Id.Neighbor() } else { id = dhtNode.node.Id.Neighbor() } tid := dhtNode.krpc.GenTID() v := make(map[string]interface{}) v["t"] = fmt.Sprintf("%d", tid) v["y"] = "q" v["q"] = "find_node" args := make(map[string]string) args["id"] = string(id) args["target"] = string(GenerateID()) v["a"] = args data, err := bencode.EncodeString(v) if err != nil { dhtNode.log.Fatalln(err) } raddr := new(net.UDPAddr) raddr.IP = node.Ip raddr.Port = node.Port err = dhtNode.network.Send([]byte(data), raddr) if err != nil { dhtNode.log.Println(err) } }
func (n *network) call(msg []byte, timeout time.Duration) (result []byte, err error) { var server net.UDPAddr server.IP = n.gateway server.Port = nAT_PMP_PORT conn, err := net.DialUDP("udp", nil, &server) if err != nil { return } defer conn.Close() // 16 bytes is the maximum result size. result = make([]byte, 16) var finalTimeout time.Time if timeout != 0 { finalTimeout = time.Now().Add(timeout) } needNewDeadline := true var tries uint for tries = 0; (tries < nAT_TRIES && finalTimeout.IsZero()) || time.Now().Before(finalTimeout); { if needNewDeadline { nextDeadline := time.Now().Add((nAT_INITIAL_MS << tries) * time.Millisecond) err = conn.SetDeadline(minTime(nextDeadline, finalTimeout)) if err != nil { return } needNewDeadline = false } _, err = conn.Write(msg) if err != nil { return } var bytesRead int var remoteAddr *net.UDPAddr bytesRead, remoteAddr, err = conn.ReadFromUDP(result) if err != nil { if err.(net.Error).Timeout() { tries++ needNewDeadline = true continue } return } if !remoteAddr.IP.Equal(n.gateway) { // Ignore this packet. // Continue without increasing retransmission timeout or deadline. continue } // Trim result to actual number of bytes received if bytesRead < len(result) { result = result[:bytesRead] } return } err = fmt.Errorf("Timed out trying to contact gateway") return }
func forward_tap_to_phys(phys_conn *net.UDPConn, tap_conn *TapConn, peer_addr *net.UDPAddr, key []byte, chan_disc_peer chan net.UDPAddr) { /* Raw tap frame received */ frame := make([]byte, TAP_MTU+14) /* Encapsulated frame and error */ var enc_frame []byte var invalid error = nil /* Discovered peer */ var disc_peer_addr net.UDPAddr /* Initialize our HMAC-SHA256 hash context */ hmac_h := hmac.New(sha256.New, key) /* If a peer was specified, fill in our discovered peer information */ if peer_addr != nil { disc_peer_addr.IP = peer_addr.IP disc_peer_addr.Port = peer_addr.Port } else { /* Otherwise, wait for the forward_phys_to_tap() goroutine to discover a peer */ disc_peer_addr = <-chan_disc_peer } log.Printf("Starting tap->phys forwarding with peer %s:%d...\n", disc_peer_addr.IP, disc_peer_addr.Port) for { /* Read a raw frame from our tap device */ n, err := tap_conn.Read(frame) if err != nil { log.Fatalf("Error reading from tap device!: %s\n", err) } if DEBUG == 2 { log.Println("<- tap | Plaintext frame to peer:") log.Println("\n" + hex.Dump(frame[0:n])) } /* Encapsulate the frame */ enc_frame, invalid = encap_frame(frame[0:n], hmac_h) /* Skip it if it's invalid */ if invalid != nil { if DEBUG >= 1 { log.Printf("-> phys | Frame discarded! Size: %d, Reason: %s\n", n, invalid.Error()) log.Println("\n" + hex.Dump(frame[0:n])) } continue } if DEBUG == 2 { log.Println("-> phys | Encapsulated frame to peer:") log.Println("\n" + hex.Dump(enc_frame)) } /* Send the encapsulated frame to our peer through UDP */ _, err = phys_conn.WriteToUDP(enc_frame, &disc_peer_addr) if err != nil { log.Fatalf("Error writing to UDP socket!: %s\n", err) } } }
/*------------------------------------------------------------------------ * int OpenPort(ttp_session_t *session); * * Creates a new UDP socket for transmitting the file data associated * with our pending transfer and receives the destination port number * from the client. Returns 0 on success and non-zero on failure. *------------------------------------------------------------------------*/ func (session *Session) OpenPort() error { /* create the address structure */ var udp_address net.UDPAddr if session.parameter.client == "" { address := session.client_fd.RemoteAddr() addr := address.(*net.TCPAddr) udp_address.IP = addr.IP udp_address.Zone = addr.Zone } else { addr, err := net.ResolveIPAddr("ip", session.parameter.client) if err != nil { return err } if addr.Network() == "ipv6" { session.parameter.ipv6 = true } udp_address.IP = addr.IP udp_address.Zone = addr.Zone } if udp_address.String() == "" { return nil } /* read in the port number from the client */ buf := make([]byte, 2) _, err := session.client_fd.Read(buf) if err != nil { return err } x := binary.BigEndian.Uint16(buf) udp_address.Port = int(x) if session.parameter.verbose { Warn("Sending to client port ", x) } fd, err := createUdpSocket(session.parameter, &udp_address) if err != nil { return Warn("Could not create UDP socket", err) } session.transfer.udp_fd = fd session.transfer.udp_address = &udp_address return nil }
func (dhtNode *KNode) GoFindNode(info *NodeInfo, target Id) { if info.Ip.Equal(net.IPv4(0, 0, 0, 0)) || info.Port == 0 { return } addr := new(net.UDPAddr) addr.IP = info.Ip addr.Port = info.Port data, err := dhtNode.krpc.EncodingFindNode(target) if err != nil { dhtNode.log.Println(err) return } err = dhtNode.network.Send([]byte(data), addr) if err != nil { dhtNode.log.Println(err) return } }
// find_node func (n *Node) Find_Node(queryingNodeInfo *ContactInfo, target ID) error { if queryingNodeInfo.IP.Equal(net.IPv4(0, 0, 0, 0)) || queryingNodeInfo.Port == 0 { return errors.New("Can not parse Bootstrap node address.") } addr := new(net.UDPAddr) addr.IP = queryingNodeInfo.IP addr.Port = queryingNodeInfo.Port args := make(map[string]interface{}) args["target"] = string(target) args["id"] = string(n.info.Id) dat, err := n.krpc.EncodeQueryPackage("find_node", args) if err != nil { return err } if _, err := n.network.conn.WriteToUDP(dat, addr); err != nil { return err } return nil }
func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) { var server net.UDPAddr server.IP = n.gateway server.Port = nAT_PMP_PORT conn, err := net.DialUDP("udp", nil, &server) if err != nil { return } defer conn.Close() result = make([]byte, resultSize) timeout := time.Now().Add(n.timeout) err = conn.SetDeadline(timeout) if err != nil { return } var bytesRead int var remoteAddr *net.UDPAddr for time.Now().Before(timeout) { _, err = conn.Write(msg) if err != nil { return } bytesRead, remoteAddr, err = conn.ReadFromUDP(result) if err != nil { if err.(net.Error).Timeout() { continue } return } if !remoteAddr.IP.Equal(n.gateway) { // Ignore this packet. continue } if bytesRead != resultSize { err = fmt.Errorf("unexpected result size %d, expected %d", bytesRead, resultSize) return } if result[0] != 0 { err = fmt.Errorf("unknown protocol version %d", result[0]) return } expectedOp := msg[1] | 0x80 if result[1] != expectedOp { err = fmt.Errorf("Unexpected opcode %d. Expected %d", result[1], expectedOp) return } resultCode := readNetworkOrderUint16(result[2:4]) if resultCode != 0 { err = fmt.Errorf("Non-zero result code %d", resultCode) return } // If we got here the RPC is good. return } err = fmt.Errorf("Timed out trying to contact gateway") return }
func forward_phys_to_tap(phys_conn *net.UDPConn, tap_conn *TapConn, peer_addr *net.UDPAddr, key []byte, chan_disc_peer chan net.UDPAddr) { /* Raw UDP packet received */ packet := make([]byte, UDP_MTU) /* Decapsulated frame and error */ var dec_frame []byte var invalid error = nil /* Peer address */ var cur_peer_addr net.UDPAddr /* Peer discovery */ var peer_discovery bool /* Initialize our HMAC-SHA256 hash context */ hmac_h := hmac.New(sha256.New, key) /* If a peer was specified, fill in our peer information */ if peer_addr != nil { cur_peer_addr.IP = peer_addr.IP cur_peer_addr.Port = peer_addr.Port log.Printf("Starting udp->tap forwarding with peer %s:%d...\n", cur_peer_addr.IP, cur_peer_addr.Port) peer_discovery = false } else { log.Printf("Starting udp->tap forwarding with peer discovery...\n") peer_discovery = true } for { /* Receive an encapsulated frame packet through UDP */ n, raddr, err := phys_conn.ReadFromUDP(packet) if err != nil { log.Fatalf("Error reading from UDP socket!: %s\n", err) } /* If peer discovery is off, ensure the received packge is from our * specified peer */ if !peer_discovery && (!raddr.IP.Equal(cur_peer_addr.IP) || raddr.Port != cur_peer_addr.Port) { continue } if DEBUG == 2 { log.Println("<- udp | Encapsulated frame:") log.Printf(" | from Peer %s:%d\n", raddr.IP, raddr.Port) log.Println("\n" + hex.Dump(packet[0:n])) } /* Decapsulate the frame, skip it if it's invalid */ dec_frame, invalid = decap_frame(packet[0:n], hmac_h) if invalid != nil { if DEBUG >= 1 { log.Printf("<- udp | Frame discarded! Size: %d, Reason: %s\n", n, invalid.Error()) log.Printf(" | from Peer %s:%d\n", raddr.IP, raddr.Port) log.Println("\n" + hex.Dump(packet[0:n])) } continue } /* If peer discovery is on and the peer is new, save the discovered * peer */ if peer_discovery && (!raddr.IP.Equal(cur_peer_addr.IP) || raddr.Port != cur_peer_addr.Port) { cur_peer_addr.IP = raddr.IP cur_peer_addr.Port = raddr.Port /* Send the new peer info to our forward_tap_to_phys() goroutine * via channel */ chan_disc_peer <- cur_peer_addr if DEBUG >= 0 { log.Printf("Discovered peer %s:%d!\n", cur_peer_addr.IP, cur_peer_addr.Port) } } if DEBUG == 2 { log.Println("-> tap | Decapsulated frame from peer:") log.Println("\n" + hex.Dump(dec_frame)) } /* Forward the decapsulated frame to our tap interface */ _, err = tap_conn.Write(dec_frame) if err != nil { log.Fatalf("Error writing to tap device!: %s\n", err) } } }
func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) { var server net.UDPAddr server.IP = n.gateway server.Port = nAT_PMP_PORT conn, err := net.DialUDP("udp", nil, &server) if err != nil { return } defer conn.Close() result = make([]byte, resultSize) needNewDeadline := true var tries uint for tries = 0; tries < nAT_TRIES; { if needNewDeadline { err = conn.SetDeadline(time.Now().Add((nAT_INITIAL_MS << tries) * time.Millisecond)) if err != nil { return } needNewDeadline = false } _, err = conn.Write(msg) if err != nil { return } var bytesRead int var remoteAddr *net.UDPAddr bytesRead, remoteAddr, err = conn.ReadFromUDP(result) if err != nil { if err.(net.Error).Timeout() { tries++ needNewDeadline = true continue } return } if !remoteAddr.IP.Equal(n.gateway) { log.Printf("Ignoring packet because IPs differ:", remoteAddr, n.gateway) // Ignore this packet. // Continue without increasing retransmission timeout or deadline. continue } if bytesRead != resultSize { err = fmt.Errorf("unexpected result size %d, expected %d", bytesRead, resultSize) return } if result[0] != 0 { err = fmt.Errorf("unknown protocol version %d", result[0]) return } expectedOp := msg[1] | 0x80 if result[1] != expectedOp { err = fmt.Errorf("Unexpected opcode %d. Expected %d", result[1], expectedOp) return } resultCode := readNetworkOrderUint16(result[2:4]) if resultCode != 0 { err = fmt.Errorf("Non-zero result code %d", resultCode) return } // If we got here the RPC is good. return } err = fmt.Errorf("Timed out trying to contact gateway") return }
func forward_phys_to_tap(phys_conn *net.UDPConn, tap_conn *TapConn, peer_addr *net.UDPAddr, key []byte, chan_disc_peer chan net.UDPAddr) { /* Raw UDP packet received */ packet := make([]byte, UDP_MTU) /* Decapsulated frame and error */ var dec_frame []byte var invalid error = nil /* Discovered peer */ var disc_peer bool = false var disc_peer_addr net.UDPAddr /* Initialize our HMAC-SHA256 hash context */ hmac_h := hmac.New(sha256.New, key) /* If a peer was specified, fill in our discovered peer information */ if peer_addr != nil { disc_peer = true disc_peer_addr.IP = peer_addr.IP disc_peer_addr.Port = peer_addr.Port log.Printf("Starting phys->tap forwarding with peer %s:%d...\n", disc_peer_addr.IP, disc_peer_addr.Port) } else { log.Printf("Starting phys->tap forwarding with peer discovery...\n") } for { /* Receive an encapsulated frame packet through UDP */ n, raddr, err := phys_conn.ReadFromUDP(packet) if err != nil { log.Fatalf("Error reading from UDP socket!: %s\n", err) } /* Ensure it's addressed from our peer, if we've already discovered * one */ if disc_peer { if !raddr.IP.Equal(disc_peer_addr.IP) || raddr.Port != disc_peer_addr.Port { continue } } if DEBUG == 2 { log.Println("<- phys | Encapsulated frame from peer:") log.Println("\n" + hex.Dump(packet[0:n])) } /* Decapsulate the frame */ dec_frame, invalid = decap_frame(packet[0:n], hmac_h) /* Skip it if it's invalid */ if invalid != nil { if DEBUG >= 1 { log.Printf("<- phys | Frame discarded! Size: %d, Reason: %s\n", n, invalid.Error()) log.Printf(" | from Peer %s:%d\n", raddr.IP, raddr.Port) log.Println("\n" + hex.Dump(packet[0:n])) } continue } /* Save the discovered peer, if it's our first valid decoded packet */ if !disc_peer { disc_peer_addr.IP = raddr.IP disc_peer_addr.Port = raddr.Port disc_peer = true /* Send the discovered peer info to our forward_tap_to_phys() * goroutine */ chan_disc_peer <- disc_peer_addr if DEBUG >= 0 { log.Printf("Discovered peer %s:%d!\n", disc_peer_addr.IP, disc_peer_addr.Port) } } if DEBUG == 2 { log.Println("-> tap | Decapsulated frame from peer:") log.Println("\n" + hex.Dump(dec_frame)) } /* Forward the decapsulated frame to our tap interface */ _, err = tap_conn.Write(dec_frame) if err != nil { log.Fatalf("Error writing to tap device!: %s\n", err) } } }
func changePort(addr *net.UDPAddr, port int) *net.UDPAddr { addr.Port = port return addr }