implement ident.me WAN option provider
This commit is contained in:
parent
a372438632
commit
928b4797f5
1 changed files with 90 additions and 0 deletions
90
main.go
90
main.go
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -9,6 +10,7 @@ import (
|
||||||
"lux/node"
|
"lux/node"
|
||||||
"lux/proto"
|
"lux/proto"
|
||||||
"lux/rpc"
|
"lux/rpc"
|
||||||
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
@ -383,6 +385,92 @@ func (wan *HostStaticWAN) Provide() (host.LuxOption, error) {
|
||||||
return &host.LuxOptionWAN{Addr4: wan.addr4, Addr6: wan.addr6}, nil
|
return &host.LuxOptionWAN{Addr4: wan.addr4, Addr6: wan.addr6}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HostIdentWAN struct{}
|
||||||
|
|
||||||
|
func dialIdentMe(identIp netip.Addr) (netip.Addr, error) {
|
||||||
|
var network string
|
||||||
|
if identIp.Is6() {
|
||||||
|
network = "tcp6"
|
||||||
|
} else {
|
||||||
|
network = "tcp4"
|
||||||
|
}
|
||||||
|
|
||||||
|
cl, err := net.DialTCP(network, nil,
|
||||||
|
net.TCPAddrFromAddrPort(netip.AddrPortFrom(identIp, 80)))
|
||||||
|
if err != nil {
|
||||||
|
return netip.Addr{}, err
|
||||||
|
}
|
||||||
|
defer cl.Close()
|
||||||
|
|
||||||
|
// I dont want to bundle http package for embedded reasons,
|
||||||
|
// so I will just bang http headers directly
|
||||||
|
const req = "GET / HTTP/1.1\r\nHost: ident.me\r\nUser-Agent: LUX-v1\r\nAccept: */*\r\n\r\n"
|
||||||
|
_, err = cl.Write([]byte(req))
|
||||||
|
if err != nil {
|
||||||
|
return netip.Addr{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res := make([]byte, 1024)
|
||||||
|
n, err := cl.Read(res)
|
||||||
|
if err != nil {
|
||||||
|
return netip.Addr{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse http headers to get response
|
||||||
|
sep := []byte{0x0D, 0x0A, 0x0D, 0x0A}
|
||||||
|
|
||||||
|
ipStr := ""
|
||||||
|
for i := 0; i < n-4; i++ {
|
||||||
|
if bytes.Equal(res[i:i+4], sep) {
|
||||||
|
ipStr = string(res[i+4 : n])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse ip
|
||||||
|
if ipStr == "" {
|
||||||
|
return netip.Addr{}, fmt.Errorf("IP not found in ident.me response: %s", string(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
// to prevent panics
|
||||||
|
parsedIp := net.ParseIP(ipStr)
|
||||||
|
if parsedIp == nil {
|
||||||
|
return netip.Addr{}, fmt.Errorf("failed to parse ident.me IP")
|
||||||
|
}
|
||||||
|
|
||||||
|
return proto.LuxProtoIPToAddr(parsedIp), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*HostIdentWAN) Provide() (host.LuxOption, error) {
|
||||||
|
wan := host.NewLuxOptionWAN()
|
||||||
|
// so first we gonna resolve ident.me and see if there is IPv6
|
||||||
|
addrs, err := net.LookupHost("ident.me")
|
||||||
|
if err != nil {
|
||||||
|
return &wan, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addr := range addrs {
|
||||||
|
ip := net.ParseIP(addr)
|
||||||
|
if ip.To4() == nil && wan.Addr6.IsUnspecified() {
|
||||||
|
// we gonna resolve IPv6
|
||||||
|
addr, err := dialIdentMe(proto.LuxProtoIPToAddr(ip))
|
||||||
|
if err == nil {
|
||||||
|
// we got IPv6
|
||||||
|
wan.Addr6 = addr
|
||||||
|
}
|
||||||
|
} else if wan.Addr4.IsUnspecified() {
|
||||||
|
addr, err := dialIdentMe(proto.LuxProtoIPToAddr(ip))
|
||||||
|
if err != nil {
|
||||||
|
// if no IPv4 its considered catastrophic error
|
||||||
|
return &wan, err
|
||||||
|
} else {
|
||||||
|
wan.Addr4 = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &wan, nil
|
||||||
|
}
|
||||||
|
|
||||||
func hostMain() {
|
func hostMain() {
|
||||||
xmlBytes, err := os.ReadFile(configPath)
|
xmlBytes, err := os.ReadFile(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -444,6 +532,8 @@ func hostMain() {
|
||||||
}
|
}
|
||||||
|
|
||||||
host.AddOptionProvider(&provider)
|
host.AddOptionProvider(&provider)
|
||||||
|
} else if wan.Method == "identme" {
|
||||||
|
host.AddOptionProvider(&HostIdentWAN{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue