178 lines
8.2 KiB
Plaintext
178 lines
8.2 KiB
Plaintext
NORM SOCKET BINDING NOTES
|
|
=========================
|
|
|
|
NORM supports a number of socket binding options to allow for multiple paradigms of use. The default operation of NORM involves two separate sockets:
|
|
|
|
1) a "tx_socket" used for sender transmission and reception of unicast feedback, and
|
|
2) a "rx_socket" used for reception of packets sent to the "session" address/port
|
|
|
|
By default both sockets are bound to INADDR_ANY with the rx_socket using the "session port" number and the
|
|
tx_socket using a port freely assigned by the operating system unless the NormSetTxPort() API is invoked. The INADDR_ANY binding allows the sockets to receive packets from any remote address/port thus support NORM's typical multicast operation compatible with both unicast and multicast feedback and even "many-to-one" unicast reception (if unicast feedback is set via NormSetDefaultUnicastNack()).
|
|
|
|
Some optional binding behaviors are invoked depending upon some additional NORM API calls. For example, the "rx_socket" can be optionally bound to the session address. This restricts the rx_socket to receive only packets specifically directed to the configured session address. The session address must be a multicast address or valid local IP address for this to work. And in the latter case, the NormSession MUST be operated
|
|
only as a NORM receiver (i.e., NormStartSender() will result in transmissions to self only!)
|
|
|
|
The rationale for the separate tx_socket and rx_socket usage was to enable NORM senders to detect when unicast feedback is used so that proper protocol behaviors are invoked (e.g. NORM_CMD(REPAIR_ADV)). Note that the code base _may_ be eventually updated so this is no longer necessary (e.g. through use of the "recvmsg()" system call
|
|
with proper socket configuration to receive UDP packet destination address header information). It may still be the case that a use case for separate send/recv sockets may persist and the code will continue to support that although it is possible that it may become the optional behavior rather than the default.
|
|
|
|
bind semantics: localAddr / localPort
|
|
|
|
connect semantics: remoteAddr / remotePort
|
|
|
|
+-------------------------------+-------------------------------+---------------------------------------+
|
|
| bind() state | connect() state | |
|
|
+---------------+---------------+---------------+---------------+ Behaviors |
|
|
| localAddr | localPort | remoteAddr | remotePort | |
|
|
+---------------+---------------+---------------+---------------+---------------------------------------+
|
|
| INADDR_ANY | 0 | NONE | OS-assigned port, sendto() any |
|
|
+---------------+---------------+---------------+---------------+---------------------------------------+
|
|
| INADDR_ANY | <port> | NONE | from any to <*/port>, sendto() any |
|
|
+---------------+---------------+---------------+---------------+---------------------------------------+
|
|
| <addr> | <port> | NONE | from any to <addr/port>. sendto() any |
|
|
+---------------+---------------+---------------+---------------+---------------------------------------+
|
|
| INADDR_ANY | <port> | remoteAddr | remotePort | from remote to <*/port> |
|
|
+---------------+---------------+---------------+---------------+---------------------------------------+
|
|
| <addr> | <port> | remoteAddr | remotePort | from remote to <addr/port> only |
|
|
+---------------+---------------+---------------+---------------+---------------------------------------+
|
|
|
|
The Rules:
|
|
|
|
If you don't bind(), you don't receive anything.
|
|
|
|
If you connect() you can only send to the specified connected addr / port.
|
|
|
|
Cannot connect to multicast addr.
|
|
|
|
Can only bind to multicast or valid local IP addr
|
|
|
|
With port reuse, each multicast socket will get a copy of matching inbound multicast packets. In fact, with an INADDR_ANY bind, the socket will get packets for _any_ group joined if the port number matches. But with an inbound unicast packet, only one socket with closest matching binding will get the packet. This includes
|
|
the bind() (i.e. local addr/port) _and_ connect() (i.e. remote addr/port) state with regard to the incoming packet where the most specific match is considered the best match.
|
|
|
|
Thus these bind/connect combinations are important in order to achieve some desired set of behaviors.
|
|
|
|
|
|
|
|
DESIRED BEHAVIORS:
|
|
|
|
1) NORM sender / receiver operation with feedback to the session port and/or unicast feedback.
|
|
|
|
|
|
2) Binding packet reception for socket(s) to specific address(es) with or without port reuse
|
|
|
|
NormSetTxPort() currently has option to bind the tx_socket to a specific local address (txAddress)
|
|
NormSetRxPortReuse() currently has option to bind rx_socket to multicast session address.
|
|
|
|
TBD - Need to add "NormSetRxAddress()" to bind rx_socket to non-session local address
|
|
|
|
|
|
3) Connecting socket(s) to remote unicast addr/port so that reused port demuxing works properly
|
|
(This is probably applicable only to unicast sessions)
|
|
|
|
So, the following conditions should be true to "connect" the socket:
|
|
|
|
1) Session address is unicast
|
|
2) Port reuse is true.
|
|
|
|
XXX - finish these thoughts and revise the implementation!!!!!
|
|
|
|
REQUIREMENTS
|
|
|
|
|
|
Enumerate some use cases and the corresponding socket behavior requirements
|
|
|
|
1) Default: sender/receiver multicast operation w/ mcast and ucast feedback
|
|
|
|
tx_socket : sendto() session addr/port,sender(s) addr/port
|
|
recvfrom() receiver src addr/port to local ucast addr
|
|
rx_socket : recvfrom() sender addr/port to session addr/port
|
|
|
|
If rxAddr is unspecified, can also receive to unicast
|
|
|
|
2) Sender-only one-to-many
|
|
|
|
tx_socket : sendto() session addr/port,sender(s) addr/port
|
|
recvfrom() receiver src addr/port to local ucast addr
|
|
|
|
rx_socket : recvfrom() sender addr/port to session addr/port (mcast feedback)
|
|
|
|
|
|
3) Receive-only many-to-one unicasts
|
|
|
|
tx_socket : sendto() senders addr/port
|
|
rx_socket : recvfrom() senders addr/port to session port
|
|
|
|
4) Bi-directional unicast
|
|
|
|
tx_socket : sendto() session addr/port
|
|
rx_socket : recvfrom() session addr/* to session port
|
|
|
|
|
|
|
|
|
|
IMPLEMENTATION NOTES:
|
|
|
|
1) Default binding
|
|
|
|
rx_socket : INADDR_ANY / <sessionPort>
|
|
|
|
tx_socket : INADDR_ANY / 0 (any port)
|
|
|
|
Implementation Details:
|
|
|
|
This is the default behavior if none of the additional API calls described below are made.
|
|
|
|
---------------------------------------------------------------------------
|
|
2) The NormSetTxPort(txPort, enableReuse, txAddr) lets this be modified by:
|
|
|
|
a) if (txPort != sessionPort) tx_socket is bound to <txPort>
|
|
b) if (txPort == sessionPort) rx_socket is used for transmission, too
|
|
|
|
c) if "enableReuse" is true, PORT/ADDR REUSE is set for tx_socket
|
|
|
|
d) if txAddr is valid, the tx_socket (or (TBD) rx_socket if txPort == sessionPort) is bound
|
|
to the given <txAddr> which must be a valid IP addr for the host (This means only
|
|
unicast packets for that address are received on that socket. Thus the binding is _not_
|
|
made for the rx_socket case if the session address is a multicast address!
|
|
|
|
|
|
Implementation Details:
|
|
|
|
TBD
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
3) The NormSetRxPortReuse(enable, bindToSessionAddr) modifies the default binding as follows:
|
|
|
|
a) If <enable> is "true", PORT/ADDR REUSE is set for the rx_socket
|
|
|
|
b) if <bindToSessionAddr> is "true" _and_ the session address is multicast, the rx_socket
|
|
binding is <sessionAddr> / <sessionPort>. This enables the same port number to be
|
|
reused for different multicast session addresses _and_ restricts the rx_socket to receive
|
|
only packets destined for the sessionAddr. In this case, unicast feedback to the rx_socket
|
|
(i.e. in the case of above where txPort == sessionPort) will NOT work!
|
|
TBD - The code resolves this conflict by ...
|
|
|
|
|
|
Implementation Details:
|
|
|
|
TBD
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
4) The NormSetTxOnly() causes only the tx_socket to be opened and no rx_socket is opened. In fact,
|
|
the rx_socket is closed if it is already open (unless txPort == sessionPort ala above)
|
|
|
|
|
|
Implementation Details:
|
|
|
|
TBD
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|