I'm writing a SIP stack, and I need to insert an ip address in the message. This address needs to be the one used for sending the message. I know the destination IP and need to determine the NIC (its address) that will be used to send the message....
问题:
回答1:
To expand a bit on Remy Lebeau's comment, GetBestInterfaceEx() is your best bet, if you're on Windows XP or newer. That will work for both IPv4 and IPv6 addresses.
GetBestInterface/GetBestInterfaceEx return the index (call it IDX) of the most appropriate interface to use to contact some address.
Then you can map that index into a local IP address by getting your interface<->IP address mapping using GetIpAddrTable or GetAdaptersAddresses if you're dual-stacking (supporting both IPv6 and IPv4).
Iterate over that table and find the interface with the dwIndex (or IfIndex, in the case of GetAdaptersAddresses) matching IDX.
回答2:
It's usually best to allow the IP address your SIP stack will operate on to be set as an adjustable configuration option. It means the user will need to set a configuration option but at least your stack will know the IP address it's operating on.
If that's not feasible then an approach you could use is to send out the SIP request on all IP addresses using a dummy value in the Via header such as 0.0.0.0 and set the interface you get a response back on as the default one. This approach alos as the advantage that the SIP response will tell you the public IP address the request was received from which can be useful if your SIP stack is behind a NAT.
回答3:
Over TCP, I think you can get the address of the local side of the socket after connect(). I don't know if the same is true for UDP (I suspect not), but it might be worth a try.
回答4:
The socket will allow you to Bind to a local endpoint before calling connect (both UDP and TCP).
That is all ok if you know the port. However, if you want the port to be ephemeral (e.g. some random port number) then you must come up with your own algorithm to do so and robust code to handle the cases where the port is exclusivly taken by another application.