func (cm CommandMap) Call(name string, args []string, stdio io.ReadWriter, apiaddr ma.Multiaddr) byte { cmd, ok := cm[name] if !ok { fmt.Printf("Unknown command: %s\n", name) return 1 } switch cmd := cmd.(type) { case *LocalCommand: return cmd.Run(args, stdio) case *RemoteCommand: // Connect to daemon conn, err := manet.Dial(apiaddr) if err != nil { fmt.Println(err) return 1 } defer conn.Close() // Send arguments mx := mux.StandardMux() err = mx.Encoder(conn).Encode(append([]string{name}, args...)) if err != nil { fmt.Println(err) return 1 } // Multiplex connection remoteStdio, err := WithErrorCode(conn) if err != nil { fmt.Println(err) return 1 } // Join stdout and stdin with remote ones go io.Copy(remoteStdio, stdio) _, err = io.Copy(stdio, remoteStdio) if err != nil { fmt.Println(err) return 1 } return <-remoteStdio.ErrorCodeCh() default: fmt.Printf("Unknown type of command: %s\n", name) return 1 } }
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 }
func manetlib() { addr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/5556/udt") if err != nil { panic(err) } list, err := manet.Listen(addr) if err != nil { panic(err) } defer list.Close() runtest( func() (net.Conn, error) { return list.Accept() }, func() (net.Conn, error) { return manet.Dial(addr) }, ) }