Skip to content

Instantly share code, notes, and snippets.

@fufuok
Created December 30, 2022 04:40
Show Gist options
  • Save fufuok/f1cc0789b6c1d96dc98106a706bc3858 to your computer and use it in GitHub Desktop.
Save fufuok/f1cc0789b6c1d96dc98106a706bc3858 to your computer and use it in GitHub Desktop.
Golang binds the local interface IP to request the URL, and you can choose to specify the domain name resolution result IP or customize DNS resolution. 绑定接口IP(源IP)请求URL, 指定域名解析结果IP.
package main
import (
"context"
"flag"
"io"
"log"
"net"
"net/http"
"os"
"time"
)
func main() {
localIP := flag.String("localip", "", "Bind local IP")
reqUrl := flag.String("url", "https://ipinfo.io", "URL to request")
domainAddr := flag.String("domainaddr", "", "Specify domain name resolution IP, 34.117.59.81:443")
flag.Parse()
log.Printf("URL to request: %s\n", *reqUrl)
resp, err := Request("GET", *reqUrl, nil, *localIP, *domainAddr)
if err != nil {
log.Fatalln(err)
}
_, _ = io.Copy(os.Stdout, resp.Body)
_ = resp.Body.Close()
}
func Request(method, url string, body io.Reader, localIP, domainAddr string) (*http.Response, error) {
client := http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return CustomDialContext(ctx, network, addr, localIP, domainAddr)
},
TLSHandshakeTimeout: 10 * time.Second,
},
}
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, err
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
func CustomDialContext(ctx context.Context, network, addr, localIP, domainAddr string) (net.Conn, error) {
// Specify domain name resolution IP, or custom domain name resolution
if domainAddr != "" {
log.Printf("Specify domain name resolution IP: %s -> %s\n", addr, domainAddr)
addr = domainAddr
}
var laddr *net.TCPAddr
if localIP != "" {
var err error
// Automatically assign source port
log.Printf("Bind local IP: %s\n", localIP)
laddr, err = net.ResolveTCPAddr(network, localIP+":0")
if err != nil {
return nil, err
}
}
dialer := &net.Dialer{
Timeout: 10 * time.Second,
KeepAlive: 10 * time.Second,
LocalAddr: laddr,
}
return dialer.DialContext(ctx, network, addr)
}
// Demo:
//
// root@10:~/ff# ./bindipget -h
// Usage of ./bindipget:
// -domainaddr string
// Specify domain name resolution IP, 34.117.59.81:443
// -localip string
// Bind local IP
// -url string
// URL to request (default "https://ipinfo.io")
//
// root@10:~/ff# ./bindipget
// 2022/12/30 12:32:18 URL to request: https://ipinfo.io
// {
// "ip": "1.2.3.4",
// "city": "Hong Kong",
// "region": "Central and Western",
// "country": "HK",
// "loc": "22.2783,114.1747",
// "org": "AS146834 SiChuan XunYou Network Technologe Limit, co",
// "timezone": "Asia/Hong_Kong",
// "readme": "https://ipinfo.io/missingauth"
// }
//
// root@10:~/ff# ./bindipget -localip=172.16.1.2
// 2022/12/30 12:32:34 URL to request: https://ipinfo.io
// 2022/12/30 12:32:34 Bind local IP: 172.16.1.2
// {
// "ip": "1.2.3.5",
// "city": "Hong Kong",
// "region": "Central and Western",
// "country": "HK",
// "loc": "22.2783,114.1747",
// "org": "AS146834 SiChuan XunYou Network Technologe Limit, co",
// "timezone": "Asia/Hong_Kong",
// "readme": "https://ipinfo.io/missingauth"
// }
//
// root@10:~/ff# ./bindipget -localip=172.16.1.2 -domainaddr=34.117.59.81:443
// 2022/12/30 12:32:50 URL to request: https://ipinfo.io
// 2022/12/30 12:32:50 Specify domain name resolution IP: ipinfo.io:443 -> 34.117.59.81:443
// 2022/12/30 12:32:50 Bind local IP: 172.16.1.2
// {
// "ip": "129.227.157.190",
// "city": "Hong Kong",
// "region": "Central and Western",
// "country": "HK",
// "loc": "22.2783,114.1747",
// "org": "AS146834 SiChuan XunYou Network Technologe Limit, co",
// "timezone": "Asia/Hong_Kong",
// "readme": "https://ipinfo.io/missingauth"
// }
//
// root@10:~/ff# ./bindipget -localip=172.16.1.2 -url="http://4.ipw.cn"
// 2022/12/30 12:33:24 URL to request: http://4.ipw.cn
// 2022/12/30 12:33:24 Bind local IP: 172.16.1.2
// 1.2.3.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment