首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >golang强制net/http客户端使用IPv4 / IPv6

golang强制net/http客户端使用IPv4 / IPv6
EN

Stack Overflow用户
提问于 2018-10-30 08:39:16
回答 4查看 6.9K关注 0票数 10

我正在使用go1.11 net/http,并且想要检测一个域是否仅限IPv6。

你干什么了?

我创建了自己的DialContext,因为我想要检测域是否仅限IPV6。下面的代码

代码语言:javascript
运行
复制
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解决这个问题。我不知道在高朗怎么做。有人能帮帮我吗?非常感谢!

EN

回答 4

Stack Overflow用户

发布于 2018-10-30 10:43:01

传递给Control函数的networktcp4 (对于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“。

票数 2
EN

Stack Overflow用户

发布于 2018-11-01 20:40:55

噢。我自己解决了这个问题。

我们无法配置强制ipv6连接,因为它是硬编码的

代码语言:javascript
运行
复制
...
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)

票数 2
EN

Stack Overflow用户

发布于 2020-06-02 03:38:28

我认为即使服务器正在监听"tcp“,使用”tcp“运行net.Dial的客户机也应该可以很好地工作-在双协议栈设置中。

当我遇到这个问题时,罪魁祸首是/etc/hosts。它有一个映射到ipv4地址而不是ipv6地址的主机条目。这会导致连接被拒绝。

我的测试示例如下:

客户端代码:

代码语言:javascript
运行
复制
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")
}

服务器代码:

代码语言:javascript
运行
复制
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文件很好地协同工作。

谢谢。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53055808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档