Skip to content
This repository has been archived by the owner on May 11, 2022. It is now read-only.

replace the port number for double NAT mapping #101

Merged
merged 5 commits into from
Feb 22, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion svc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package autonat
import (
"context"
"errors"
"fmt"
"math/rand"
"net"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -115,6 +117,7 @@ func (as *autoNATService) handleDial(p peer.ID, obsaddr ma.Multiaddr, mpi *pb.Me
obsHost, _ = manet.ToIP(obsaddr)
}

obscodename, obsport, _ := as.extractPort(obsaddr)
for _, maddr := range mpi.GetAddrs() {
addr, err := ma.NewMultiaddrBytes(maddr)
if err != nil {
Expand All @@ -123,7 +126,18 @@ func (as *autoNATService) handleDial(p peer.ID, obsaddr ma.Multiaddr, mpi *pb.Me
}

if as.config.dialPolicy.skipDial(addr) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may skip an address because it's a relay address (e.g.). This logic will continue to dial said addresses.

continue
if manet.IsPrivateAddr(addr) {
addrcodename, addrport, err := as.extractPort(addr)
if err == nil && addrcodename == obscodename && addrport != obsport { //make a new address
obsportstr := fmt.Sprintf("/%s/%s", obscodename, obsport)
addrportstr := fmt.Sprintf("/%s/%s", addrcodename, addrport)
addr, err = ma.NewMultiaddr(strings.Replace(obsaddr.String(), obsportstr, addrportstr, -1)) //replace the private addr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could have issues with circuit addresses or other weird edges of multiaddr. rather than string replace prefer finding the component with the expected code, and changing it in that way using the multiaddr library for parsing.

Copy link
Contributor Author

@huo-ju huo-ju Feb 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nat obsaddr shouldn't be a circuit address or over the proxy, and it supposed to be a simple /ipv4 or /ipv6 address in this situation.

The go-multiaddr package didn't provide a function to replace a component and I have to rewrite all bytes and parse to multiaddr, so replace the /tcp/port could be a clean way to resolve the issue, IMO.

} else {
huo-ju marked this conversation as resolved.
Show resolved Hide resolved
continue
}
} else {
continue
}
}

if ip, err := manet.ToIP(addr); err != nil || !obsHost.Equal(ip) {
Expand Down Expand Up @@ -228,3 +242,16 @@ func (as *autoNATService) background(ctx context.Context) {
}
}
}

func (as *autoNATService) extractPort(m ma.Multiaddr) (name string, port string, err error) {
for _, p := range m.Protocols() {
if p.Code == ma.P_TCP || p.Code == ma.P_UDP {
v, err := m.ValueForProtocol(p.Code)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than iterating through all protocols in m, can you instead directly see if there is a value for the 2 protocols of instance?

Copy link
Contributor Author

@huo-ju huo-ju Feb 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The multiformats encoding format is (<addr-protocol-code><addr-value>)+ so /tcp/34372/ip4/192.168.0.100 also a correctly formatted address, but search over bytes might be a better way.

if err != nil {
return "", "", err
}
return p.Name, v, nil
}
}
return "", "", errors.New("can't extract port")
}