예제 #1
0
파일: ucat.go 프로젝트: utamaro/utp
// Dial connects to a remote address and pipes all os.Stdin to the remote end.
// If localAddr is set, uses it to Dial from.
func Dial(localAddr, remoteAddr string) error {

	var laddr net.Addr
	var err error
	if localAddr != "" {
		laddr, err = utp.ResolveAddr("utp", localAddr)
		if err != nil {
			return fmt.Errorf("failed to resolve address %s", localAddr)
		}
	}

	if laddr != nil {
		log("dialing %s from %s", remoteAddr, laddr)
	} else {
		log("dialing %s", remoteAddr)
	}

	d := utp.Dialer{LocalAddr: laddr}
	c, err := d.Dial("utp", remoteAddr)
	if err != nil {
		return err
	}
	log("connected to %s", c.RemoteAddr())

	netcat(c)
	return c.Close()
}
예제 #2
0
파일: router.go 프로젝트: h2so5/murcott
func getOpenPortConn(config utils.Config) (*utp.Listener, error) {
	for _, port := range config.Ports() {
		addr, err := utp.ResolveAddr("utp", ":"+strconv.Itoa(port))
		conn, err := utp.Listen("utp", addr)
		if err == nil {
			return conn, nil
		}
	}
	return nil, errors.New("fail to bind port")
}
예제 #3
0
파일: ucat_test.go 프로젝트: utamaro/utp
func TestUcatListen(t *testing.T) {
	child, err := gexpect.Spawn("libutp/ucat-static -l -p 8000")
	if err != nil {
		t.Fatal(err)
	}

	time.Sleep(500 * time.Millisecond)
	addr, err := utp.ResolveAddr("utp", "127.0.0.1:8000")
	if err != nil {
		t.Fatal(err)
	}
	c, err := utp.DialUTPTimeout("utp", nil, addr, 1000*time.Millisecond)
	if err != nil {
		t.Fatal(err)
	}

	var payload [128]byte
	_, err = rand.Read(payload[:])
	if err != nil {
		t.Fatal(err)
	}

	msg := hex.EncodeToString(payload[:])
	_, err = c.Write([]byte(msg + "\n"))
	if err != nil {
		t.Fatal(err)
	}

	err = child.ExpectTimeout(msg, 1000*time.Millisecond)
	if err != nil {
		t.Fatal(err)
	}

	child.SendLine(msg + "\n")

	err = c.SetDeadline(time.Now().Add(1000 * time.Millisecond))
	if err != nil {
		t.Fatal(err)
	}

	var buf [1024]byte
	l, err := c.Read(buf[:])
	if err != nil {
		t.Fatal(err)
	}

	if string(buf[:l]) != msg+"\n" {
		t.Errorf("expected payload of %s; got %s", msg, string(buf[:l]))
	}

	c.Close()
	child.Wait()
}
예제 #4
0
파일: router.go 프로젝트: h2so5/murcott
func (p *Router) getDirectSession(id utils.NodeID) *session {
	if id.Match(p.id) {
		return nil
	}
	p.sessionMutex.RLock()
	if s, ok := p.sessions[id]; ok {
		p.sessionMutex.RUnlock()
		return s
	}
	p.sessionMutex.RUnlock()

	var info *utils.NodeInfo
	p.dhtMutex.RLock()
	info = p.mainDht.GetNodeInfo(id)
	if info == nil {
		for _, d := range p.groupDht {
			info = d.GetNodeInfo(id)
			if info != nil {
				break
			}
		}
	}
	p.dhtMutex.RUnlock()

	if info == nil {
		return nil
	}

	addr, err := utp.ResolveAddr("utp", info.Addr.String())
	if err != nil {
		p.logger.Error("%v", err)
		return nil
	}

	conn, err := utp.DialUTPTimeout("utp", nil, addr, 100*time.Millisecond)
	if err != nil {
		p.logger.Error("%v %v", addr, err)
		return nil
	}

	s, err := newSesion(conn, p.key)
	if err != nil {
		conn.Close()
		p.logger.Error("%v", err)
		return nil
	} else {
		go p.readSession(s)
		p.addSession(s)
	}

	return s
}
예제 #5
0
파일: ucat.go 프로젝트: utamaro/utp
// Listen listens and accepts one incoming uTP connection on a given port,
// and pipes all incoming data to os.Stdout.
func Listen(localAddr string) error {
	laddr, err := utp.ResolveAddr("utp", localAddr)
	if err != nil {
		return fmt.Errorf("failed to resolve address %s", localAddr)
	}
	l, err := utp.Listen("utp", laddr)
	if err != nil {
		return err
	}
	log("listening at %s", l.Addr())

	c, err := l.Accept()
	if err != nil {
		return err
	}
	log("accepted connection from %s", c.RemoteAddr())

	// should be able to close listener here, but utp.Listener.Close
	// closes all open connections.
	defer l.Close()

	netcat(c)
	return c.Close()
}
예제 #6
0
파일: dht_test.go 프로젝트: h2so5/murcott
func TestDhtGroup(t *testing.T) {
	logger := log.NewLogger()

	n := 20
	dhtmap := make(map[string]*DHT)
	idary := make([]utils.NodeInfo, n)

	for i := 0; i < n; i++ {
		id := utils.NewRandomNodeID(namespace)
		addr, err := utp.ResolveAddr("utp", ":0")
		if err != nil {
			t.Fatal(err)
		}
		utp, err := utp.Listen("utp", addr)
		uaddr, err := getLoopbackAddr(utp.Addr())
		if err != nil {
			t.Fatal(err)
		}
		node := utils.NodeInfo{ID: id, Addr: uaddr}
		d := NewDHT(10, node.ID, node.ID, utp.RawConn, logger)
		idary[i] = node
		dhtmap[id.String()] = d
		defer d.Close()

		go func() {
			var b [102400]byte
			for {
				l, addr, err := utp.RawConn.ReadFrom(b[:])
				if err != nil {
					return
				}
				d.ProcessPacket(b[:l], addr)
			}
		}()
	}

	rootNode := idary[0]
	rootDht := dhtmap[rootNode.ID.String()]

	for _, d := range dhtmap {
		d.AddNode(rootNode)
		d.FindNearestNode(d.id)
	}

	kvs := map[string]string{}
	for i := 0; i < 20; i++ {
		kvs[fmt.Sprintf("<%d>", i)] = utils.NewRandomNodeID(namespace).String()
	}

	for k, v := range kvs {
		rootDht.StoreValue(k, v)
	}

	for _, d := range dhtmap {
		for k := range kvs {
			val := d.LoadValue(k)
			if val == nil {
				t.Errorf("key not found: %s", k)
			} else if *val != kvs[k] {
				t.Errorf("wrong value for the key: %s : %s; %s expected", k, val, kvs[k])
			}
		}
	}
}
예제 #7
0
파일: dht_test.go 프로젝트: h2so5/murcott
func TestDhtPing(t *testing.T) {

	addr, err := utp.ResolveAddr("utp", ":0")
	if err != nil {
		t.Fatal(err)
	}
	utp1, err := utp.Listen("utp", addr)
	if err != nil {
		t.Fatal(err)
	}
	utp2, err := utp.Listen("utp", addr)
	if err != nil {
		t.Fatal(err)
	}

	addr1, err := getLoopbackAddr(utp1.Addr())
	if err != nil {
		t.Fatal(err)
	}
	addr2, err := getLoopbackAddr(utp2.Addr())
	if err != nil {
		t.Fatal(err)
	}

	node1 := utils.NodeInfo{ID: utils.NewRandomNodeID(namespace), Addr: addr1}
	node2 := utils.NodeInfo{ID: utils.NewRandomNodeID(namespace), Addr: addr2}

	dht1 := NewDHT(10, node1.ID, node1.ID, utp1.RawConn, log.NewLogger())
	dht2 := NewDHT(10, node2.ID, node2.ID, utp2.RawConn, log.NewLogger())
	defer dht1.Close()
	defer dht2.Close()

	go func() {
		var b [102400]byte
		for {
			l, addr, err := utp1.RawConn.ReadFrom(b[:])
			if err != nil {
				return
			}
			dht1.ProcessPacket(b[:l], addr)
		}
	}()

	go func() {
		var b [102400]byte
		for {
			l, addr, err := utp2.RawConn.ReadFrom(b[:])
			if err != nil {
				return
			}
			dht2.ProcessPacket(b[:l], addr)
		}
	}()

	dht1.AddNode(node2)

	time.Sleep(time.Millisecond * 100)

	if dht1.GetNodeInfo(node2.ID) == nil {
		t.Errorf("dht1 should know node2")
	}

	if dht2.GetNodeInfo(node1.ID) == nil {
		t.Errorf("dht2 should know node1")
	}
}
예제 #8
0
파일: main.go 프로젝트: utamaro/utp
func c2s(l int64, stream bool) float64 {
	laddr, err := utp.ResolveAddr("utp", "127.0.0.1:0")
	if err != nil {
		log.Fatal(err)
	}
	ln, err := utp.Listen("utp", laddr)
	if err != nil {
		log.Fatal(err)
	}

	cch := make(chan *utp.Conn)
	go func() {
		c, err := utp.DialUTPTimeout("utp", nil, ln.Addr().(*utp.Addr), 1000*time.Millisecond)
		if err != nil {
			log.Fatal(err)
		}

		if err != nil {
			log.Fatal(err)
		}
		cch <- c
	}()

	s, err := ln.Accept()
	if err != nil {
		log.Fatal(err)
	}
	defer s.Close()
	ln.Close()

	c := <-cch
	defer c.Close()

	rch := make(chan int)
	wch := make(chan int)

	sendHash := md5.New()
	readHash := md5.New()
	counter := ByteCounter{}

	var bps float64
	if stream {
		go func() {
			defer c.Close()
			defer close(wch)
			io.Copy(io.MultiWriter(c, sendHash, &counter), io.LimitReader(RandReader{}, l))
		}()

		go func() {
			defer close(rch)
			io.Copy(readHash, s)
		}()

		go func() {
			for {
				select {
				case <-time.After(time.Second):
					if *h {
						fmt.Printf("\r <--> %s    ", humanize.IBytes(uint64(counter.Length())))
					} else {
						fmt.Printf("\r <--> %d    ", counter.Length())
					}
				case <-rch:
					fmt.Printf("\r")
					return
				}
			}
		}()

		start := time.Now()
		<-rch
		<-wch
		bps = float64(l*8) / (float64(time.Now().Sub(start)) / float64(time.Second))

	} else {
		var sendBuf, readBuf bytes.Buffer
		io.Copy(io.MultiWriter(&sendBuf, sendHash), io.LimitReader(RandReader{}, l))

		go func() {
			defer c.Close()
			defer close(wch)
			io.Copy(c, &sendBuf)
		}()

		go func() {
			defer close(rch)
			io.Copy(&readBuf, s)
		}()

		start := time.Now()
		<-rch
		<-wch
		bps = float64(l*8) / (float64(time.Now().Sub(start)) / float64(time.Second))

		io.Copy(sendHash, &sendBuf)
		io.Copy(readHash, &readBuf)
	}

	if !bytes.Equal(sendHash.Sum(nil), readHash.Sum(nil)) {
		log.Fatal("Broken payload")
	}

	return bps
}