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
}
Beispiel #2
0
/*
	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
}
Beispiel #3
0
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)
	}
}
Beispiel #4
0
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)
		}
	}
}
Beispiel #6
0
/*------------------------------------------------------------------------
 * 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
}
Beispiel #7
0
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
}
Beispiel #9
0
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)
		}
	}
}
Beispiel #11
0
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)
		}
	}
}
Beispiel #13
0
func changePort(addr *net.UDPAddr, port int) *net.UDPAddr {
	addr.Port = port
	return addr
}