bio-routing / bio-rd

bio routing is a project to create a versatile, fast and reliable routing daemon in Golang. bio = BGP + IS-IS + OSPF
Apache License 2.0
283 stars 44 forks source link

Bind is always 0.0.0.0 regardless of specified address in listener #450

Closed netixx closed 10 months ago

netixx commented 11 months ago

Describe the bug A clear and concise description of what the bug is.

Steps to Reproduce in cmd/bio-rd/main.go, configure a bind IP for

listenAddrsByVRF := map[string][]string{
        vrf.DefaultVRFName: {
            "10.0.0.1:179",
        },
    }

Expected behavior The program should bind the socket on the provided IP address.

Configuration used

routing_options:
  autonomous_system: 111
  router_id: 10.0.0.1
policy_options:
  policy_statements:
    - name: "ACCEPT_ALL"
      terms:
        - name: "ACCEPT_ALL"
          then:
            accept: true
    - name: "REJECT_ALL"
      terms:
        - name: "REJECT_ALL"
          then:
            reject: true
protocols:
  bgp:
    groups:
      - name: "IXP RS Clients"
        local_address: 10.0.0.1
        #route_server_client: true
        passive: true
        neighbors:
          - peer_address: 10.0.0.2
            peer_as: 111
            import: ["ACCEPT_ALL"]
            export: ["REJECT_ALL"]

Additional context By modifying the code in net/tcp/listen.go the following way:

fmt.Println(laddr.IP)
    fmt.Println(ipv4AddrToArray(laddr.IP))
    if laddr.IP.To4() != nil {
        err = unix.Bind(fd, &unix.SockaddrInet4{
            Port: laddr.Port,
            Addr: ipv4AddrToArray(laddr.IP),
        })
    } else {
        err = unix.Bind(fd, &unix.SockaddrInet6{
            Port: laddr.Port,
            Addr: ipv6AddrToArray(laddr.IP),
        })
    }

I was able to produce the following output:

strace -e trace=network ./bio-rd
10.0.0.1
[0 0 0 0]
bind(13, {sa_family=AF_INET, sin_port=htons(2179), sin_addr=inet_addr("0.0.0.0")}, 16) = 0

As you can see the bind call is 0.0.0.0 beccause ipv4AddrToArray returns [0 0 0 0].

netixx commented 11 months ago

Looks like the bytes are store in index 12,13,14 and 15:

func ipv4AddrToArray(x net.IP) [4]byte {
    return [4]byte{
        x[12], x[13], x[14], x[15],
    }
}

at least in go1.21 (source net/ip.go).

BarbarossaTM commented 11 months ago

Thanks for the detailed bug report!

I'll provide a fix asap :)

netixx commented 11 months ago

Thanks for the quick work!! Honestly I thought there would be better way to convert (in the sdtlib), but I didn't find any!! Maybe the new netip package has something...

Just to mention: I think the function should be fine for ipv6, but I didn't test it!