-
Notifications
You must be signed in to change notification settings - Fork 35
/
NormSocketBindingNotes.txt
executable file
·177 lines (98 loc) · 8.21 KB
/
NormSocketBindingNotes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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