How to set IP address to an existing SOCKET - sockets

I know I can get the IP address by using 'getpeername' function, but how can I set the IP address to an existing socket? I search the web and I only find that it can be done by creating a new socket. From MSDN example, it shows the same client socket can be used to receive and send, but what can I do with a different IP.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms737593(v=vs.85).aspx

If you want to force a socket towards a specific IP address or port you need to bind the socket.
More information about the bind function can be found here :
https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

Related

Socket Address in Computer Networks

I read that in the server site – The local (server) socket address is provided by the OS and the remote (client) socket address is the address of the client that makes the connection. The server can find this socket address when a client tries to connect
to the server but in the Client Site – The local (client) socket address is provided by the OS.
What about the remote (server) socket address?
The client does need some way to find the IP address of the server it wants to connect to; the most common way to find the IP address is by starting with a hostname string (e.g. "stackoverflow.com" or whatever) that was either supplied by the user or hard-coded into the program, and using DNS to look up an IP address that corresponds to that hostname string. The usual API for doing a DNS lookup is getaddrinfo(), although older (or lazier) software might call the older gethostbyname() function instead.
Once the client has the IP address of the server it wants to connect to, it also needs to supply a port number; often the port number just a well-known standard port number for a particular type of service (such as 80 for HTTP, or 22 for SSH). If not, then the client will either have to "just know" what port number to use to contact the server, or it will need some other mechanism to figure out which port number to use.

Can I bind a client socket to an ip not belongs to any interfaces?

For a client socket, I can use bind() to bind it to a specific source Ip address to select a specific interface. Or I can use connect() directly then it will pick the source ip based on routing table.
I wonder can I bind a client socket to an ip not belongs to any interfaces ? E.g.: I have two interfaces:
eth0 : ip0
eth1 : ip1
(1) If I bind the client socket to ip2. Is this feasible ?
(2) If (1) is feasible, assuming client socket sent packets thru eth0. Then I configure the iptables in this client host, to forward all incoming packets to ip0 (eth0). In this case, if there are packets sent back from server side with destination ip address is ip2 (assuming this packet will reach my client host). Will my client socket receive the packet ?
Thanks in advance.
I don't really understand your question, but here goes:
For client sockets, you typically want the the OS and its routing table to pick the best interface for you using any available port. In which case, you bind to INADDR_ANY (0) and port 0. Or don't explicitly call bind at at all. Just call connect() and it will do the right thing.
If you need the client connection to occur through a specific interface, then bind the socket to a specific IP address. And then the OS will attempt to use that interface for the subsequent connect call and all traffic after that.
Attempting to bind the socket to an IP that doesn't belong to a local interface is surely going to result in an error.
Not sure what you mean about the iptables stuff. Sounds dicey.
Please have a look at:
https://www.rsyslog.com/doc/v8-stable/configuration/modules/omfwd.html#ipfreebind
MAN:
https://man7.org/linux/man-pages/man7/ip.7.html
IP_FREEBIND (since Linux 2.4)
If enabled, this boolean option allows binding to an IP
address that is nonlocal or does not (yet) exist. This
permits listening on a socket, without requiring the
underlying network interface or the specified dynamic IP
address to be up at the time that the application is
trying to bind to it. This option is the per-socket
equivalent of the ip_nonlocal_bind /proc interface
described below.

What does it mean to bind() a socket to any address other than localhost?

I don't understand what it means to bind a socket to any address other than 127.0.0.1 (or ::1, etc.).
Am I not -- by definition -- binding the socket to a port on my own machine.. which is localhost?
What sense does it make to bind or listen to another machine or IP address's port?
Conceptually, it just doesn't make sense to me!
(This has proven surprisingly hard to Google... possibly because I'm not Googling the right terms.)
Binding of a socket is done to address and port in order to receive data on this socket (most cases) or to use this address/port as the source of the data when sending data (for example used with data connections in FTP server).
Usually there are several interfaces on a specific machine, i.e. the pseudo-interface loopback where the machine can reach itself, ethernet, WLAN, VPN... . Each of these interfaces can have multiple IP addresses assigned. For example, loopback usually has 127.0.0.1 and with IPv6 also ::1, but you can assign others too. Ethernet or WLAN have the IP addresses on the local network, i.e. 172.16.0.34 or whatever.
If you bind a socket for receiving data to a specific address you can only receive data sent to this specific IP address. For example, if you bind to 127.0.0.1 you will be able to receive data from your own system but not from some other system on the local network, because they cannot send data to your 127.0.0.1: for one any data to 127.0.0.1 will be sent to their own 127.0.0.1 and second your 127.0.0.1 is an address on your internal loopback interface which is not reachable from outside.
You can also bind a socket to a catch-all address like 0.0.0.0 (Ipv4) and :: (Ipv6). In this case it is not bound to a specific IP address but will be able to receive data send to any IP address of the machine.

Obtaining the source IP and port of an INADDR_ANY client socket before the TCP three-way handshake?

I'm on Windows 7, using bind before connect with SO_REUSEADDR, and setting the local address structure to IP address INADDR _ANY and port 0 (zero), in order to let the operating system select the source details for a client socket.
Firstly, I've read that it's not possible to get the source IP before connecting to the server, since it's being chosen at this point and several addresses can be valid. But the port is selected before the connection, so is there a way to get it? (getsockname() looks like to not work).
Secondly, about the source IP, is there a way to get it before a packet is sent to the server? I need the specific time between the moment the OS selected the source IP and the moment it starts the three-way handshake. The connect() function dominates the both.
I'm on Windows 7, using bind before connect with SO_REUSEADDR
Why are you using SO_REUSEADDR in this situation? You don't need it, and it makes no sense for what you are attempting. SO_REUSEADDR should typically only be used for a listening socket, not a connecting socket.
setting the local address structure to IP address INADDR _ANY and port 0 (zero), in order to let the operating system select the source details for a client socket.
It is meaningless to bind() a client socket to INADDR_ANY:0. You can (and should) omit such a bind() completely and leave the socket unbound until connect() is called. The only time you should ever bind() a client socket is if you want to bind it to a specific local IP and/or Port. But you are not doing that in this situation, so get rid of it.
Firstly, I've read that it's not possible to get the source IP before connecting to the server, since it's being chosen at this point and several addresses can be valid.
Correct, unless you bind() to a specific source IP.
But the port is selected before the connection
Both source IP and source port are selected by connect() if the socket is unbound, or bound to source IP INADDR_ANY and/or source port 0. So you have no opportunity to query either value before connect() has selected them.
so is there a way to get it? (getsockname() looks like to not work).
getsockname() is exactly what you need. Just make sure you are not calling it until connect() has successfully connected to the server first. This is stated in the getsockname() documentation:
This call is especially useful when a connect call has been made without doing a bind first; the getsockname function provides the only way to determine the local association that has been set by the system.
...
The getsockname function does not always return information about the host address when the socket has been bound to an unspecified address, unless the socket has been connected with connect or accept (for example, using ADDR_ANY). A Windows Sockets application must not assume that the address will be specified unless the socket is connected. The address that will be used for the socket is unknown unless the socket is connected when used in a multihomed host. If the socket is using a connectionless protocol, the address may not be available until I/O occurs on the socket.
Secondly, about the source IP, is there a way to get it before a packet is sent to the server?
For TCP, you can retrieve the selected source IP using getsockname() immediately after connect() has successfully connected to the server. Not before.
I need the specific time between the moment the OS selected the source IP and the moment it starts the three-way handshake.
It is not possible to determine that detail. No socket application should ever need that detail. Why do you need it?
I'm on Windows 7, using bind before connect with SO_REUSEADDR, and setting the local address structure to IP address INADDR _ANY and port 0 (zero), in order to let the operating system select the source details for a client socket.
Why? That's exactly what happens if you don't call bind() at all, during connect(). Binding a client socket to INADDR_ANY isn't correct in any case. Setting SO_REUSEADDR doesn't make sense either without specifying a non-zero port number. Just remove all this.
Firstly, I've read that it's not possible to get the source IP before connecting to the server, since it's being chosen at this point and several addresses can be valid.
Correct.
But the port is selected before the connection, so is there a way to get it?
Yes. getsockname().
(getsockname() looks like to not work)
Doesn't work how?
Secondly, about the source IP, is there a way to get it before a packet is sent to the server?
You can get it with getsockname() as soon as connect() has succeeded, but this involves sending packets to the server.
I need the specific time between the moment the OS selected the source IP and the moment it starts the three-way handshake. The connect() function dominates the both.
Bad luck.

Can I do strict socket bind for a client ip address at server side?

I need to accept only connections from particular client ip address at server side. Should not use acl. With help of socket strict bind at server side can i do?
Example:
client ip address: 1.1.1.1
server ip address: 1.1.1.2
At server side:
1. Open a socket
2. Bind socket with 1.1.1.1(client ip address) with port no.
Will i be allow to do the second step at server side? Any special options are there to do?
Please let me know.
Thanks,
Boobesh
You can only bind the server port to an ip address to specify the interface to use.
For example your server has two network interfaces, one connected to the internet and one to a configuration network. The webserver should maybe only listen on the internet interface and a management tool only listen on the configuration network.
For your purpose you can accept the connection, compare the ip address and if it is not in the list of allowed clients close the connection immediately (or after sending an error message).
The other solution would be to use a firewall that is configured to allow only connections from the specified clients to the server port.
I agree with the friend above, u can only manage the ip and port in you server, but not client. u should compare the coming socket with the one u store in your server.