(WinSock), What should I fill in WSARecvFrom source ip address for server? - udp

So, I'm implementing udp packet communication between client and server.
I've already done sending udp data to client from server using WSASendTo
For client side, the parameter sockaddr* ipFrom in WSARecvFrom is server's endpoint. Everything works good.
But the problem is that the server uses only one udp socket, so I don't know what should I fill in sockaddr* ipFrom parameter in WSARecvFrom. Since each client has different ip, I can't specify the source ip address.
I tried to just fill nullptr in this parameter but it didn't work. And I tried fill it with server endpoint, and it worked.
But as you know, using server endpoint for ipFrom doesn't make sense because that is not source address, so I'm curious what address/endpoint should I fill in sockaddr* ipFrom.
EDIT : By the way, I binded udp socket as server ip/port before using it.

the problem is that the server uses only one udp socket, so I don't know what should I fill in sockaddr* ipFrom parameter in WSARecvFrom.
Nothing. That is not your responsibility to do in that call.
But as you know, using server endpoint for ipFrom doesn't make sense because that is not source address, so I'm curious what address/endpoint should I fill in sockaddr* ipFrom.
None.
You seem to have a misunderstanding of what the ipFrom parameter is meant for. It is an output parameter, not an input parameter. So you don't need to supply any data to it at all. WSARecvFrom() receives an incoming packet. If you want to know who the sender of that packet is (ie, to send a subsequent reply back using WSASendTo()), you supply a pointer to an allocated sockaddr_... and then WSARecvFrom() fills it with the sender's info. You don't fill the sockaddr_... yourself at all.
Just like when the client receives a packet from the server and WSARecvFrom() reports the server's info, the same is true when the server receives a packet from a client and WSARecvFrom() reports the client's info.

Related

Will ICE negotiations between peers behind two symmetric NAT's result in requiring two TURN servers?

I read RFC6577 and RFC8445 but I feel like there is a bit of a disconnect between how TURN can be used versus how ICE actually utilizes the relay candidates.
The TURN RFC describes the use of one single TURN server to ferry data between a client and a peer. The transport address on the TURN server accepts data flow from a client via TURN messages, whereas the relayed transport address accepts data flow from peer(s) via UDP. This sounds great - one TURN server and bidirectional data flow.
However in reading about ICE, I feel like this never happens. Both caller and callee independently allocate on potentially two TURN servers, and then send their respective relayed transport addresses to each other. More like an I can be reached via this relayed transport address sort of thing. Connectivity checks then occur and thus, two TURN servers end up being used here where data only flows in one direction through the relayed transport address of each participants allocated TURN server.
Is this true?
From the TURN RFC, it says the following:
The client can arrange for the server to relay packets to and from
certain other hosts (called peers) and can control aspects of how the
relaying is done. The client does this by obtaining an IP address and
port on the server, called the relayed transport address. When a peer
sends a packet to the relayed transport address, the server relays the
packet to the client. When the client sends a data packet to the
server, the server relays it to the appropriate peer using the relayed
transport address as the source.
However, I can't see a scenario whereby through ICE negotiations, data would ever flow through the transport address from the client to the peer. Both the caller and the callee independently allocate on a TURN server and send relayed transport addresses to each other to be reached on.
Basically, TURN can do bidirectional data flow, but with ICE between two symmetric NAT's, it wont. Is this correct?
Its a bit complicated.... bear with me. Reading just the TURN RFC isn't enough, you need context from RFC 5245 on ICE too.
The following scenario is the baseline case:
client A allocates a relay address 8.8.8.8:43739, sends it to client B
client B sends a UDP packet to 8.8.8.8:43739
TURN servers wraps the packet in a stun message, sends it to client A
Now as you say, typically client B will also allocate its own relay address and send it to A. Why isn't that used all the time (or half the time)? The priorities of the candidates are equal after all.
However the candidate pair priority which determines which pair to pick includes a factor which acts as a tie-breaker:
pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
Where G>D?1:0 is an expression whose value is 1 if G is greater than
D, and 0 otherwise.
This means the pair where the callers (assuming its the controlling agent) relay address is used has a higher priority than the pair with the callees relay address.
Additionally, there is another candidate in the game here for the port client B uses to send to port 8.8.8.8:43739. This will typically be from one of the local candidates and the TURN server sees (and puts into the data indication) the public (post-nat) ip of client B. On client A this will show up as a remote srflx candidate -- which has a higher priority than a relayed candidate and will therefore be used.
Now if B is behind a symmetric NAT (I think) the TURN server will see a different port from client B than anything for which client A has added a permission. This will typically mean the TURN server will drop the packet and that pair won't work.
If client A is not behind a symmetric NAT, the baseline process will be repeated in the other direction. Slightly less priority but its the same in terms of latency so users won't notice.
If both clients are (and now we are finally at the case you're asking about) are behind symmetric NAT, neither will work and a relay-relay pair will be used. This is fairly rare (<1% probably) and the latency impact is typically insignificant even when both clients are on different TURN servers.

How to get handle on addr of client which lost connection?

I have a UDP server implemented using the template in the documentation, which can be found here: https://docs.python.org/3/library/asyncio-protocol.html#udp-echo-server-protocol
I would like to know the addr of the client which lost connection. The connection_lost callback only has a single parameter, exc for the exception.
Edit: Following the downvotes I want to highlight that its not a very noob-friendly part of the module naming a callback in the datagram ServerProtocol class 'connection_made'.
The Python API designers need to document this properly.
It looks like connection_made() is called when you create the socket and connect it, which in turn only happens if you specify a non-None Remote_addr.
To understand all that, first you need to understand what connect() does to a UDP socket at the Berkeley Sockets API level:
It conditions the socket so that write() andsend()can be used as well assendto()`, both of which will only send to the connected target address.
It conditions the socket to filter out all datagrams that did not originate at the connect target.
It does not create a wire connection of any kind. Nothing is received by the peer or sent on the wire in any way.
You can connect() a UDP socket multiple times, either to a different address or to null, which completely undoes (1) and (2).
So, I can only imagine that the connection_lost() callback is called when (4) happens, which it isn't in your code.
Whatever it does, if anything, it certainly can't be used to detect when a client disconnects, as there is no such event in UDP.

Why does ICE needs both-ways signaling?

To establish WebRTC connections the ICE protocol is used with a signaling server which must send messages in both directions. I wonder why after the initiator sent its offer and candidates to the other participant, the participant needed to send back its answer and candidates using the signaling channel in the other direction. Cannot the participant open the connection to the initiator using candidates from both sides and send back its answer using the open connection?
I started reading ICE RFC and the only relevant part I found is in section 5.2 where the initiator must take the controlling role and nominates candidate pairs. But it does not explain why the other could not initiate connection.
To give some background, I am trying to build a webapp for which I want users to establish WebRTC connections without using a signaling server. I thought of having the app to generate a URL including the offer and candidates and providing this URL to other participants through other medium like instant messaging. The issue I got is that the participant need to send back its answer and candidates using the same medium, which is not practical. In the end I will go for a signalling server but I wonder the technical reason.
Yes, you can do that if caller is behind public IP or Full Cone NAT(in this case, router connection mapping needs not to be timed out).
You can able full fill above conditions rarely.
What's the problem with other NAT types?
For example , PRC(port restricted cone) NAT won't allow you to receive a packet from a IP:Port , if you didn't send any packet to that IP:Port before. So callee will never able to send you a packet.
So if callee sends her candidates list to you . you can send some dummy data(with low TTL) to her IP:Port to fool your PRC NAT (now it allow incoming packets from callee's IP:Port as it sends a packet to that IP:Port before).
To know more about different types of NAT:
https://en.wikipedia.org/wiki/Network_address_translation
http://think-like-a-computer.com/2011/09/16/types-of-nat/

webRTC to setup signaling server

how to setup a signaling server for webRTC when the system are connected in Local Area Network? Its mandatory that we must use STUN and TURN server for signaling?
To make WebRTC run on LAN, you will require to have a signaling server in that LAN. A signaling server is any web server that will allow your web clients to exchange the SDP offer/answer and ICE candidates that are generated by the WebRTC PeerConnection. This can be done using AJAX or WebSockets.
I have listed some top sources for information about WebRTC. Please go through some of the links on that page to better understand how the WebRTC signaling works.
You will not require a STUN/TURN server as your WebRTC clients (i.e. Web Browser) will be in the LAN and accessible to each other. FYI... STUN/TURN servers are not part of the signaling but part of the media leg and usually required for NAT traversals of media.
Webrtc needs some kind of signalling system for initial negotiation.. like transferring SDP, ICE-candidates, sending and receiving offers etc... rest is done by peer-peer connection. For initial signalling you can use any technique like sending AJAX calls, using socket.io etc.
STUN and TURN servers are required for NAT traversal, NAT traversal is important because it is needed for determining the path between peers. You can use google provided STUN/TURN server address stun:stun.l.google.com:19302 etc , or you can configure your own turn server by using rfc-5766 turn server
Making signalling server for WebRTC is quite easy.
I used PHP, MYSQL and AJAX to maintain signalling data.
Suppose A wants to call B.
Then A creates offer using createOffer method. This method returns an offer object.
You have to transfer this offer object to user B, This is a part of signalling process.
Now create MYSQL database, having columns :
caller, callee, offer, answer, callerICE and calleeICE
Now offer created by A is stored in offer attribute with the help of AJAX call .
(Remember to use JSON.stringify the JS object before "POSTing" object to server.)
Now user B scans this offer attribute created by caller A , again with the help of AJAX call.
In this way , offer object created at user A can arrive at user B.
Now, user B responds to the offer by calling createAnswer method. This method returns answer object. This can again be stored in "answer" attribute of database.
Then the caller A scans this "answer" attribute created by callee B.
In this way, answer object created by B can arrive at A.
To store iceCandidate object representing caller A, use "callerIce" attribute of MYSQL table. Note that, callee B is scanning "callerIce" to know the details of caller A.
In this way we can transfer the iceCandidate objects representing future peer.
After you complete transferring of iceCandidate object, the connectionState property holds "connected" indicating two peers are connected.
If any questions, let me know!
Cheers ! You can now share local media stream to the remote peer.

How to set local endpoint when using boost asio udp socket

I have 3 network interfaces on pc and want to make sure that when I do udp socket send, it sends via a specific network interface ( I have the ip address to use when sending data).
Here is the code.
udp::socket send_socket(io_service,boost::asio::ip::udp::v6());
udp::endpoint local_end_point(boost::asio::ip::address::from_string(LocalIpAddress),1111);
// send_socket.bind(local_end_point);
send_socket.send_to(const_buffer,senderEndpoint,0,error);
The above code works but I dont have control over what network interface the data would be sent through. If I uncomment the send_socket.bind line, I stop receiving any data on the other end.
Is there any other way to bind a socket to a particular network interface?
The bind() function ties your socket to a specific network interface for sending AND receiving. If you stop receiving data on the other end it's likely because the other end is not routable via the NIC that you've specified in the bind call.