// DialArgs is a convenience function returning arguments for use in net.Dial func DialArgs(m ma.Multiaddr) (string, string, error) { if !IsThinWaist(m) { return "", "", fmt.Errorf("%s is not a 'thin waist' address", m) } str := m.String() parts := strings.Split(str, "/")[1:] if len(parts) == 2 { // only IP return parts[0], parts[1], nil } network := parts[2] if parts[2] == "udp" && len(parts) > 4 && parts[4] == "utp" { network = parts[4] } var host string switch parts[0] { case "ip4": host = strings.Join([]string{parts[1], parts[3]}, ":") case "ip6": host = fmt.Sprintf("[%s]:%s", parts[1], parts[3]) } return network, host, nil }
// DialAddr connects to a peer over a particular address // Ensures raddr is part of peer.Addresses() // Example: d.DialAddr(ctx, peer.Addresses()[0], peer) func (d *Dialer) DialAddr(ctx context.Context, raddr ma.Multiaddr, remote peer.Peer) (Conn, error) { found := false for _, addr := range remote.Addresses() { if addr.Equal(raddr) { found = true } } if !found { return nil, debugerror.Errorf("address %s is not in peer %s", raddr, remote) } network, _, err := manet.DialArgs(raddr) if err != nil { return nil, err } laddr := d.LocalPeer.NetAddress(network) if laddr == nil { return nil, debugerror.Errorf("No local address for network %s", network) } if strings.HasPrefix(raddr.String(), "/ip4/0.0.0.0") { return nil, debugerror.Errorf("Attempted to connect to zero address: %s", raddr) } remote.SetType(peer.Remote) remote, err = d.Peerstore.Add(remote) if err != nil { log.Errorf("Error putting peer into peerstore: %s", remote) } // TODO: try to get reusing addr/ports to work. // madialer := manet.Dialer{LocalAddr: laddr} madialer := manet.Dialer{} log.Infof("%s dialing %s %s", d.LocalPeer, remote, raddr) maconn, err := madialer.Dial(raddr) if err != nil { return nil, err } c, err := newSingleConn(ctx, d.LocalPeer, remote, maconn) if err != nil { return nil, err } return newSecureConn(ctx, c, d.Peerstore) }
func outfmt(m ma.Multiaddr) string { switch format { case "string": return m.String() case "slice": return fmt.Sprintf("%v", m.Bytes()) case "bytes": return string(m.Bytes()) case "hex": return "0x" + hex.EncodeToString(m.Bytes()) } die("error: invalid format", format) return "" }