Beispiel #1
0
func receiveUDP(udpConn *net.UDPConn, rAddr *net.UDPAddr) {
	b := make([]byte, 1024)
	udpConn.SetReadDeadline(time.Now().Add(5 * time.Second))

	n, Addr, err := udpConn.ReadFromUDP(b)
	//	n,err:=udpConn.Read(b)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	if n > 1024 {
		fmt.Println("Buff out!")
		return
	}
	fmt.Println(udpConn.RemoteAddr().Network())
	if !Addr.IP.Equal(rAddr.IP) {
		fmt.Println("IP diff:%s-%s", Addr.IP.String(), rAddr.IP.String())
		return
	} else if Addr.Port != rAddr.Port {
		fmt.Println("Port diff:%d-%d", Addr.Port, rAddr.Port)
		return
	}
	fmt.Printf("Receive from %s:%s", udpConn.RemoteAddr().String(), b[:n])

}
Beispiel #2
0
// HandleFind - Receives a Find message with a list of peers in this environment
func (dht *DHTClient) HandleFind(data DHTMessage, conn *net.UDPConn) {
	// This means we've received a list of nodes we can connect to
	if data.Arguments != "" {
		ids := strings.Split(data.Arguments, ",")
		if len(ids) == 0 {
			Log(Error, "Malformed list of peers received")
		} else {
			// Go over list of received peer IDs and look if we know
			// anything about them. Add every new peer into list of peers
			for _, id := range ids {
				var found = false
				for _, peer := range dht.Peers {
					if peer.ID == id {
						found = true
					}
				}
				if !found {
					var p PeerIP
					p.ID = id
					dht.Peers = append(dht.Peers, p)
				}
			}
			k := 0
			for _, peer := range dht.Peers {
				var found = false
				for _, id := range ids {
					if peer.ID == id {
						found = true
					}
				}
				if found {
					dht.Peers[k] = peer
					k++
				}
			}
			dht.Peers = dht.Peers[:k]
			if dht.PeerChannel == nil {
				dht.PeerChannel = make(chan []PeerIP)
			}
			dht.PeerChannel <- dht.Peers
			Log(Debug, "Received peers from %s: %s", conn.RemoteAddr().String(), data.Arguments)
			dht.UpdateLastCatch(data.Arguments)
		}
	} else {
		dht.Peers = dht.Peers[:0]
	}
}
Beispiel #3
0
func (p *Proxy) proxyUDPStream(ctx context.Context, src *net.UDPConn) {
	srcRemoteAddr := src.RemoteAddr().(*net.UDPAddr)
	srcLocalAddr := src.LocalAddr().(*net.UDPAddr)

	route := p.routes.GetTable().Lookup(protocols.UDP,
		srcRemoteAddr.IP, srcLocalAddr.IP,
		uint16(srcRemoteAddr.Port), uint16(srcLocalAddr.Port))
	if route == nil {
		src.Close()
		return
	}

	go func() {
		dstAddr := net.UDPAddr{
			IP:   route.Outbound.DstIP,
			Port: int(route.Outbound.DstPort),
		}

		dst, err := net.DialUDP("udp", nil, &dstAddr)
		if err != nil {
			src.Close()
			return
		}

		dst.SetKeepAlivePeriod(10 * time.Second)
		src.SetKeepAlivePeriod(10 * time.Second)

		go func() {
			<-ctx.Done()
			src.Close()
			dst.Close()
		}()

		go func() {
			defer dst.CloseWrite()
			defer src.CloseRead()
			io.Copy(dst, src)
		}()

		go func() {
			defer src.CloseWrite()
			defer dst.CloseRead()
			io.Copy(src, dst)
		}()
	}()
}
Beispiel #4
0
func readAndWriteUDP(r io.Reader, w io.Writer, con *net.UDPConn, ra net.Addr, verbose bool) <-chan net.Addr {
	buf := make([]byte, BUFFER_LIMIT)
	cAddr := make(chan net.Addr)
	go func() {
		defer func() {
			con.Close()
			cAddr <- ra
		}()

		for {
			var bytesread int
			var errRead, errWrite error
			if con, ok := r.(*net.UDPConn); ok {
				var addr net.Addr
				bytesread, addr, errRead = con.ReadFrom(buf)
				if con.RemoteAddr() == nil && ra == nil {
					ra = addr
					cAddr <- ra
				}
			} else {
				bytesread, errRead = r.Read(buf)
			}
			if errRead != nil {
				if errRead != io.EOF {
					if verbose {
						log.Println("READ ERROR: ", errRead)
					}
				}
				break
			}
			if con, ok := w.(*net.UDPConn); ok && con.RemoteAddr() == nil {
				_, errWrite = con.WriteTo(buf[0:bytesread], ra)
			} else {
				_, errWrite = w.Write(buf[0:bytesread])
			}
			if errWrite != nil {
				if verbose {
					log.Println("WRITE ERROR: ", errWrite)
				}
				return
			}
		}
	}()
	return cAddr
}
Beispiel #5
0
// HandleConn analyzes received connecting message and assigns received
// cliend ID if any
func (dht *DHTClient) HandleConn(data DHTMessage, conn *net.UDPConn) {
	if dht.State != DHTStateConnecting && dht.State != DHTStateReconnecting {
		return
	}
	if data.ID == "" {
		Log(Error, "Empty ID was received")
		return
	}
	if data.ID == "0" {
		Log(Error, "Empty ID were received. Stopping")
		return
	}
	dht.State = DHTStateOperating
	dht.ID = data.ID
	Log(Info, "Received connection confirmation from router %s",
		conn.RemoteAddr().String())
	Log(Info, "Received personal ID for this session: %s", data.ID)
}
Beispiel #6
0
func HandleUDPConnection(con *net.UDPConn, verbose bool) {

	chan_remote := readAndWriteUDP(con, os.Stdout, con, nil, verbose)
	ra := con.RemoteAddr()
	if ra == nil {
		ra = <-chan_remote
	}
	chan_local := readAndWriteUDP(os.Stdin, con, con, ra, verbose)
	select {
	case <-chan_local:
		if verbose {
			log.Println("Connection closed from local process")
		}
	case <-chan_remote:
		if verbose {
			log.Println("Connection closed from remote process")
		}
	}
}
Beispiel #7
0
// ListenDHT - listens for packets received from DHT bootstrap node
// Every packet is unmarshaled and turned into Request structure
// which we should analyze and respond
func (dht *DHTClient) ListenDHT(conn *net.UDPConn) {
	defer conn.Close()
	Log(Info, "Bootstraping via %s", conn.RemoteAddr().String())
	dht.Listeners++
	var failCounter = 0
	for {
		if dht.Shutdown {
			Log(Info, "Closing DHT Connection to %s", conn.RemoteAddr().String())
			conn.Close()
			for i, c := range dht.Connection {
				if c.RemoteAddr().String() == conn.RemoteAddr().String() {
					dht.Connection = append(dht.Connection[:i], dht.Connection[i+1:]...)
				}
			}
			break
		}
		var buf [512]byte
		_, _, err := conn.ReadFromUDP(buf[0:])
		if err != nil {
			Log(Debug, "Failed to read from Discovery Service: %v", err)
			failCounter++
		} else {
			failCounter = 0
			data, err := dht.Extract(buf[:512])
			if err != nil {
				Log(Error, "Failed to extract a message received from discovery service: %v", err)
			} else {
				callback, exists := dht.ResponseHandlers[data.Command]
				if exists {
					Log(Trace, "DHT Received %v", data)
					callback(data, conn)
				} else {
					Log(Debug, "Unsupported packet type received from DHT: %s", data.Command)
				}
			}
		}
		if failCounter > 1000 {
			Log(Error, "Multiple errors reading from DHT")
			break
		}
	}
	dht.Listeners--
}
Beispiel #8
0
func dnsReqResp(name string, conn *net.UDPConn) (net.IP, error) {
	//question
	var ret net.IP
	remote := conn.RemoteAddr().String()
	header, err := dnsQdGen(name, remote)
	if err != nil {
		return ret, qdGenError
	}
	_, err = conn.Write(header)
	if err != nil {
		return ret, reqNetworkError
	}

	respBuf := make([]byte, dnsBufSize)
	nread, _, err := conn.ReadFromUDP(respBuf[:dnsRespMax])

	if err != nil {
		return ret, respNetworkError
	}
	//respose
	respRd := bytes.NewReader(respBuf)

	dns := dnsHeader{}
	err = binary.Read(respRd, binary.BigEndian, &dns)
	if (dns.Flags&_QR) == 0 || err != nil {
		return ret, respFormatError
	}
	numQd := dns.QdCount
	numAn := dns.AnCount

	buflen := len(respBuf)
	pos := int(unsafe.Sizeof(dns))
	for i := 0; i < int(numQd); i++ {
		for {
			n := int(respBuf[pos])
			if n == 0 {
				pos += 1
				break
			}
			if n > nameLenMax {
				return ret, respFormatError
			}
			pos += (n + 1)
			if pos >= buflen {
				return ret, respFormatError
			}
		}
		pos += 4 //skip type and class
	}

	if pos >= nread {
		return ret, respFormatError
	}

	for i := 0; i < int(numAn); i++ {
		size := parseNameSize(respBuf, pos)
		if size <= 0 {
			return ret, respFormatError
		}
		pos += size

		tp := (respBuf[pos] << 16) + respBuf[pos+1]
		pos += 8 //skip type, class ttl
		if pos >= nread {
			return ret, respFormatError
		}
		dataLen := (respBuf[pos] << 16) + respBuf[pos+1]
		pos += 2 //skip data len
		if tp == qdTypeA && dataLen == net.IPv4len {
			ret = respBuf[pos : pos+4]
			return ret, nil
		}
		pos += int(dataLen) //skip data
		if pos >= nread {
			return ret, respFormatError
		}
	}
	return ret, respNotFoundError
}
Beispiel #9
0
// Sends the data in sendbuf to peer_addr (with possible resends) and waits for
// an ACK with the correct block id, if sendbuf contains a DATA message.
// Returns true if the sending was successful and the ACK was received.
func sendAndWaitForAck(udp_conn *net.UDPConn, peer_addr *net.UDPAddr, sendbuf []byte, retransmissions, dups, strays *int) bool {
	// absolute deadline when this function will return false
	deadline := time.Now().Add(total_timeout)

	readbuf := make([]byte, 4096)

	*retransmissions-- // to counter the ++ being done at the start of the loop

outer:
	for {
		// re/send
		*retransmissions++
		n, err := udp_conn.Write(sendbuf)
		if err != nil {
			util.Log(0, "ERROR! TFTP error in Write(): %v", err)
			break
		}
		if n != len(sendbuf) {
			util.Log(0, "ERROR! TFTP: Incomplete write")
			break
		}
		//util.Log(2, "DEBUG! TFTP: Sent %v bytes to %v. Waiting for ACK...", len(sendbuf), peer_addr)

		for {
			// check absolute deadline
			if time.Now().After(deadline) {
				break outer
			}

			// set deadline for next read
			timo := time.Duration(rand.Int63n(int64(max_wait_retry-min_wait_retry))) + min_wait_retry
			endtime2 := time.Now().Add(timo)
			if endtime2.After(deadline) {
				endtime2 = deadline
			}
			udp_conn.SetReadDeadline(endtime2)

			n, from, err := udp_conn.ReadFromUDP(readbuf)

			if err != nil {
				e, ok := err.(*net.OpError)
				if !ok || !e.Timeout() {
					util.Log(0, "ERROR! TFTP ReadFromUDP() failed while waiting for ACK from %v (local address: %v): %v", udp_conn.RemoteAddr(), udp_conn.LocalAddr(), err)
					break outer // retries make no sense => bail out
				} else {
					//util.Log(2, "DEBUG! TFTP timeout => resend %#v", sendbuf)
					continue outer // resend
				}
			}
			if from.Port != peer_addr.Port {
				*strays++
				emsg := fmt.Sprintf("WARNING! TFTP server got UDP packet from incorrect source: %v instead of %v", from.Port, peer_addr.Port)
				sendError(udp_conn, from, 5, emsg) // 5 => Unknown transfer ID
				continue                           // This error is not fatal since it doesn't affect our peer
			}
			if n == 4 && readbuf[0] == 0 && readbuf[1] == 4 && // 4 => ACK
				(sendbuf[1] != 3 || // we did not send DATA
					// or the ACK's block id is the same as the one we sent
					(readbuf[2] == sendbuf[2] && readbuf[3] == sendbuf[3])) {
				//util.Log(2, "DEBUG! TFTP: Received ACK from %v: %#v", peer_addr, readbuf[0:n])
				return true
			} else {
				if readbuf[0] == 0 && readbuf[1] == 5 { // error
					util.Log(0, "ERROR! TFTP ERROR received while waiting for ACK from %v: %v", peer_addr, string(readbuf[4:n]))
					break outer // retries make no sense => bail out
				} else {
					// if we sent DATA but the ACK is not for the block we sent,
					// increase dup counter. If we wanted to be anal we would need to check
					// if the block id is one less for it to be an actual dup, but
					// since the dup counter is only for reporting, we don't care.
					if sendbuf[1] == 3 && (readbuf[2] != sendbuf[2] || readbuf[3] != sendbuf[3]) {
						*dups++
						//util.Log(2, "DEBUG! TFTP duplicate ACK received: %#v => Ignored", string(readbuf[0:n]))

						// ONLY "continue", NOT "continue outer", i.e. DUPs DO NOT CAUSE A RESEND.
						// THIS PREVENTS http://en.wikipedia.org/wiki/Sorcerer's_Apprentice_Syndrome
						// When timeout happens, it will cause a resend.
						continue
					} else {
						emsg := fmt.Sprintf("ERROR! TFTP server waiting for ACK from %v but got: %#v", peer_addr, string(readbuf[0:n]))
						sendError(udp_conn, from, 0, emsg) // 0 => Unspecified error
						break outer                        // retries make no sense => bail out
					}
				}
			}
		}
	}

	util.Log(0, "ERROR! TFTP send not acknowledged by %v (retransmissions: %v, dups: %v, strays: %v)", peer_addr, *retransmissions, *dups, *strays)

	return false
}
Beispiel #10
0
func close(c *net.UDPConn) {
	log.Printf("closing: %s -> %s", c.LocalAddr().String(), c.RemoteAddr().String())
	c.Close()
}