mirror of
https://github.com/xmdhs/natupnp.git
synced 2025-09-26 19:11:11 +08:00
参数改为 netip.Addr
This commit is contained in:
22
main.go
22
main.go
@@ -57,8 +57,10 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
laddrPort := netip.AddrPortFrom(netip.MustParseAddr(localAddr), uint16(portu))
|
||||
|
||||
for {
|
||||
err := openPort(ctx, target, localAddr, uint16(portu), stun, func(s netip.AddrPort) {
|
||||
err := openPort(ctx, target, laddrPort, stun, func(s netip.AddrPort) {
|
||||
fmt.Println(s)
|
||||
if comm != "" {
|
||||
c := exec.CommandContext(ctx, comm, localAddr, port, s.Addr().String(), strconv.Itoa(int(s.Port())))
|
||||
@@ -78,19 +80,19 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func openPort(ctx context.Context, target, localAddr string, portu uint16,
|
||||
func openPort(ctx context.Context, target string, laddr netip.AddrPort,
|
||||
stun string, finish func(netip.AddrPort), udp bool, testserver bool) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
if target != "" {
|
||||
var forward func(ctx context.Context, port uint16, target string, log func(string)) (io.Closer, error)
|
||||
var forward func(ctx context.Context, laddr netip.AddrPort, target string, log func(string)) (io.Closer, error)
|
||||
if udp {
|
||||
forward = natmap.ForwardUdp
|
||||
} else {
|
||||
forward = natmap.Forward
|
||||
}
|
||||
l, err := forward(ctx, portu, target, func(s string) {
|
||||
l, err := forward(ctx, laddr, target, func(s string) {
|
||||
log.Println(s)
|
||||
})
|
||||
if err != nil {
|
||||
@@ -99,21 +101,21 @@ func openPort(ctx context.Context, target, localAddr string, portu uint16,
|
||||
defer l.Close()
|
||||
}
|
||||
if testserver {
|
||||
l, err := testServer(ctx, portu)
|
||||
l, err := testServer(ctx, laddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("openPort: %w", err)
|
||||
}
|
||||
defer l.Close()
|
||||
}
|
||||
errCh := make(chan error, 1)
|
||||
var nmap func(ctx context.Context, stunAddr string, host string, port uint16, log func(error)) (*natmap.Map, netip.AddrPort, error)
|
||||
var nmap func(ctx context.Context, stunAddr string, laddr netip.AddrPort, log func(error)) (*natmap.Map, netip.AddrPort, error)
|
||||
if udp {
|
||||
nmap = natmap.NatMapUdp
|
||||
} else {
|
||||
nmap = natmap.NatMap
|
||||
}
|
||||
|
||||
m, s, err := nmap(ctx, stun, localAddr, uint16(portu), func(s error) {
|
||||
m, s, err := nmap(ctx, stun, laddr, func(s error) {
|
||||
cancel()
|
||||
select {
|
||||
case errCh <- s:
|
||||
@@ -134,16 +136,16 @@ func openPort(ctx context.Context, target, localAddr string, portu uint16,
|
||||
return nil
|
||||
}
|
||||
|
||||
func testServer(ctx context.Context, port uint16) (net.Listener, error) {
|
||||
func testServer(ctx context.Context, laddr netip.AddrPort) (net.Listener, error) {
|
||||
s := http.Server{
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
Addr: "0.0.0.0:" + strconv.FormatUint(uint64(port), 10),
|
||||
Addr: laddr.String(),
|
||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("ok"))
|
||||
}),
|
||||
}
|
||||
l, err := reuse.Listen(ctx, "tcp", "0.0.0.0:"+strconv.FormatUint(uint64(port), 10))
|
||||
l, err := reuse.Listen(ctx, "tcp", laddr.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("testServer: %w", err)
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/xmdhs/natupnp/reuse"
|
||||
@@ -20,21 +19,20 @@ type Map struct {
|
||||
cancel func()
|
||||
}
|
||||
|
||||
func getPubulicPort(ctx context.Context, stunAddr string, host string, port uint16, isTcp bool) (netip.AddrPort, error) {
|
||||
func getPubulicPort(ctx context.Context, stunAddr string, laddr netip.AddrPort, isTcp bool) (netip.AddrPort, error) {
|
||||
var (
|
||||
upnpP = "TCP"
|
||||
dialP = "tcp4"
|
||||
dialP = "tcp"
|
||||
)
|
||||
if !isTcp {
|
||||
upnpP = "UDP"
|
||||
dialP = "udp4"
|
||||
dialP = "udp"
|
||||
}
|
||||
|
||||
err := upnp.AddPortMapping(ctx, "", port, upnpP, port, host, true, "github.com/xmdhs/natupnp", 0)
|
||||
err := upnp.AddPortMapping(ctx, "", laddr.Port(), upnpP, laddr.Port(), laddr.Addr().String(), true, "github.com/xmdhs/natupnp", 0)
|
||||
if err != nil {
|
||||
return netip.AddrPort{}, fmt.Errorf("getPubulicPort: %w", err)
|
||||
}
|
||||
stunConn, err := reuse.DialContext(ctx, dialP, "0.0.0.0:"+strconv.Itoa(int(port)), stunAddr)
|
||||
stunConn, err := reuse.DialContext(ctx, dialP, laddr.String(), stunAddr)
|
||||
if err != nil {
|
||||
return netip.AddrPort{}, fmt.Errorf("getPubulicPort: %w", err)
|
||||
}
|
||||
@@ -47,16 +45,16 @@ func getPubulicPort(ctx context.Context, stunAddr string, host string, port uint
|
||||
return netip.AddrPortFrom(addr, uint16(mapAddr.Port)), nil
|
||||
}
|
||||
|
||||
func NatMap(ctx context.Context, stunAddr string, host string, port uint16, log func(error)) (*Map, netip.AddrPort, error) {
|
||||
func NatMap(ctx context.Context, stunAddr string, laddr netip.AddrPort, log func(error)) (*Map, netip.AddrPort, error) {
|
||||
m := Map{}
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
m.cancel = cancel
|
||||
|
||||
mapAddr, err := getPubulicPort(ctx, stunAddr, host, port, true)
|
||||
mapAddr, err := getPubulicPort(ctx, stunAddr, laddr, true)
|
||||
if err != nil {
|
||||
return nil, netip.AddrPort{}, fmt.Errorf("NatMap: %w", err)
|
||||
}
|
||||
go keepalive(ctx, port, log)
|
||||
go keepalive(ctx, laddr, log)
|
||||
return &m, mapAddr, nil
|
||||
}
|
||||
|
||||
@@ -65,17 +63,19 @@ func (m Map) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func keepalive(ctx context.Context, port uint16, log func(error)) {
|
||||
func keepalive(ctx context.Context, laddr netip.AddrPort, log func(error)) {
|
||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||
tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return reuse.DialContext(ctx, "tcp", "0.0.0.0:"+strconv.Itoa(int(port)), addr)
|
||||
return reuse.DialContext(ctx, "tcp", laddr.String(), addr)
|
||||
}
|
||||
tr.Proxy = nil
|
||||
c := http.Client{Transport: tr, Timeout: 5 * time.Second}
|
||||
|
||||
for {
|
||||
func() {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
reqs, err := http.NewRequestWithContext(ctx, "GET", "http://connect.rom.miui.com/generate_204", nil)
|
||||
reqs, err := http.NewRequestWithContext(ctx, "HEAD", "http://www.gstatic.com/generate_204", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -100,14 +100,14 @@ func keepalive(ctx context.Context, port uint16, log func(error)) {
|
||||
func GetLocalAddr() (net.Addr, error) {
|
||||
l, err := net.Dial("udp4", "223.5.5.5:53")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getLocal: %w", err)
|
||||
return nil, fmt.Errorf("GetLocalAddr: %w", err)
|
||||
}
|
||||
defer l.Close()
|
||||
return l.LocalAddr(), nil
|
||||
}
|
||||
|
||||
func Forward(ctx context.Context, port uint16, target string, log func(string)) (io.Closer, error) {
|
||||
l, err := reuse.Listen(ctx, "tcp", "0.0.0.0:"+strconv.FormatUint(uint64(port), 10))
|
||||
func Forward(ctx context.Context, laddr netip.AddrPort, target string, log func(string)) (io.Closer, error) {
|
||||
l, err := reuse.Listen(ctx, "tcp", laddr.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Forward: %w", err)
|
||||
}
|
||||
|
@@ -6,32 +6,35 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xmdhs/natupnp/reuse"
|
||||
)
|
||||
|
||||
func NatMapUdp(ctx context.Context, stunAddr string, host string, port uint16, log func(error)) (*Map, netip.AddrPort, error) {
|
||||
func NatMapUdp(ctx context.Context, stunAddr string, laddr netip.AddrPort, log func(error)) (*Map, netip.AddrPort, error) {
|
||||
m := Map{}
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
m.cancel = cancel
|
||||
|
||||
mapAddr, err := getPubulicPort(ctx, stunAddr, host, port, false)
|
||||
mapAddr, err := getPubulicPort(ctx, stunAddr, laddr, false)
|
||||
if err != nil {
|
||||
return nil, netip.AddrPort{}, fmt.Errorf("NatMap: %w", err)
|
||||
}
|
||||
go keepaliveUDP(ctx, port, log)
|
||||
go keepaliveUDP(ctx, laddr, log)
|
||||
return &m, mapAddr, nil
|
||||
|
||||
}
|
||||
|
||||
func keepaliveUDP(ctx context.Context, port uint16, log func(error)) {
|
||||
func keepaliveUDP(ctx context.Context, laddr netip.AddrPort, log func(error)) {
|
||||
raddr := "223.5.5.5:53"
|
||||
if laddr.Addr().Is6() {
|
||||
raddr = "[2400:3200::1]:53"
|
||||
}
|
||||
r := net.Resolver{
|
||||
PreferGo: true,
|
||||
Dial: func(context context.Context, network, address string) (net.Conn, error) {
|
||||
conn, err := reuse.DialContext(context, "udp", "0.0.0.0:"+strconv.Itoa(int(port)), "223.5.5.5:53")
|
||||
conn, err := reuse.DialContext(context, "udp", laddr.String(), raddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -67,8 +70,8 @@ func (l logger) Println(v ...any) {
|
||||
l.log(build.String())
|
||||
}
|
||||
|
||||
func ForwardUdp(ctx context.Context, port uint16, target string, log func(string)) (io.Closer, error) {
|
||||
lc, err := reuse.ListenPacket(ctx, "udp", "0.0.0.0:"+strconv.FormatUint(uint64(port), 10))
|
||||
func ForwardUdp(ctx context.Context, laddr netip.AddrPort, target string, log func(string)) (io.Closer, error) {
|
||||
lc, err := reuse.ListenPacket(ctx, "udp", laddr.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user