@@ -101,63 +101,182 @@ describe("UDP6 transport", () => {
101101} ) ;
102102
103103describe ( "UDP4+6 transport" , ( ) => {
104- const address4 = "127.0.0.1" ;
105- const address6 = "::1" ;
106- const nodeIdA = bytesToHex ( new Uint8Array ( 32 ) . fill ( 1 ) ) ;
107- const portA = 49523 ;
108- const multiaddr4A = multiaddr ( `/ip4/${ address4 } /udp/${ portA } ` ) ;
109- const multiaddr6A = multiaddr ( `/ip6/${ address6 } /udp/${ portA } ` ) ;
110- const a = new UDPTransportService ( { bindAddrs : { ip4 : multiaddr4A , ip6 : multiaddr6A } , nodeId : nodeIdA } ) ;
104+ context ( "with loopback addresses" , ( ) => {
105+ const address4 = "127.0.0.1" ;
106+ const address6 = "::1" ;
107+ const nodeIdA = bytesToHex ( new Uint8Array ( 32 ) . fill ( 1 ) ) ;
108+ const portA = 49523 ;
109+ const multiaddr4A = multiaddr ( `/ip4/${ address4 } /udp/${ portA } ` ) ;
110+ const multiaddr6A = multiaddr ( `/ip6/${ address6 } /udp/${ portA } ` ) ;
111+ const a = new UDPTransportService ( { bindAddrs : { ip4 : multiaddr4A , ip6 : multiaddr6A } , nodeId : nodeIdA } ) ;
111112
112- const nodeIdB = bytesToHex ( new Uint8Array ( 32 ) . fill ( 2 ) ) ;
113- const portB = portA + 1 ;
114- const multiaddr4B = multiaddr ( `/ip4/${ address4 } /udp/${ portB } ` ) ;
115- const multiaddr6B = multiaddr ( `/ip6/${ address6 } /udp/${ portB } ` ) ;
116- const b = new UDPTransportService ( { bindAddrs : { ip4 : multiaddr4B , ip6 : multiaddr6B } , nodeId : nodeIdB } ) ;
113+ const nodeIdB = bytesToHex ( new Uint8Array ( 32 ) . fill ( 2 ) ) ;
114+ const portB = portA + 1 ;
115+ const multiaddr4B = multiaddr ( `/ip4/${ address4 } /udp/${ portB } ` ) ;
116+ const multiaddr6B = multiaddr ( `/ip6/${ address6 } /udp/${ portB } ` ) ;
117+ const b = new UDPTransportService ( { bindAddrs : { ip4 : multiaddr4B , ip6 : multiaddr6B } , nodeId : nodeIdB } ) ;
117118
118- before ( async ( ) => {
119- await a . start ( ) ;
120- await b . start ( ) ;
121- } ) ;
119+ before ( async ( ) => {
120+ await a . start ( ) ;
121+ await b . start ( ) ;
122+ } ) ;
122123
123- after ( async ( ) => {
124- await a . stop ( ) ;
125- await b . stop ( ) ;
124+ after ( async ( ) => {
125+ await a . stop ( ) ;
126+ await b . stop ( ) ;
127+ } ) ;
128+
129+ it ( "should send and receive messages" , async ( ) => {
130+ const messagePacket : IPacket = {
131+ maskingIv : new Uint8Array ( MASKING_IV_SIZE ) ,
132+ header : {
133+ protocolId : "discv5" ,
134+ version : 1 ,
135+ flag : PacketType . Message ,
136+ nonce : new Uint8Array ( NONCE_SIZE ) ,
137+ authdataSize : 32 ,
138+ authdata : new Uint8Array ( 32 ) . fill ( 2 ) ,
139+ } ,
140+ message : new Uint8Array ( 44 ) . fill ( 1 ) ,
141+ } ;
142+ async function send ( multiaddr : Multiaddr , nodeId : string , packet : IPacket ) : Promise < [ Multiaddr , IPacket ] > {
143+ const received = new Promise < [ Multiaddr , IPacket ] > ( ( resolve ) =>
144+ a . once ( "packet" , ( sender , packet ) => resolve ( [ sender , packet ] ) )
145+ ) ;
146+ await b . send ( multiaddr , nodeId , packet ) ;
147+ return await received ;
148+ }
149+ {
150+ const [ rSender , rPacket ] = await send ( multiaddr6A , nodeIdA , messagePacket ) ;
151+ expect ( rSender . toString ( ) ) . to . deep . equal ( multiaddr6B . toString ( ) ) ;
152+ expect ( rPacket . maskingIv ) . to . deep . equal ( messagePacket . maskingIv ) ;
153+ expect ( rPacket . header ) . to . deep . equal ( messagePacket . header ) ;
154+ expect ( rPacket . message ) . to . deep . equal ( messagePacket . message ) ;
155+ }
156+ {
157+ const [ rSender , rPacket ] = await send ( multiaddr4A , nodeIdA , messagePacket ) ;
158+ expect ( rSender . toString ( ) ) . to . deep . equal ( multiaddr4B . toString ( ) ) ;
159+ expect ( rPacket . maskingIv ) . to . deep . equal ( messagePacket . maskingIv ) ;
160+ expect ( rPacket . header ) . to . deep . equal ( messagePacket . header ) ;
161+ expect ( rPacket . message ) . to . deep . equal ( messagePacket . message ) ;
162+ }
163+ } ) ;
126164 } ) ;
127165
128- it ( "should send and receive messages" , async ( ) => {
129- const messagePacket : IPacket = {
130- maskingIv : new Uint8Array ( MASKING_IV_SIZE ) ,
131- header : {
132- protocolId : "discv5" ,
133- version : 1 ,
134- flag : PacketType . Message ,
135- nonce : new Uint8Array ( NONCE_SIZE ) ,
136- authdataSize : 32 ,
137- authdata : new Uint8Array ( 32 ) . fill ( 2 ) ,
138- } ,
139- message : new Uint8Array ( 44 ) . fill ( 1 ) ,
140- } ;
141- async function send ( multiaddr : Multiaddr , nodeId : string , packet : IPacket ) : Promise < [ Multiaddr , IPacket ] > {
142- const received = new Promise < [ Multiaddr , IPacket ] > ( ( resolve ) =>
166+ context ( "with wildcard addresses" , ( ) => {
167+ it ( "should bind to the same port on both IPv4 and IPv6" , async ( ) => {
168+ const nodeId = bytesToHex ( new Uint8Array ( 32 ) . fill ( 3 ) ) ;
169+ const port = 49525 ;
170+ const multiaddr4 = multiaddr ( `/ip4/0.0.0.0/udp/${ port } ` ) ;
171+ const multiaddr6 = multiaddr ( `/ip6/::/udp/${ port } ` ) ;
172+
173+ const transport = new UDPTransportService ( {
174+ bindAddrs : { ip4 : multiaddr4 , ip6 : multiaddr6 } ,
175+ nodeId,
176+ } ) ;
177+
178+ await transport . start ( ) ;
179+ expect ( transport . bindAddrs ) . to . have . lengthOf ( 2 ) ;
180+ expect ( transport . bindAddrs [ 0 ] . toString ( ) ) . to . equal ( multiaddr4 . toString ( ) ) ;
181+ expect ( transport . bindAddrs [ 1 ] . toString ( ) ) . to . equal ( multiaddr6 . toString ( ) ) ;
182+ await transport . stop ( ) ;
183+ } ) ;
184+
185+ it ( "should successfully communicate between dual-stack nodes on same port" , async ( ) => {
186+ const nodeIdA = bytesToHex ( new Uint8Array ( 32 ) . fill ( 4 ) ) ;
187+ const nodeIdB = bytesToHex ( new Uint8Array ( 32 ) . fill ( 5 ) ) ;
188+ const portA = 49526 ;
189+ const portB = 49527 ;
190+
191+ const multiaddr4A = multiaddr ( `/ip4/127.0.0.1/udp/${ portA } ` ) ;
192+ const multiaddr6A = multiaddr ( `/ip6/::1/udp/${ portA } ` ) ;
193+ const a = new UDPTransportService ( {
194+ bindAddrs : { ip4 : multiaddr4A , ip6 : multiaddr6A } ,
195+ nodeId : nodeIdA ,
196+ } ) ;
197+
198+ const multiaddr4B = multiaddr ( `/ip4/127.0.0.1/udp/${ portB } ` ) ;
199+ const multiaddr6B = multiaddr ( `/ip6/::1/udp/${ portB } ` ) ;
200+ const b = new UDPTransportService ( {
201+ bindAddrs : { ip4 : multiaddr4B , ip6 : multiaddr6B } ,
202+ nodeId : nodeIdB ,
203+ } ) ;
204+
205+ await a . start ( ) ;
206+ await b . start ( ) ;
207+
208+ const messagePacket : IPacket = {
209+ maskingIv : new Uint8Array ( MASKING_IV_SIZE ) ,
210+ header : {
211+ protocolId : "discv5" ,
212+ version : 1 ,
213+ flag : PacketType . Message ,
214+ nonce : new Uint8Array ( NONCE_SIZE ) ,
215+ authdataSize : 32 ,
216+ authdata : new Uint8Array ( 32 ) . fill ( 2 ) ,
217+ } ,
218+ message : new Uint8Array ( 44 ) . fill ( 1 ) ,
219+ } ;
220+
221+ const receivedIPv4 = new Promise < [ Multiaddr , IPacket ] > ( ( resolve ) =>
222+ a . once ( "packet" , ( sender , packet ) => resolve ( [ sender , packet ] ) )
223+ ) ;
224+ await b . send ( multiaddr4A , nodeIdA , messagePacket ) ;
225+ const [ senderIPv4 ] = await receivedIPv4 ;
226+ expect ( senderIPv4 . toString ( ) ) . to . equal ( multiaddr4B . toString ( ) ) ;
227+
228+ const receivedIPv6 = new Promise < [ Multiaddr , IPacket ] > ( ( resolve ) =>
143229 a . once ( "packet" , ( sender , packet ) => resolve ( [ sender , packet ] ) )
144230 ) ;
145- await b . send ( multiaddr , nodeId , packet ) ;
146- return await received ;
147- }
148- {
149- const [ rSender , rPacket ] = await send ( multiaddr6A , nodeIdA , messagePacket ) ;
150- expect ( rSender . toString ( ) ) . to . deep . equal ( multiaddr6B . toString ( ) ) ;
151- expect ( rPacket . maskingIv ) . to . deep . equal ( messagePacket . maskingIv ) ;
152- expect ( rPacket . header ) . to . deep . equal ( messagePacket . header ) ;
153- expect ( rPacket . message ) . to . deep . equal ( messagePacket . message ) ;
154- }
155- {
156- const [ rSender , rPacket ] = await send ( multiaddr4A , nodeIdA , messagePacket ) ;
157- expect ( rSender . toString ( ) ) . to . deep . equal ( multiaddr4B . toString ( ) ) ;
158- expect ( rPacket . maskingIv ) . to . deep . equal ( messagePacket . maskingIv ) ;
159- expect ( rPacket . header ) . to . deep . equal ( messagePacket . header ) ;
160- expect ( rPacket . message ) . to . deep . equal ( messagePacket . message ) ;
161- }
231+ await b . send ( multiaddr6A , nodeIdA , messagePacket ) ;
232+ const [ senderIPv6 ] = await receivedIPv6 ;
233+ expect ( senderIPv6 . toString ( ) ) . to . equal ( multiaddr6B . toString ( ) ) ;
234+
235+ await a . stop ( ) ;
236+ await b . stop ( ) ;
237+ } ) ;
238+
239+ it ( "should handle multiple dual-stack nodes on different ports" , async ( ) => {
240+ const ports = [ 49528 , 49529 , 49530 ] ;
241+ const transports : UDPTransportService [ ] = [ ] ;
242+
243+ for ( let i = 0 ; i < ports . length ; i ++ ) {
244+ const nodeId = bytesToHex ( new Uint8Array ( 32 ) . fill ( 10 + i ) ) ;
245+ const multiaddr4 = multiaddr ( `/ip4/127.0.0.1/udp/${ ports [ i ] } ` ) ;
246+ const multiaddr6 = multiaddr ( `/ip6/::1/udp/${ ports [ i ] } ` ) ;
247+ const transport = new UDPTransportService ( {
248+ bindAddrs : { ip4 : multiaddr4 , ip6 : multiaddr6 } ,
249+ nodeId,
250+ } ) ;
251+ transports . push ( transport ) ;
252+ }
253+
254+ await Promise . all ( transports . map ( ( t ) => t . start ( ) ) ) ;
255+
256+ const messagePacket : IPacket = {
257+ maskingIv : new Uint8Array ( MASKING_IV_SIZE ) ,
258+ header : {
259+ protocolId : "discv5" ,
260+ version : 1 ,
261+ flag : PacketType . Message ,
262+ nonce : new Uint8Array ( NONCE_SIZE ) ,
263+ authdataSize : 32 ,
264+ authdata : new Uint8Array ( 32 ) . fill ( 2 ) ,
265+ } ,
266+ message : new Uint8Array ( 44 ) . fill ( 1 ) ,
267+ } ;
268+
269+ const received = new Promise < boolean > ( ( resolve ) => {
270+ transports [ 1 ] . once ( "packet" , ( ) => resolve ( true ) ) ;
271+ } ) ;
272+
273+ const targetMultiaddr = multiaddr ( `/ip4/127.0.0.1/udp/${ ports [ 1 ] } ` ) ;
274+ const targetNodeId = bytesToHex ( new Uint8Array ( 32 ) . fill ( 11 ) ) ;
275+ await transports [ 0 ] . send ( targetMultiaddr , targetNodeId , messagePacket ) ;
276+
277+ expect ( await received ) . to . be . true ;
278+
279+ await Promise . all ( transports . map ( ( t ) => t . stop ( ) ) ) ;
280+ } ) ;
162281 } ) ;
163282} ) ;
0 commit comments