douzongluo7542 2016-05-24 00:06
浏览 153
已采纳

以编程方式进行DNS SRV绑定

Could anybody know how to set up SRV record locally in Go?

It's for testing purposes. For example, I want to bind test.com to localhost just during the tests. Currently, I have to edit host /etc/bind/test.com.hosts

test.com.   IN  SOA bindhostname. admin.test.com. (
1452607488
10800
3600
604800
38400 )
test.com.   IN  NS  bindhostname.
my1.test.com.   300 IN  A   127.0.0.1
_etcd-client._tcp   300 IN  SRV 0 0 5000 my1.test.com.

I looked at https://github.com/miekg/dns but can't figure out where to start. Could anybody help?

Thanks!

  • 写回答

1条回答 默认 最新

  • dongshuobei1037 2016-05-26 22:59
    关注

    First you need to add your local ip to /etc/resolv.conf

    Then you can use following code:

    package main
    
    import (
        "log"
        "net"
    
        "github.com/miekg/dns"
    )
    
    const (
        DOM    = "test.com."
        srvDom = "_etcd-client._tcp."
    )
    
    func handleSRV(w dns.ResponseWriter, r *dns.Msg) {
        var a net.IP
        m := new(dns.Msg)
        m.SetReply(r)
        if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok {
            a = ip.IP
        }
        if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok {
            a = ip.IP
        }
    
        // Add in case you are using IPv6 alongwith AAAA
        /*if a.To4() !=nil {
            a = a.To4()
            }
        */
        // Checking which type of query has come
        switch r.Question[0].Qtype {
        default:
            fallthrough
        case dns.TypeA:
            rr := new(dns.A)
            rr.Hdr = dns.RR_Header{Name: DOM, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
            rr.A = a.To4()
            m.Answer = append(m.Answer, rr)
        case dns.TypeSRV:
            rr := new(dns.SRV)
            rr.Hdr = dns.RR_Header{Name: srvDom, Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: 0}
            rr.Priority = 0
            rr.Weight = 0
            rr.Port = 5000
            rr.Target = DOM
            m.Answer = append(m.Answer, rr)
        }
        w.WriteMsg(m)
    }
    
    func serve(net string) {
        server := &dns.Server{Addr: ":53", Net: net, TsigSecret: nil}
        err := server.ListenAndServe()
        if err != nil {
            log.Fatal("Server can't be started")
        }
    }
    
    func main() {
        dns.HandleFunc(DOM, handleSRV)
        dns.HandleFunc(srvDom, handleSRV)
        go serve("tcp")
        go serve("udp")
        for {
        }
    }
    

    You can check that this bind server gives correct answer for dig

    dig @"127.0.0.1"  _etcd-client._tcp. SRV
    

    I have assumed that you are using IPv4 address (It's addition of about only ten lines but I wanted code to be succinct without handling IPv6).

    You can change DOM and SRV pattern that I have taken as const.

    You can integrate this as library which start the dns server when you do test. I am using port 53 for which you need to be root user. You can change it to something else. And when tests are run, you can get it from some different port.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 yolov8边框坐标
  • ¥15 matlab中使用gurobi时报错
  • ¥15 WPF 大屏看板表格背景图片设置
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真