예제 #1
0
파일: rwc.go 프로젝트: Gaboose/go-pubsub
func client(whole net.Conn) (ErrorCodeRWC, error) {
	sconn, _ := transport.NewConn(whole, false)
	go sconn.Serve(func(smux.Stream) {})

	mainPeel, err := sconn.OpenStream()
	if err != nil {
		return nil, err
	}

	err = sroute.SelectProtoOrFail("/main", mainPeel)
	if err != nil {
		return nil, err
	}

	ecPeel, err := sconn.OpenStream()
	if err != nil {
		return nil, err
	}

	err = sroute.SelectProtoOrFail("/ec", ecPeel)
	if err != nil {
		return nil, err
	}

	ecCh := make(chan byte)
	go readToCh(ecPeel, ecCh)

	return &errorCodeRWC{whole, mainPeel, ecPeel, ecCh}, nil
}
예제 #2
0
파일: id.go 프로젝트: libp2p/go-libp2p
func (ids *IDService) IdentifyConn(c inet.Conn) {
	ids.currmu.Lock()
	if wait, found := ids.currid[c]; found {
		ids.currmu.Unlock()
		log.Debugf("IdentifyConn called twice on: %s", c)
		<-wait // already identifying it. wait for it.
		return
	}
	ch := make(chan struct{})
	ids.currid[c] = ch
	ids.currmu.Unlock()

	defer close(ch)

	s, err := c.NewStream()
	if err != nil {
		log.Debugf("error opening initial stream for %s: %s", ID, err)
		log.Event(context.TODO(), "IdentifyOpenFailed", c.RemotePeer())
		c.Close()
		return
	}
	defer s.Close()

	s.SetProtocol(ID)

	if ids.Reporter != nil {
		s = mstream.WrapStream(s, ids.Reporter)
	}

	// ok give the response to our handler.
	if err := msmux.SelectProtoOrFail(ID, s); err != nil {
		log.Debugf("error writing stream header for %s", ID)
		log.Event(context.TODO(), "IdentifyOpenFailed", c.RemotePeer())
		return
	}

	ids.ResponseHandler(s)

	ids.currmu.Lock()
	_, found := ids.currid[c]
	delete(ids.currid, c)
	ids.currmu.Unlock()

	if !found {
		log.Debugf("IdentifyConn failed to find channel (programmer error) for %s", c)
		return
	}
}
예제 #3
0
func Client(target string, proto string) error {
	con, err := net.Dial("tcp", target)
	if err != nil {
		return err
	}
	defer con.Close()

	err = mss.SelectProtoOrFail(proto, con)
	if err != nil {
		return err
	}

	data := make([]byte, 4096)
	rand.Read(data)
	errs := make(chan error)

	go func() {
		_, err := con.Write(data)
		errs <- err
	}()

	go func() {
		resp := make([]byte, 4096)
		_, err := io.ReadFull(con, resp)
		if err != nil {
			errs <- err
			return
		}

		if !bytes.Equal(resp, data) {
			errs <- fmt.Errorf("data wasnt the same!!")
		}
		errs <- nil
	}()

	err = <-errs
	if err != nil {
		return err
	}
	err = <-errs
	if err != nil {
		return err
	}
	return nil
}
예제 #4
0
func (gw *Gateway) Dial(dest pnet.Peer, proto string) (io.ReadWriteCloser, error) {
	// See if we already have a connection with this peer.
	s, err := gw.conns.NewStreamWithGroup(dest.Id())
	if err != nil {
		// We don't, let's create a new connection.

		//TODO: Dial many/all addrs, use earliest. Like here:
		//https://github.com/ipfs/go-ipfs/blob/master/p2p/net/swarm/swarm_dial.go
		p, ok := dest.(*PeerInfo)
		if !ok {
			return nil, errors.New("Unknown pnet.Peer type")
		}

		m, err := ma.NewMultiaddrBytes(p.MAddrs[0])
		if err != nil {
			return nil, err
		}

		nc, err := manet.Dial(m)
		if err != nil {
			return nil, err
		}

		c, err := gw.conns.AddConn(nc)
		if err != nil {
			nc.Close()
			return nil, err
		}
		gw.conns.AddConnToGroup(c, p.Id())

		s, err = gw.conns.NewStreamWithGroup(p.Id())
		if err != nil {
			return nil, err
		}
	}

	// Select the protocol on the new stream.
	err = ms.SelectProtoOrFail(proto, s)
	if err != nil {
		s.Close()
	}

	return s, err
}
예제 #5
0
파일: id.go 프로젝트: tilgovi/go-libp2p
func (ids *IDService) IdentifyConn(c inet.Conn) {
	ids.currmu.Lock()
	if wait, found := ids.currid[c]; found {
		ids.currmu.Unlock()
		log.Debugf("IdentifyConn called twice on: %s", c)
		<-wait // already identifying it. wait for it.
		return
	}
	ids.currid[c] = make(chan struct{})
	ids.currmu.Unlock()

	s, err := c.NewStream()
	if err != nil {
		log.Debugf("error opening initial stream for %s", ID)
		log.Event(context.TODO(), "IdentifyOpenFailed", c.RemotePeer())
		c.Close()
		return
	} else {
		bwc := ids.Host.GetBandwidthReporter()
		s = mstream.WrapStream(s, ID, bwc)

		// ok give the response to our handler.
		if err := msmux.SelectProtoOrFail(ID, s); err != nil {
			log.Debugf("error writing stream header for %s", ID)
			log.Event(context.TODO(), "IdentifyOpenFailed", c.RemotePeer())
			s.Close()
			return
		} else {
			ids.ResponseHandler(s)
		}
	}

	ids.currmu.Lock()
	ch, found := ids.currid[c]
	delete(ids.currid, c)
	ids.currmu.Unlock()

	if !found {
		log.Debugf("IdentifyConn failed to find channel (programmer error) for %s", c)
		return
	}

	close(ch) // release everyone waiting.
}
예제 #6
0
func TestRelayStress(t *testing.T) {
	buflen := 1 << 18
	iterations := 10

	ctx := context.Background()

	// these networks have the relay service wired in already.
	n1 := testutil.GenHostSwarm(t, ctx)
	n2 := testutil.GenHostSwarm(t, ctx)
	n3 := testutil.GenHostSwarm(t, ctx)

	n1p := n1.ID()
	n2p := n2.ID()
	n3p := n3.ID()

	n2pi := n2.Peerstore().PeerInfo(n2p)
	if err := n1.Connect(ctx, n2pi); err != nil {
		t.Fatalf("Failed to dial:", err)
	}
	if err := n3.Connect(ctx, n2pi); err != nil {
		t.Fatalf("Failed to dial:", err)
	}

	// setup handler on n3 to copy everything over to the pipe.
	piper, pipew := io.Pipe()
	n3.SetStreamHandler(protocol.TestingID, func(s inet.Stream) {
		log.Debug("relay stream opened to n3!")
		log.Debug("piping and echoing everything")
		w := io.MultiWriter(s, pipew)
		io.Copy(w, s)
		log.Debug("closing stream")
		s.Close()
	})

	// ok, now we can try to relay n1--->n2--->n3.
	log.Debug("open relay stream")
	s, err := n1.NewStream(ctx, n2p, relay.ID)
	if err != nil {
		t.Fatal(err)
	}

	// ok first thing we write the relay header n1->n3
	log.Debug("write relay header")
	if err := relay.WriteHeader(s, n1p, n3p); err != nil {
		t.Fatal(err)
	}

	// ok now the header's there, we can write the next protocol header.
	log.Debug("write testing header")
	if err := msmux.SelectProtoOrFail(string(protocol.TestingID), s); err != nil {
		t.Fatal(err)
	}

	// okay, now write lots of text and read it back out from both
	// the pipe and the stream.
	buf1 := make([]byte, buflen)
	buf2 := make([]byte, len(buf1))
	buf3 := make([]byte, len(buf1))

	fillbuf := func(buf []byte, b byte) {
		for i := range buf {
			buf[i] = b
		}
	}

	for i := 0; i < iterations; i++ {
		fillbuf(buf1, byte(int('a')+i))
		log.Debugf("writing %d bytes (%d/%d)", len(buf1), i, iterations)
		if _, err := s.Write(buf1); err != nil {
			t.Fatal(err)
		}

		log.Debug("read it out from the pipe.")
		if _, err := io.ReadFull(piper, buf2); err != nil {
			t.Fatal(err)
		}
		if string(buf1) != string(buf2) {
			t.Fatal("should've gotten that text out of the pipe")
		}

		// read it out from the stream (echoed)
		log.Debug("read it out from the stream (echoed).")
		if _, err := io.ReadFull(s, buf3); err != nil {
			t.Fatal(err)
		}
		if string(buf1) != string(buf3) {
			t.Fatal("should've gotten that text out of the stream")
		}
	}

	log.Debug("sweet, relay works under stress.")
	s.Close()
}
예제 #7
0
func TestRelaySimple(t *testing.T) {

	ctx := context.Background()

	// these networks have the relay service wired in already.
	n1 := testutil.GenHostSwarm(t, ctx)
	n2 := testutil.GenHostSwarm(t, ctx)
	n3 := testutil.GenHostSwarm(t, ctx)

	n1p := n1.ID()
	n2p := n2.ID()
	n3p := n3.ID()

	n2pi := n2.Peerstore().PeerInfo(n2p)
	if err := n1.Connect(ctx, n2pi); err != nil {
		t.Fatal("Failed to connect:", err)
	}
	if err := n3.Connect(ctx, n2pi); err != nil {
		t.Fatal("Failed to connect:", err)
	}

	// setup handler on n3 to copy everything over to the pipe.
	piper, pipew := io.Pipe()
	n3.SetStreamHandler(protocol.TestingID, func(s inet.Stream) {
		log.Debug("relay stream opened to n3!")
		log.Debug("piping and echoing everything")
		w := io.MultiWriter(s, pipew)
		io.Copy(w, s)
		log.Debug("closing stream")
		s.Close()
	})

	// ok, now we can try to relay n1--->n2--->n3.
	log.Debug("open relay stream")
	s, err := n1.NewStream(ctx, n2p, relay.ID)
	if err != nil {
		t.Fatal(err)
	}

	// ok first thing we write the relay header n1->n3
	log.Debug("write relay header")
	if err := relay.WriteHeader(s, n1p, n3p); err != nil {
		t.Fatal(err)
	}

	// ok now the header's there, we can write the next protocol header.
	log.Debug("write testing header")
	if err := msmux.SelectProtoOrFail(string(protocol.TestingID), s); err != nil {
		t.Fatal(err)
	}

	// okay, now we should be able to write text, and read it out.
	buf1 := []byte("abcdefghij")
	buf2 := make([]byte, 10)
	buf3 := make([]byte, 10)
	log.Debug("write in some text.")
	if _, err := s.Write(buf1); err != nil {
		t.Fatal(err)
	}

	// read it out from the pipe.
	log.Debug("read it out from the pipe.")
	if _, err := io.ReadFull(piper, buf2); err != nil {
		t.Fatal(err)
	}
	if string(buf1) != string(buf2) {
		t.Fatal("should've gotten that text out of the pipe")
	}

	// read it out from the stream (echoed)
	log.Debug("read it out from the stream (echoed).")
	if _, err := io.ReadFull(s, buf3); err != nil {
		t.Fatal(err)
	}
	if string(buf1) != string(buf3) {
		t.Fatal("should've gotten that text out of the stream")
	}

	// sweet. relay works.
	log.Debug("sweet, relay works.")
	s.Close()
}