// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to // use the known local interfaces. If ifaceAddr is nil, we request interface addresses // from the network stack. (this is so you can provide a cached value if resolving many addrs) func ResolveUnspecifiedAddress(resolve ma.Multiaddr, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) { // split address into its components split := ma.Split(resolve) // if first component (ip) is not unspecified, use it as is. if !manet.IsIPUnspecified(split[0]) { return []ma.Multiaddr{resolve}, nil } out := make([]ma.Multiaddr, 0, len(ifaceAddrs)) for _, ia := range ifaceAddrs { // must match the first protocol to be resolve. if ia.Protocols()[0].Code != resolve.Protocols()[0].Code { continue } split[0] = ia joined := ma.Join(split...) out = append(out, joined) log.Debug("adding resolved addr:", resolve, joined, out) } if len(out) < 1 { return nil, fmt.Errorf("failed to resolve: %s", resolve) } return out, nil }
// buildChain returns two parralel slices. One holds a sequence of MatchAppliers, // which is capable to handle the given Multiaddr with the side constant. // The second: full Multiaddr split into one or more protocols a piece, which // is what each MatchApplier.Apply expects as its m argument. // // Allowed values for side are match.S_Server and match.S_Client. func (mr matchreg) buildChain(m ma.Multiaddr, side int) ([]match.MatchApplier, []ma.Multiaddr, error) { tail := m chain := []match.MatchApplier{} split := []ma.Multiaddr{} for tail.String() != "" { mch, n, err := mr.matchPrefix(tail, side) if err != nil { return nil, nil, err } spl := ma.Split(tail) head := ma.Join(spl[:n]...) tail = ma.Join(spl[n:]...) split = append(split, head) chain = append(chain, mch) } return chain, split, nil }