func (d *tcpDialer) reuseDial(raddr ma.Multiaddr) (manet.Conn, error) { logdial := lgbl.Dial("conn", "", "", d.laddr, raddr) rpev := log.EventBegin(context.TODO(), "tptDialReusePort", logdial) network, netraddr, err := manet.DialArgs(raddr) if err != nil { return nil, err } con, err := d.rd.Dial(network, netraddr) if err == nil { logdial["reuseport"] = "success" rpev.Done() return manet.WrapNetConn(con) } if !ReuseErrShouldRetry(err) { logdial["reuseport"] = "failure" logdial["error"] = err rpev.Done() return nil, err } logdial["reuseport"] = "retry" logdial["error"] = err rpev.Done() return d.madialer.Dial(raddr) }
func reuseDial(dialer net.Dialer, laddr, raddr ma.Multiaddr) (conn net.Conn, retry bool, err error) { if laddr == nil { // if we're given no local address no sense in using reuseport to dial, dial out as usual. return nil, true, reuseport.ErrReuseFailed } // give reuse.Dialer the manet.Dialer's Dialer. // (wow, Dialer should've so been an interface...) rd := reuseport.Dialer{dialer} // get the local net.Addr manually rd.D.LocalAddr, err = manet.ToNetAddr(laddr) if err != nil { return nil, true, err // something wrong with laddr. retry without. } // get the raddr dial args for rd.dial network, netraddr, err := manet.DialArgs(raddr) if err != nil { return nil, true, err // something wrong with laddr. retry without. } // rd.Dial gets us a net.Conn with SO_REUSEPORT and SO_REUSEADDR set. conn, err = rd.Dial(network, netraddr) return conn, reuseErrShouldRetry(err), err // hey! it worked! }
func apiClientForAddr(addr ma.Multiaddr) (cmdsHttp.Client, error) { _, host, err := manet.DialArgs(addr) if err != nil { return nil, err } return cmdsHttp.NewClient(host), nil }
// rawConnDial dials the underlying net.Conn + manet.Conns func (d *Dialer) rawConnDial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (manet.Conn, error) { // before doing anything, check we're going to be able to dial. // we may not support the given address. if _, _, err := manet.DialArgs(raddr); err != nil { return nil, err } if strings.HasPrefix(raddr.String(), "/ip4/0.0.0.0") { log.Event(ctx, "connDialZeroAddr", lgbl.Dial("conn", d.LocalPeer, remote, nil, raddr)) return nil, fmt.Errorf("Attempted to connect to zero address: %s", raddr) } // get local addr to use. laddr := pickLocalAddr(d.LocalAddrs, raddr) logdial := lgbl.Dial("conn", d.LocalPeer, remote, laddr, raddr) defer log.EventBegin(ctx, "connDialRawConn", logdial).Done() // make a copy of the manet.Dialer, we may need to change its timeout. madialer := d.Dialer if laddr != nil && reuseportIsAvailable() { // we're perhaps going to dial twice. half the timeout, so we can afford to. // otherwise our context would expire right after the first dial. madialer.Dialer.Timeout = (madialer.Dialer.Timeout / 2) // dial using reuseport.Dialer, because we're probably reusing addrs. // this is optimistic, as the reuseDial may fail to bind the port. rpev := log.EventBegin(ctx, "connDialReusePort", logdial) if nconn, retry, reuseErr := reuseDial(madialer.Dialer, laddr, raddr); reuseErr == nil { // if it worked, wrap the raw net.Conn with our manet.Conn logdial["reuseport"] = "success" rpev.Done() return manet.WrapNetConn(nconn) } else if !retry { // reuseDial is sure this is a legitimate dial failure, not a reuseport failure. logdial["reuseport"] = "failure" logdial["error"] = reuseErr rpev.Done() return nil, reuseErr } else { // this is a failure to reuse port. log it. logdial["reuseport"] = "retry" logdial["error"] = reuseErr rpev.Done() } } defer log.EventBegin(ctx, "connDialManet", logdial).Done() return madialer.Dial(raddr) }
func (f *Filters) AddrBlocked(a ma.Multiaddr) bool { _, addr, err := manet.DialArgs(a) if err != nil { // if we cant parse it, its probably not blocked return false } ipstr := strings.Split(addr, ":")[0] ip := net.ParseIP(ipstr) for _, ft := range f.filters { if ft.Contains(ip) { return true } } return false }
// NewMapping attemps to construct a mapping on protocol and internal port // It will also periodically renew the mapping until the returned Mapping // -- or its parent NAT -- is Closed. // // May not succeed, and mappings may change over time; // NAT devices may not respect our port requests, and even lie. // Clients should not store the mapped results, but rather always // poll our object for the latest mappings. func (nat *NAT) NewMapping(maddr ma.Multiaddr) (Mapping, error) { if nat == nil { return nil, fmt.Errorf("no nat available") } network, addr, err := manet.DialArgs(maddr) if err != nil { return nil, fmt.Errorf("DialArgs failed on addr:", maddr.String()) } switch network { case "tcp", "tcp4", "tcp6": network = "tcp" case "udp", "udp4", "udp6": network = "udp" default: return nil, fmt.Errorf("transport not supported by NAT: %s", network) } intports := strings.Split(addr, ":")[1] intport, err := strconv.Atoi(intports) if err != nil { return nil, err } m := &mapping{ nat: nat, proto: network, intport: intport, intaddr: maddr, } m.proc = goprocess.WithTeardown(func() error { nat.rmMapping(m) return nil }) nat.addMapping(m) m.proc.AddChild(periodic.Every(MappingDuration/3, func(worker goprocess.Process) { nat.establishMapping(m) })) // do it once synchronously, so first mapping is done right away, and before exiting, // allowing users -- in the optimistic case -- to use results right after. nat.establishMapping(m) return m, nil }
func main() { flag.Parse() // extract address from host flag addr, err := ma.NewMultiaddr(*host) if err != nil { log.Fatal("NewMultiaddr() failed: ", err) } p := addr.Protocols() if len(p) < 2 { log.Fatal("need two protocols in host flag (/ip/tcp): ", addr) } _, host, err := manet.DialArgs(addr) if err != nil { log.Fatal("manet.DialArgs() failed: ", err) } if *verbose { // lower log level logging.SetDebugLogging() } // construct url to dial var u url.URL u.Scheme = "http" u.Host = host u.Path = *endpoint // show what we got start := time.Now() log.Debug("starting at %s, tries: %d, timeout: %s, url: %s", start, *tries, *timeout, u) for *tries > 0 { err := checkOK(http.Get(u.String())) if err == nil { log.Debugf("ok - endpoint reachable with %d tries remaining, took %s", *tries, time.Since(start)) os.Exit(0) } log.Debug("get failed: ", err) time.Sleep(*timeout) *tries-- } log.Error("failed.") os.Exit(1) }
func getNodesAPIAddr(nnum int) (string, error) { addrb, err := ioutil.ReadFile(path.Join(IpfsDirN(nnum), "api")) if err != nil { return "", err } maddr, err := ma.NewMultiaddr(string(addrb)) if err != nil { fmt.Println("error parsing multiaddr: ", err) return "", err } _, addr, err := manet.DialArgs(maddr) if err != nil { fmt.Println("error on multiaddr dialargs: ", err) return "", err } return addr, nil }
func manetListen(addr ma.Multiaddr) (manet.Listener, error) { network, naddr, err := manet.DialArgs(addr) if err != nil { return nil, err } if ReuseportIsAvailable() { nl, err := reuseport.Listen(network, naddr) if err == nil { // hey, it worked! return manet.WrapNetListener(nl) } // reuseport is available, but we failed to listen. log debug, and retry normally. log.Debugf("reuseport available, but failed to listen: %s %s, %s", network, naddr, err) } // either reuseport not available, or it failed. try normally. return manet.Listen(addr) }
func (s *UtpSocket) Dial(raddr ma.Multiaddr) (Conn, error) { _, addr, err := manet.DialArgs(raddr) if err != nil { return nil, err } con, err := s.s.Dial(addr) if err != nil { return nil, err } mnc, err := manet.WrapNetConn(&mautp.Conn{Conn: con}) if err != nil { return nil, err } return &connWrap{ Conn: mnc, transport: s.transport, }, nil }
func (t *UtpTransport) newConn(addr ma.Multiaddr, opts ...DialOpt) (*UtpSocket, error) { network, netaddr, err := manet.DialArgs(addr) if err != nil { return nil, err } s, err := utp.NewSocket("udp"+network[3:], netaddr) if err != nil { return nil, err } laddr, err := manet.FromNetAddr(mautp.MakeAddr(s.LocalAddr())) if err != nil { return nil, err } return &UtpSocket{ s: s, laddr: laddr, transport: t, }, nil }
func IpfsStart(waitall bool) error { var addrs []string n := GetNumNodes() for i := 0; i < n; i++ { dir := IpfsDirN(i) cmd := exec.Command("ipfs", "daemon") cmd.Dir = dir cmd.Env = envForDaemon(i) setupOpt(cmd) stdout, err := os.Create(path.Join(dir, "daemon.stdout")) if err != nil { return err } stderr, err := os.Create(path.Join(dir, "daemon.stderr")) if err != nil { return err } cmd.Stdout = stdout cmd.Stderr = stderr err = cmd.Start() if err != nil { return err } pid := cmd.Process.Pid fmt.Printf("Started daemon %d, pid = %d\n", i, pid) err = ioutil.WriteFile(path.Join(dir, "daemon.pid"), []byte(fmt.Sprint(pid)), 0666) if err != nil { return err } // Make sure node 0 is up before starting the rest so // bootstrapping works properly cfg, err := serial.Load(path.Join(IpfsDirN(i), "config")) if err != nil { return err } maddr := ma.StringCast(cfg.Addresses.API) _, addr, err := manet.DialArgs(maddr) if err != nil { return err } addrs = append(addrs, addr) err = waitOnAPI(cfg.Identity.PeerID, i) if err != nil { return err } } if waitall { for i := 0; i < n; i++ { err := waitOnSwarmPeers(i) if err != nil { return err } } } return nil }
func callCommand(ctx context.Context, req cmds.Request, root *cmds.Command, cmd *cmds.Command) (cmds.Response, error) { log.Info(config.EnvDir, " ", req.InvocContext().ConfigRoot) var res cmds.Response err := req.SetRootContext(ctx) if err != nil { return nil, err } details, err := commandDetails(req.Path(), root) if err != nil { return nil, err } log.Debug("looking for running daemon...") useDaemon, err := commandShouldRunOnDaemon(*details, req, root) if err != nil { return nil, err } err = callPreCommandHooks(ctx, *details, req, root) if err != nil { return nil, err } if cmd.PreRun != nil { err = cmd.PreRun(req) if err != nil { return nil, err } } if useDaemon { cfg, err := req.InvocContext().GetConfig() if err != nil { return nil, err } addr, err := ma.NewMultiaddr(cfg.Addresses.API) if err != nil { return nil, err } log.Infof("Executing command on daemon running at %s", addr) _, host, err := manet.DialArgs(addr) if err != nil { return nil, err } client := cmdsHttp.NewClient(host) res, err = client.Send(req) if err != nil { return nil, err } } else { log.Debug("Executing command locally") err := req.SetRootContext(ctx) if err != nil { return nil, err } // Okay!!!!! NOW we can call the command. res = root.Call(req) } if cmd.PostRun != nil { cmd.PostRun(req, res) } return res, nil }