Esempio n. 1
0
func (h httpreuser) Match(m ma.Multiaddr, side int) (int, bool) {
	if side != S_Server {
		return 0, false
	}

	// check if h.prefix is a prefix of m
	ms := ma.Split(m)
	ps := ma.Split(h.prefix)

	if len(ms) < len(ps) {
		return 0, false
	}

	for i, p := range ps {
		if !p.Equal(ms[i]) {
			return 0, false
		}
	}

	// match an additional http protocol if it's there
	if len(ms) > len(ps) && ms[len(ps)].String() == "/http" {
		return len(ps) + 1, true
	}

	return len(ps), true
}
Esempio n. 2
0
func pickLocalAddr(laddrs []ma.Multiaddr, raddr ma.Multiaddr) (laddr ma.Multiaddr) {
	if len(laddrs) < 1 {
		return nil
	}

	// make sure that we ONLY use local addrs that match the remote addr.
	laddrs = manet.AddrMatch(raddr, laddrs)
	if len(laddrs) < 1 {
		return nil
	}

	// make sure that we ONLY use local addrs that CAN dial the remote addr.
	// filter out all the local addrs that aren't capable
	raddrIPLayer := ma.Split(raddr)[0]
	raddrIsLoopback := manet.IsIPLoopback(raddrIPLayer)
	raddrIsLinkLocal := manet.IsIP6LinkLocal(raddrIPLayer)
	laddrs = addrutil.FilterAddrs(laddrs, func(a ma.Multiaddr) bool {
		laddrIPLayer := ma.Split(a)[0]
		laddrIsLoopback := manet.IsIPLoopback(laddrIPLayer)
		laddrIsLinkLocal := manet.IsIP6LinkLocal(laddrIPLayer)
		if laddrIsLoopback { // our loopback addrs can only dial loopbacks.
			return raddrIsLoopback
		}
		if laddrIsLinkLocal {
			return raddrIsLinkLocal // out linklocal addrs can only dial link locals.
		}
		return true
	})

	// TODO pick with a good heuristic
	// we use a random one for now to prevent bad addresses from making nodes unreachable
	// with a random selection, multiple tries may work.
	return laddrs[rand.Intn(len(laddrs))]
}
Esempio n. 3
0
// 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
}
Esempio n. 4
0
// AddrOverNonLocalIP returns whether the addr uses a non-local ip link
func AddrOverNonLocalIP(a ma.Multiaddr) bool {
	split := ma.Split(a)
	if len(split) < 1 {
		return false
	}
	if manet.IsIP6LinkLocal(split[0]) {
		return false
	}
	return true
}
Esempio n. 5
0
// AddrIsShareableOnWAN returns whether the given address should be shareable on the
// wide area network (wide internet).
func AddrIsShareableOnWAN(addr ma.Multiaddr) bool {
	s := ma.Split(addr)
	if len(s) < 1 {
		return false
	}
	a := s[0]
	if manet.IsIPLoopback(a) || manet.IsIP6LinkLocal(a) || manet.IsIPUnspecified(a) {
		return false
	}
	return manet.IsThinWaist(a)
}
Esempio n. 6
0
// 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
}
Esempio n. 7
0
// observerGroup is a function that determines what part of
// a multiaddr counts as a different observer. for example,
// two ipfs nodes at the same IP/TCP transport would get
// the exact same NAT mapping; they would count as the
// same observer. This may protect against NATs who assign
// different ports to addresses at different IP hosts, but
// not TCP ports.
//
// Here, we use the root multiaddr address. This is mostly
// IP addresses. In practice, this is what we want.
func observerGroup(m ma.Multiaddr) string {
	return ma.Split(m)[0].String()
}