我正在使用go1.11 net/http,并且想要检测一个域是否仅限IPv6。
你干什么了?
我创建了自己的DialContext,因为我想要检测域是否仅限IPV6。下面的代码
package main
import (
"errors"
"fmt"
"net"
"net/http"
"syscall"
"time"
)
func ModifiedTransport() {
var MyTransport = &http.Transport{
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: false,
Control: func(network, address string, c syscall.RawConn) error {
if network == "ipv4" {
// I want to cancel connection here client.Get("http://myexample.com") return a non-nil err.
return errors.New("you should not use ipv4")
}
return nil
},
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
var myClient = http.Client{Transport: MyTransport}
resp, myerr := myClient.Get("http://www.github.com")
if myerr != nil {
fmt.Println("request error")
return
}
var buffer = make([]byte, 1000)
resp.Body.Read(buffer)
fmt.Println(string(buffer))
}
func main(){
ModifiedTransport();
}
我现在不知道如何关闭请求,即使我可以进入network == "ipv4"
。
加法
Python可以通过Force requests to use IPv4 / IPv6解决这个问题。我不知道在高朗怎么做。有人能帮帮我吗?非常感谢!
发布于 2018-10-30 10:43:01
传递给Control
函数的network
为tcp4
(对于IPv4连接)或tcp6
(对于IPv6连接)(如果您正在进行传出TCP连接)。
来自type Dialer
上的评论
// Network and address parameters passed to Control method are not // necessarily the ones passed to Dial. For example, passing "tcp" to Dial // will cause the Control function to be called with "tcp4" or "tcp6".
(在非TCP连接情况下,可以使用other strings。)
已知的网络是"tcp“、"tcp4”(仅IPV4)、"tcp6“(仅限IPV6)、"udp”、"udp4“(仅限IPV4)、"udp6”(仅限IPV6)、"ip“、"ip4”(仅限IPV4)、"ip6“(仅限IPV6)、"unix”、“unix”和"unixpacket“。
发布于 2018-11-01 20:40:55
噢。我自己解决了这个问题。
我们无法配置强制ipv6连接,因为它是硬编码的
...
if cm.scheme() == "https" && t.DialTLS != nil {
var err error
pconn.conn, err = t.DialTLS("tcp", cm.addr())
if err != nil {
return nil, wrapErr(err)
}
...
( code here.)
我为transport.go添加了一个ipv6only标志,一个getTcpString(),它可以工作。
(diff here)
发布于 2020-06-02 03:38:28
我认为即使服务器正在监听"tcp“,使用”tcp“运行net.Dial的客户机也应该可以很好地工作-在双协议栈设置中。
当我遇到这个问题时,罪魁祸首是/etc/hosts。它有一个映射到ipv4地址而不是ipv6地址的主机条目。这会导致连接被拒绝。
我的测试示例如下:
客户端代码:
package main
import "net"
import "fmt"
func main() {
conn, err := net.Dial("tcp", "hostname:9876")
if err != nil {
fmt.Println("Error in net.Dial", err)
return
}
conn.Close()
fmt.Println("Successful")
}
服务器代码:
package main
import "net"
import "fmt"
func main() {
lis, err := net.Listen("tcp6", ":9876")
if err != nil {
fmt.Println("Error in listen", err)
return
}
for {
_, err := lis.Accept()
if err != nil {
fmt.Println("Error in Accept", err)
return
}
}
}
这段代码应该可以在双堆栈设置中与干净的/etc/hosts文件很好地协同工作。
谢谢。
https://stackoverflow.com/questions/53055808
复制相似问题