Usage of getaddrinfo() with AI_PASSIVE

前端 未结 2 1616
忘了有多久
忘了有多久 2021-01-12 22:52

The getaddrinfo() function not only allows for client programs to efficiently find the correct data for creating a socket to a given host, it also allows for se

相关标签:
2条回答
  • 2021-01-12 23:07

    Your getaddrinfo is returning the wrong result for some reason. It's supposed to return the IPv6 socket first. The only thing I can think of is if your OS detects that your system has a low prio IPv6 (6to4 or Teredo) and avoids them, IMO wrongly so in that case. Edit: Just noticed my own computer does the same thing, I use 6to4.

    However, you can either listen to both of them, or use AF_INET6 instead of AF_UNSPEC. Then you can do setsockopt to disable IPV6_V6ONLY.

    getaddrinfo does the reasonable thing here and returns all applicable results (though in the wrong order, as I mentioned). Both one and two listen sockets are valid approaches, depending on your application.

    0 讨论(0)
  • 2021-01-12 23:07

    JFTR: It seems now that the program given in the manpage is wrong.

    There are two possible approaches for listening to both IP types:

    1. Create only a IPv6 socket and switch off the v6 only flag:

      from socket import *
      s = socket(AF_INET6, SOCK_STREAM)
      s.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0)
      s.bind(...)
      

      resp.

      from socket import *
      ai = getaddrinfo(None, ..., AF_INET6, SOCK_STREAM, 0, AI_PASSIVE)[0]
      s = socket(ai[0], ai[1], ai[2])
      s.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0)
      s.bind(ai[4])
      

      Pros:

      • simpler to handle

      Cons:

      • doesn't work under XP (AFAIK) - there are two different protocol stacks
    2. work with two sockets and switch on the v6only flag:

      from socket import *
      aii = getaddrinfo(None, ..., AF_UNSPEC, SOCK_STREAM, 0, AI_PASSIVE)
      sl = []
      for ai in aii:
          s = socket(ai[0], ai[1], ai[2])
          if ai[0] == AF_INET6: s.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 1)
          s.bind(ai[4])
          sl.append(s)
      

      and handle all sockets in sl in accepting loop (use select() or nonblocking IO to do so)

      Pros:

      • uses a (nearly) protocol independent handling with getaddrinfo()
      • works under XP as well

      Cons:

      • complicated to handle
    0 讨论(0)
提交回复
热议问题