示例#1
0
func DialTunnel(addr string) (tc net.Conn, err error) {
	var conn *net.UDPConn
	var t *Tunnel

	udpaddr, err := net.ResolveUDPAddr("udp", addr)
	if err != nil {
		return
	}
	conn, err = net.DialUDP("udp", nil, udpaddr)
	if err != nil {
		return
	}
	localaddr := conn.LocalAddr()
	localstr := localaddr.String()

	name := fmt.Sprintf("%s_cli", strings.Split(localstr, ":")[1])
	t = NewTunnel(udpaddr, name, make(chan *SendBlock, TBUFSIZE))
	c := &Client{t, conn, name, make(chan uint8)}
	t.onclose = func() {
		sutils.Info("close tunnel", localaddr)
		conn.Close()
		close(c.c_close)
		close(t.c_send)
	}
	go c.sender()
	go c.recver()

	t.c_event <- EV_CONNECT
	<-t.c_connect
	sutils.Info("create tunnel", localaddr)

	return &TunnelConn{t, localaddr}, nil
}
示例#2
0
func (udp *Udp) listen(conn *net.UDPConn) {
	log.Info("Begin listening for UDP on address %s", conn.LocalAddr())

	buffer := make([]byte, c_BUFSIZE)
	for {
		num, _, err := conn.ReadFromUDP(buffer)
		if err != nil {
			if udp.stop {
				log.Info("Stopped listening for UDP on %s", conn.LocalAddr)
				break
			} else {
				log.Severe("Failed to read from UDP buffer: " + err.Error())
				continue
			}
		}

		pkt := append([]byte(nil), buffer[:num]...)
		go func() {
			msg, err := parser.ParseMessage(pkt)
			if err != nil {
				log.Warn("Failed to parse SIP message: %s", err.Error())
			} else {
				udp.output <- msg
			}
		}()
	}
}
示例#3
0
func GatherCandidates(sock *net.UDPConn) ([]candidate, error) {
	laddr := sock.LocalAddr().(*net.UDPAddr)
	ret := []candidate{}
	switch {
	case laddr.IP.IsLoopback():
		return nil, errors.New("Connecting over loopback not supported")
	case laddr.IP.IsUnspecified():
		addrs, err := net.InterfaceAddrs()
		if err != nil {
			return nil, err
		}

		for _, addr := range addrs {
			ip, ok := addr.(*net.IPNet)
			if ok && ip.IP.IsGlobalUnicast() {
				ret = append(ret, candidate{&net.UDPAddr{ip.IP, laddr.Port, ""}, 0})
			}
		}
	default:
		ret = append(ret, candidate{laddr, 0})
	}

	// Get the reflexive address
	reflexive, err := getReflexive(sock)
	if err == nil {
		ret = append(ret, candidate{reflexive, 0})
	}

	setPriorities(ret)
	return ret, nil
}
示例#4
0
func (listener *Listener) newUDPSession(remote *net.UDPAddr) (*UDPSession, bool) {

	remoteAddrStr := remote.String()
	listener.Lock()
	if sess, ok := listener.remoteAddrs[remoteAddrStr]; ok == true {
		listener.Unlock()
		return sess, true
	}
	listener.Unlock()

	var err error
	var local *net.UDPConn
	if local, err = net.ListenUDP("udp", &net.UDPAddr{}); err != nil {
		//log.Println(err)
		return nil, false
	}
	localAddr := local.LocalAddr().(*net.UDPAddr)

	sess := newUDPSession(listener, remote, local, localAddr)

	listener.Lock()
	listener.remoteAddrs[remoteAddrStr] = sess
	listener.Unlock()

	return sess, false
}
示例#5
0
// Creates a 2 byte ClientID from the local machine's IP.
func GetClientId() (id []byte, err error) {
	var conn *net.UDPConn
	var addr *net.UDPAddr

	// Connect to a random machine somewhere in this subnet. It's irrelevant
	// where to, as long as it's not the loopback address.
	if addr, err = net.ResolveUDPAddr("udp", "192.168.1.1:0"); err != nil {
		return
	}

	if conn, err = net.DialUDP("udp", nil, addr); err != nil {
		return
	}

	defer conn.Close()

	// strip port number off.
	str := conn.LocalAddr().String()
	if idx := strings.LastIndex(str, ":"); idx != -1 {
		str = str[0:idx]
	}

	var ip net.IP
	if ip = net.ParseIP(str).To16(); ip == nil {
		return
	}

	// TODO(jimt): I am unsure how 2 full IPv6 addresses in the same subnet relate
	// to eachother. Specifically if the 2 last bytes in the 16-byte address are
	// really the relevant bits that set them apart from eachother.
	// For IPv4 this is simple: 192.168.2.101 vs 192.168.2.102 -> we need the
	// '2.101' and '2.102' bits. Bytes are stored in Big Endian order.
	id = []byte{ip[14], ip[15]}
	return
}
示例#6
0
/*
	Used to listen for incoming UDP packets on  an given connection. Runs an infinite loop reading from the connection to a buffer.
	When a message is complete, it sends it to to the caller via the receive channel.
*/
func udpConnectionReader(connection *net.UDPConn, messageSize int, receiveChannel chan<- UDPMessage) {
	defer func() {
		if r := recover(); r != nil {
			log.Println("UDPConnectionReader:\t ERROR in udpConnectionReader:\t %s \n Closig connection.", r)
			connection.Close()
		}
	}()

	for {
		if debug {
			log.Printf("UDPConnectionReader:\t Waiting on data from UDPConnection %s\n", connection.LocalAddr().String())
		}
		buffer := make([]byte, messageSize) // TODO: Do without allocation memory each time!
		n, returnAddress, err := connection.ReadFromUDP(buffer)
		if err != nil || n < 0 || n > messageSize {
			log.Println("UDPConnectionReader:\t Error in ReadFromUDP:", err)
		} else {
			if debug {
				log.Println("UDPConnectionReader:\t Received package from:", returnAddress.String())
				log.Println("UDP-Listen:\t", string(buffer[:]))
			}
			receiveChannel <- UDPMessage{RAddress: returnAddress.String(), Data: buffer[:n], Length: n}
		}
	}
}
示例#7
0
func listenServer(conn *net.UDPConn, receiveChannel chan UDPMessage, networkLogger log.Logger) {
	networkLogger.Printf("Listening on %s", conn.LocalAddr().String())
	for {
		buf := make([]byte, 1024)
		len, raddr, _ := conn.ReadFromUDP(buf)
		receiveChannel <- UDPMessage{Address: IP(raddr.IP.String()), Data: buf[:len], Length: len}
	}
}
示例#8
0
func getUDPAddr(conn *net.UDPConn) *net.UDPAddr {
	addr := conn.LocalAddr()
	udpAddr, ok := addr.(*net.UDPAddr)
	if !ok {
		log.Fatal()
	}
	return udpAddr
}
示例#9
0
文件: gost.go 项目: xyz12810/gost-1
// Listen launches the various server goroutines and starts the various listeners.
// If the listener params are nil, these are constructed from the parameters in the conf. Otherwise they are
// used as-is. This makes it possible for the tests to construct listeners on an available port and pass them
// in.
func (s *Server) Listen(clientConn *net.UDPConn, forwardListener, debugListener net.Listener) error {
	go s.handleMetaStats()
	go s.flush()
	go s.aggregate()
	if s.conf.OSStats != nil {
		go s.checkOSStats()
	}
	if s.conf.Scripts != nil {
		go s.runScripts()
	}

	if s.conf.forwardingEnabled {
		s.forwardingIncoming = make(chan *Stat, incomingQueueSize)
		go s.flushForwarding()
		go s.aggregateForwarding()
	}

	errorCh := make(chan error)
	if s.conf.forwarderEnabled {
		if forwardListener == nil {
			l, err := net.Listen("tcp", s.conf.ForwarderListenAddr)
			if err != nil {
				return err
			}
			forwardListener = tcpKeepAliveListener{l.(*net.TCPListener)}
		}
		s.l.Println("Listening for forwarded gost messages on", forwardListener.Addr())
		go s.aggregateForwarded()
		go func() {
			errorCh <- s.forwardServer(forwardListener)
		}()
	}

	if err := s.debugServer.Start(s.conf.DebugPort, debugListener); err != nil {
		return err
	}

	if clientConn == nil {
		udpAddr := fmt.Sprintf("localhost:%d", s.conf.Port)
		udp, err := net.ResolveUDPAddr("udp", udpAddr)
		if err != nil {
			return err
		}
		clientConn, err = net.ListenUDP("udp", udp)
		if err != nil {
			return err
		}
	}
	s.l.Println("Listening for UDP client requests on", clientConn.LocalAddr())
	go func() {
		errorCh <- s.clientServer(clientConn)
	}()

	// Indicate that we've started
	s.metaInc("server_start")

	return <-errorCh
}
示例#10
0
func handleudp(conn *net.UDPConn, remaddr net.Addr, message []byte) {
	fmt.Printf("UDP packet from %s (to %s)... ", remaddr, conn.LocalAddr())
	n, error := conn.WriteTo(message, remaddr)
	checkError("Cannot write", error)
	if n != len(message) {
		panic("Cannot write")
	}
	fmt.Printf("Echoed %d bytes\n", n)
}
示例#11
0
func GatherCandidates(sock *net.UDPConn, outIpList string) ([]candidate, error) {
	laddr := sock.LocalAddr().(*net.UDPAddr)
	ret := []candidate{}
	switch {
	case laddr.IP.IsLoopback():
		return nil, errors.New("Connecting over loopback not supported")
	case laddr.IP.IsUnspecified():
		addrs, err := net.InterfaceAddrs()
		if err != nil {
			return nil, err
		}

		for _, addr := range addrs {
			ip, ok := addr.(*net.IPNet)
			if ok && ip.IP.IsGlobalUnicast() {
				ret = append(ret, candidate{&net.UDPAddr{IP: ip.IP, Port: laddr.Port}})
			}
		}
	default:
		ret = append(ret, candidate{laddr})
	}

	addip := func(ipStr string, port int) {
		ip := net.ParseIP(ipStr)
		if port == 0 {
			port = laddr.Port
		}
		bHave := false
		for _, info := range ret {
			if info.Addr.IP.Equal(ip) && info.Addr.Port == port {
				bHave = true
				break
			}
		}
		if !bHave {
			ret = append(ret, candidate{&net.UDPAddr{IP: ip, Port: port}})
		}
	}
	// Get the reflexive address
	if *stunserver != "" {
		ip, port, err := getReflexive(sock)
		if err == nil {
			addip(ip, port)
		}
	}

	arr := strings.Split(outIpList, ";")
	for _, ip := range arr {
		addip(ip, 0)
	}

	/*	for _, info := range ret {
			log.Println("init ip:", info.Addr.String())
	}*/
	return ret, nil
}
示例#12
0
文件: discord.go 项目: ckolbeck/god
func findAddress() (addr string, err error) {
	var udpAddr *net.UDPAddr
	if udpAddr, err = net.ResolveUDPAddr("udp", "www.internic.net:80"); err != nil {
		return
	}
	var udpConn *net.UDPConn
	if udpConn, err = net.DialUDP("udp", nil, udpAddr); err != nil {
		return
	}
	addr = udpConn.LocalAddr().String()
	return
}
示例#13
0
文件: network.go 项目: pee/smapoller
func StartListener(conn *net.UDPConn, callback func(address *net.UDPAddr)) {

	log.Println("listener:Listening on:", conn.LocalAddr())
	buf := make([]byte, 1024)

	for {

		//log.Println("listener:going to read")
		n, addr, err := conn.ReadFromUDP(buf)
		checkError(err)
		log.Println("listener:received:", n, "bytes from:", addr)
		callback(addr)
	}
}
示例#14
0
func listen(c chan string, conn *net.UDPConn, label string) {
	log.Printf("listening to %s", conn.LocalAddr().String())
	buf := make([]byte, 9999)
	for {
		n, _, err := conn.ReadFromUDP(buf)
		if err != nil {
			log.Print(err)
			time.Sleep(3 * time.Second)
			continue
		}
		s := string(buf[:n])
		log.Printf("%s got {%s}", label, s)
		c <- s
	}
}
示例#15
0
func TestIngestPacket_CRC(t *testing.T) {
	m := GetMemberlist(t)
	m.config.EnableCompression = false
	defer m.Shutdown()

	var udp *net.UDPConn
	for port := 60000; port < 61000; port++ {
		udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
		udpLn, err := net.ListenPacket("udp", udpAddr)
		if err == nil {
			udp = udpLn.(*net.UDPConn)
			break
		}
	}

	if udp == nil {
		t.Fatalf("no udp listener")
	}

	// Get a message with a checksum
	payload := []byte{3, 3, 3, 3}
	m.rawSendMsgUDP(udp.LocalAddr(), &Node{PMax: 5}, payload)

	in := make([]byte, 1500)
	n, _, err := udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	if len(in) != 9 {
		t.Fatalf("bad: %v", in)
	}

	// Corrupt the checksum
	in[1] <<= 1

	logs := &bytes.Buffer{}
	logger := log.New(logs, "", 0)
	m.logger = logger
	m.ingestPacket(in, udp.LocalAddr(), time.Now())

	if !strings.Contains(logs.String(), "invalid checksum") {
		t.Fatalf("bad: %s", logs.String())
	}
}
示例#16
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)
		}()
	}()
}
示例#17
0
func (trans *udpTransportProvider) newConn(udp *net.UDPConn, remote_addr *udpAddr, protocol Protocol, err error) (*udpConn, error) {
	if err != nil {
		return nil, err
	}
	local, ok := udp.LocalAddr().(*net.UDPAddr)
	if !ok {
		return nil, fmt.Errorf("Could not convert LocalAddr to *net.UDPAddr: %v", udp.LocalAddr())
	}
	return &udpConn{
		trans:    trans,
		udp:      udp,
		protocol: protocol,
		local:    udpAddr{trans, local},
		remote:   remote_addr,
		retries:  DefaultRetries,
	}, nil
}
示例#18
0
func ReceiveDatagrams(hostAndPort string) *data.EventStream {

	var conn *net.UDPConn

	conn, err := createUDPListener(hostAndPort)

	if err != nil {
		panic("Could not create UDP listener")
	}

	fmt.Printf("Listener for UDP connections on %s\n", conn.LocalAddr().String())

	eventStream := data.NewEventStream()

	go rcv(conn, eventStream)

	return eventStream

}
示例#19
0
文件: main.go 项目: pablomelo/gmd
func rd(out chan string, conn *net.UDPConn, quit chan struct{}) {
	log.Printf("rd: %s", conn.LocalAddr())
	defer log.Printf("rd: done")
	const maxSize = 4096
	for {
		select {
		case <-quit:
			return

		default:
			b := make([]byte, maxSize)
			conn.SetReadDeadline(time.Now().Add(cycle))
			n, remoteAddr, err := conn.ReadFrom(b)
			if err != nil {
				continue
			}
			if n >= maxSize {
				log.Printf("%s: too big", remoteAddr)
				continue
			}
			out <- string(b[:n])
		}
	}
}
示例#20
0
func Main(clusterName, self, buri, rwsk, rosk string, cl *doozer.Conn, udpConn *net.UDPConn, listener, webListener net.Listener, pulseInterval, fillDelay, kickTimeout int64, hi int64) {
	listenAddr := listener.Addr().String()

	canWrite := make(chan bool, 1)
	in := make(chan consensus.Packet, 50)
	out := make(chan consensus.Packet, 50)

	st := store.New()
	pr := &proposer{
		seqns: make(chan int64, alpha),
		props: make(chan *consensus.Prop),
		st:    st,
	}

	calSrv := func(start int64) {
		go gc.Pulse(self, st.Seqns, pr, pulseInterval)
		go gc.Clean(st, hi, time.Tick(1e9))
		var m consensus.Manager
		m.Self = self
		m.DefRev = start
		m.Alpha = alpha
		m.In = in
		m.Out = out
		m.Ops = st.Ops
		m.PSeqn = pr.seqns
		m.Props = pr.props
		m.TFill = fillDelay
		m.Store = st
		m.Ticker = time.Tick(10e6)
		go m.Run()
	}

	hostname, err := os.Hostname()
	if err != nil {
		hostname = "unknown"
	}

	if cl == nil { // we are the only node in a new cluster
		set(st, "/ctl/name", clusterName, store.Missing)
		set(st, "/ctl/node/"+self+"/addr", listenAddr, store.Missing)
		set(st, "/ctl/node/"+self+"/hostname", hostname, store.Missing)
		set(st, "/ctl/node/"+self+"/version", Version, store.Missing)
		set(st, "/ctl/cal/0", self, store.Missing)
		if buri == "" {
			set(st, "/ctl/ns/"+clusterName+"/"+self, listenAddr, store.Missing)
		}
		calSrv(<-st.Seqns)
		// Skip ahead alpha steps so that the registrar can provide a
		// meaningful cluster.
		for i := 0; i < alpha; i++ {
			st.Ops <- store.Op{1 + <-st.Seqns, store.Nop}
		}
		canWrite <- true
		go setReady(pr, self)
	} else {
		setC(cl, "/ctl/node/"+self+"/addr", listenAddr, store.Clobber)
		setC(cl, "/ctl/node/"+self+"/hostname", hostname, store.Clobber)
		setC(cl, "/ctl/node/"+self+"/version", Version, store.Clobber)

		rev, err := cl.Rev()
		if err != nil {
			panic(err)
		}

		stop := make(chan bool, 1)
		go follow(st, cl, rev+1, stop)

		errs := make(chan error)
		go func() {
			e, ok := <-errs
			if ok {
				panic(e)
			}
		}()
		doozer.Walk(cl, rev, "/", cloner{st.Ops, cl}, errs)
		close(errs)
		st.Flush()

		ch, err := st.Wait(store.Any, rev+1)
		if err == nil {
			<-ch
		}

		go func() {
			n := activate(st, self, cl)
			calSrv(n)
			advanceUntil(cl, st.Seqns, n+alpha)
			stop <- true
			canWrite <- true
			go setReady(pr, self)
			if buri != "" {
				b, err := doozer.DialUri(buri, "")
				if err != nil {
					panic(err)
				}
				setC(
					b,
					"/ctl/ns/"+clusterName+"/"+self,
					listenAddr,
					store.Missing,
				)
			}
		}()
	}

	shun := make(chan string, 3) // sufficient for a cluster of 7
	go member.Clean(shun, st, pr)
	go server.ListenAndServe(listener, canWrite, st, pr, rwsk, rosk)

	if rwsk == "" && rosk == "" && webListener != nil {
		web.Store = st
		web.ClusterName = clusterName
		go web.Serve(webListener)
	}

	go func() {
		for p := range out {
			n, err := udpConn.WriteTo(p.Data, p.Addr)
			if err != nil {
				log.Println(err)
				continue
			}
			if n != len(p.Data) {
				log.Println("packet len too long:", len(p.Data))
				continue
			}
		}
	}()

	selfAddr, ok := udpConn.LocalAddr().(*net.UDPAddr)
	if !ok {
		panic("no UDP addr")
	}
	lv := liveness{
		timeout: kickTimeout,
		ival:    kickTimeout / 2,
		self:    selfAddr,
		shun:    shun,
	}
	for {
		t := time.Now().UnixNano()

		buf := make([]byte, maxUDPLen)
		n, addr, err := udpConn.ReadFromUDP(buf)
		if err == syscall.EINVAL {
			return
		}
		if err != nil {
			log.Println(err)
			continue
		}

		buf = buf[:n]

		lv.mark(addr, t)
		lv.check(t)

		in <- consensus.Packet{addr, buf}
	}
}
示例#21
0
	. "github.com/onsi/gomega"
)

var _ = Describe("UDP Client", func() {
	var (
		client      *clientpool.UDPClient
		udpListener *net.UDPConn
	)

	BeforeEach(func() {
		udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
		Expect(err).NotTo(HaveOccurred())
		udpListener, err = net.ListenUDP("udp", udpAddr)
		Expect(err).NotTo(HaveOccurred())

		client, err = clientpool.NewUDPClient(gosteno.NewLogger("TestLogger"), udpListener.LocalAddr().String())
		Expect(err).NotTo(HaveOccurred())
	})

	AfterEach(func() {
		client.Close()
		udpListener.Close()
	})

	Describe("NewUDPClient", func() {
		Context("when the address is invalid", func() {
			It("returns an error", func() {
				_, err := clientpool.NewUDPClient(gosteno.NewLogger("TestLogger"), "127.0.0.1:abc")
				Expect(err).To(HaveOccurred())
			})
		})
示例#22
0
文件: gather.go 项目: vzex/dog-tunnel
func GatherCandidates(sock *net.UDPConn, outIpList string, udpAddr string) ([]candidate, error) {
	laddr := sock.LocalAddr().(*net.UDPAddr)
	ret := []candidate{}
	switch {
	case laddr.IP.IsLoopback():
		return nil, errors.New("Connecting over loopback not supported")
	case laddr.IP.IsUnspecified():
		addrs, err := net.InterfaceAddrs()
		if err != nil {
			return nil, err
		}

		for _, addr := range addrs {
			ip, ok := addr.(*net.IPNet)
			if ok && ip.IP.IsGlobalUnicast() {
				ret = append(ret, candidate{&net.UDPAddr{IP: ip.IP, Port: laddr.Port}})
			}
		}
	default:
		ret = append(ret, candidate{laddr})
	}

	addip := func(ipStr string, port int) {
		ip := net.ParseIP(ipStr)
		if port == 0 {
			port = laddr.Port
		}
		bHave := false
		for _, info := range ret {
			if info.Addr.IP.Equal(ip) && info.Addr.Port == port {
				bHave = true
				break
			}
		}
		if !bHave {
			ret = append(ret, candidate{&net.UDPAddr{IP: ip, Port: port}})
		}
	}

	if udpAddr != "" {
		addr, err := net.ResolveUDPAddr("udp", udpAddr)
		if err != nil {
			fmt.Println("Can't resolve udp address: ", err)
			return nil, err
		}
		p2pAddr := ""

		for i := 0; i < 5; i++ {
			sock.WriteToUDP([]byte("makehole"), addr)
			buf := make([]byte, 100)
			sock.SetReadDeadline(time.Now().Add(time.Duration(1) * time.Second))
			n, _, err := sock.ReadFromUDP(buf)
			if err != nil {
				fmt.Println("Can't ReadFromUDP: ", err, addr.String())
				continue
			} else {
				p2pAddr = string(buf[0:n])
				fmt.Println("read: ", p2pAddr)
				break
			}
		}

		addLen := len(p2pAddr)
		if addLen > 0 {
			tmparr := strings.Split(p2pAddr, ":")

			var strip string
			var strport string
			strip, strport = tmparr[0], tmparr[1]
			ip := net.ParseIP(strip)
			port, _ := strconv.Atoi(strport)
			ret = append(ret, candidate{&net.UDPAddr{IP: ip, Port: port}})
		}
	}
	arr := strings.Split(outIpList, ";")

	for _, ip := range arr {
		addip(ip, 0)
	}

	/*	for _, info := range ret {
			log.Println("init ip:", info.Addr.String())
	}*/
	return ret, nil
}
示例#23
0
func TestRawSendUdp_CRC(t *testing.T) {
	m := GetMemberlist(t)
	m.config.EnableCompression = false
	defer m.Shutdown()

	var udp *net.UDPConn
	for port := 60000; port < 61000; port++ {
		udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
		udpLn, err := net.ListenPacket("udp", udpAddr)
		if err == nil {
			udp = udpLn.(*net.UDPConn)
			break
		}
	}

	if udp == nil {
		t.Fatalf("no udp listener")
	}

	// Pass a nil node with no nodes registered, should result in no checksum
	payload := []byte{3, 3, 3, 3}
	m.rawSendMsgUDP(udp.LocalAddr(), nil, payload)

	in := make([]byte, 1500)
	n, _, err := udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	if len(in) != 4 {
		t.Fatalf("bad: %v", in)
	}

	// Pass a non-nil node with PMax >= 5, should result in a checksum
	m.rawSendMsgUDP(udp.LocalAddr(), &Node{PMax: 5}, payload)

	in = make([]byte, 1500)
	n, _, err = udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	if len(in) != 9 {
		t.Fatalf("bad: %v", in)
	}

	// Register a node with PMax >= 5 to be looked up, should result in a checksum
	m.nodeMap["127.0.0.1"] = &nodeState{
		Node: Node{PMax: 5},
	}
	m.rawSendMsgUDP(udp.LocalAddr(), nil, payload)

	in = make([]byte, 1500)
	n, _, err = udp.ReadFrom(in)
	if err != nil {
		t.Fatalf("unexpected err %s", err)
	}
	in = in[0:n]

	if len(in) != 9 {
		t.Fatalf("bad: %v", in)
	}
}
示例#24
0
文件: socks.go 项目: guest6379/gost
func (s *Socks5Server) transportUDP(relay, peer *net.UDPConn) (err error) {
	errc := make(chan error, 2)

	var clientAddr *net.UDPAddr

	go func() {
		b := make([]byte, LargeBufferSize)

		for {
			n, laddr, err := relay.ReadFromUDP(b)
			if err != nil {
				errc <- err
				return
			}
			if clientAddr == nil {
				clientAddr = laddr
			}
			dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n]))
			if err != nil {
				errc <- err
				return
			}

			raddr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String())
			if err != nil {
				continue // drop silently
			}
			if _, err := peer.WriteToUDP(dgram.Data, raddr); err != nil {
				errc <- err
				return
			}
			glog.V(LDEBUG).Infof("[socks5-udp] %s >>> %s length: %d", relay.LocalAddr(), raddr, len(dgram.Data))
		}
	}()

	go func() {
		b := make([]byte, LargeBufferSize)

		for {
			n, raddr, err := peer.ReadFromUDP(b)
			if err != nil {
				errc <- err
				return
			}
			if clientAddr == nil {
				continue
			}
			buf := bytes.Buffer{}
			dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(0, 0, ToSocksAddr(raddr)), b[:n])
			dgram.Write(&buf)
			if _, err := relay.WriteToUDP(buf.Bytes(), clientAddr); err != nil {
				errc <- err
				return
			}
			glog.V(LDEBUG).Infof("[socks5-udp] %s <<< %s length: %d", relay.LocalAddr(), raddr, len(dgram.Data))
		}
	}()

	select {
	case err = <-errc:
		//log.Println("w exit", err)
	}

	return
}
示例#25
0
文件: main.go 项目: nbari/UDP-proxy
func close(c *net.UDPConn) {
	log.Printf("closing: %s -> %s", c.LocalAddr().String(), c.RemoteAddr().String())
	c.Close()
}
示例#26
0
文件: socks.go 项目: guest6379/gost
func (s *Socks5Server) tunnelUDP(uc *net.UDPConn, cc net.Conn, client bool) (err error) {
	errc := make(chan error, 2)

	var clientAddr *net.UDPAddr

	go func() {
		b := make([]byte, LargeBufferSize)

		for {
			n, addr, err := uc.ReadFromUDP(b)
			if err != nil {
				errc <- err
				return
			}

			var dgram *gosocks5.UDPDatagram
			if client { // pipe from relay to tunnel
				dgram, err = gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n]))
				if err != nil {
					errc <- err
					return
				}
				if clientAddr == nil {
					clientAddr = addr
				}
				dgram.Header.Rsv = uint16(len(dgram.Data))
				if err := dgram.Write(cc); err != nil {
					errc <- err
					return
				}
				glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", uc.LocalAddr(), dgram.Header.Addr, len(dgram.Data))
			} else { // pipe from peer to tunnel
				dgram = gosocks5.NewUDPDatagram(
					gosocks5.NewUDPHeader(uint16(n), 0, ToSocksAddr(addr)), b[:n])
				if err := dgram.Write(cc); err != nil {
					errc <- err
					return
				}
				glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", cc.RemoteAddr(), dgram.Header.Addr, len(dgram.Data))
			}
		}
	}()

	go func() {
		for {
			dgram, err := gosocks5.ReadUDPDatagram(cc)
			if err != nil {
				errc <- err
				return
			}

			if client { // pipe from tunnel to relay
				if clientAddr == nil {
					continue
				}
				dgram.Header.Rsv = 0

				buf := bytes.Buffer{}
				dgram.Write(&buf)
				if _, err := uc.WriteToUDP(buf.Bytes(), clientAddr); err != nil {
					errc <- err
					return
				}
				glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", uc.LocalAddr(), dgram.Header.Addr, len(dgram.Data))
			} else { // pipe from tunnel to peer
				addr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String())
				if err != nil {
					continue // drop silently
				}
				if _, err := uc.WriteToUDP(dgram.Data, addr); err != nil {
					errc <- err
					return
				}
				glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", cc.RemoteAddr(), addr, len(dgram.Data))
			}
		}
	}()

	select {
	case err = <-errc:
	}

	return
}
示例#27
0
// NetIO shares GitChanges on toNet with the network via a multicast group. It
// will pass on GitChanges from the network via fromNet. It uniques the daemon
// instance by changing the .Name member to be name@<host IP>/<original .Name)
func NetIO(l log.Logger, repo Repo, addr *net.UDPAddr, fromNet, toNet chan GitChange) {
	var (
		err                error
		recvConn, sendConn *net.UDPConn // UDP connections to allow us to send and	receive change updates
	)

	l.Info("Joining %v multicast(%t) group", addr, addr.IP.IsMulticast())
	if recvConn, sendConn, err = establishConnPair(addr); err != nil {
		l.Critical("Error joining listening: %s\n", addr, err)
		return
	}

	l.Info("Successfully joined %v multicast(%t) group", addr, addr.IP.IsMulticast())
	defer recvConn.Close()
	defer sendConn.Close()
	hostIp := sendConn.LocalAddr().(*net.UDPAddr).IP.String()

	term := false
	defer func() { term = true }()
	rawFromNet := make(chan []byte, 128)
	go func() {
		for !term {
			b := make([]byte, 1024)

			if n, err := recvConn.Read(b); err != nil {
				l.Critical("Cannot read socket: %s", err)
				continue
			} else {
				rawFromNet <- b[:n]
			}
		}
	}()

	for {
		select {
		case req, ok := <-toNet:
			if !ok {
				return
			}

			req.User = repo.User()
			req.HostIp = hostIp

			l.Info("Sending %+v", req)
			buf := &bytes.Buffer{}
			enc := gob.NewEncoder(buf)

			if err := enc.Encode(req); err != nil {
				l.Critical("%s", err)
				continue
			}

			l.Fine("Sending %+v", buf.Bytes())
			if _, err := sendConn.Write(buf.Bytes()); err != nil {
				l.Critical("%s", err)
				continue
			}

		case resp := <-rawFromNet:
			var change GitChange
			dec := gob.NewDecoder(bytes.NewReader(resp))

			if err := dec.Decode(&change); err != nil {
				l.Critical("%s", err)
				continue
			} else {
				l.Debug("received %+v", change)
			}

			if rootCommit, err := repo.RootCommit(); err != nil {
				log.Critical("Error getting root commit")
			} else {
				if (repo.User() != change.User) && (rootCommit == change.RootCommit) {
					fromNet <- change
				}
			}
		}
	}
}
示例#28
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
}