4949 , tc_conn_basic_slow_start /1
5050 , tc_conn_double_close /1
5151 , tc_conn_other_port /1
52+ , tc_conn_with_localaddr /1
5253 , tc_conn_controlling_process /1
5354
5455 , tc_stream_client_init /1
7273 , tc_getopt /1
7374 , tc_getopt_stream_active /1
7475 , tc_setopt /1
75- , tc_setopt_conn_local_addr /1
76+
77+ % % @TODO following two tcs are failing due to:
78+ % https://github.com/microsoft/msquic/issues/2033
79+ % , tc_setopt_conn_local_addr/1
80+ % , tc_setopt_conn_local_addr_in_use/1
7681 , tc_strm_opt_active_n /1
7782 , tc_strm_opt_active_once /1
7883 , tc_strm_opt_active_1 /1
@@ -369,6 +374,26 @@ tc_conn_other_port(Config)->
369374 ct :fail (" timeout" )
370375 end .
371376
377+ tc_conn_with_localaddr (Config )->
378+ Port = 5568 ,
379+ Owner = self (),
380+ {SPid , Ref } = spawn_monitor (fun () -> simple_conn_server (Owner , Config , Port ) end ),
381+
382+ {ok , CPort0 } = gen_udp :open (0 , [{ip , {127 , 0 , 0 , 1 }}]),
383+ {ok , {{127 , 0 , 0 , 1 }, PortX }} = inet :sockname (CPort0 ),
384+ ok = gen_udp :close (CPort0 ),
385+ receive
386+ listener_ready ->
387+ {ok , Conn } = quicer :connect (" 127.0.0.1" , Port , [{param_conn_local_address , " 127.0.0.1:" ++ integer_to_list (PortX )}
388+ | default_conn_opts ()], 5000 ),
389+ ? assertEqual ({ok , {{127 ,0 ,0 ,1 }, PortX }}, quicer :sockname (Conn )),
390+ ok = quicer :close_connection (Conn ),
391+ SPid ! done ,
392+ ok = ensure_server_exit_normal (Ref )
393+ after 1000 ->
394+ ct :fail (" timeout" )
395+ end .
396+
372397tc_stream_client_init (Config ) ->
373398 Port = 4568 ,
374399 Owner = self (),
@@ -862,6 +887,7 @@ tc_getstat_closed(Config) ->
862887 {ok , 4 } = quicer :send (Stm , <<" ping" >>),
863888 receive {quic , _ , _ , _ ,_ ,_ } -> ok end ,
864889 ok = quicer :close_stream (Stm ),
890+ ok = quicer :close_connection (Conn ),
865891 case quicer :getstat (Conn , [send_cnt , recv_oct , send_pend ]) of
866892 {error ,invalid_parameter } -> ok ;
867893 {error ,invalid_state } -> ok ;
@@ -1045,8 +1071,13 @@ tc_setopt_conn_local_addr(Config) ->
10451071 % % change local addr with a new port 5060
10461072 ? assertEqual (ok , quicer :setopt (Conn , param_conn_local_address , " 127.0.0.1:50600" )),
10471073 % % sleep is needed to finish migration at protocol level
1048- timer :sleep (200 ),
1049- ? assertEqual ({ok , {{127 ,0 ,0 ,1 }, 50600 }}, quicer :sockname (Stm0 )),
1074+ retry_with (fun () ->
1075+ timer :sleep (100 ),
1076+ case quicer :sockname (Stm0 ) of
1077+ {ok , {{127 ,0 ,0 ,1 }, 50600 }} -> true ;
1078+ {ok , Other } -> {false , Other }
1079+ end
1080+ end , 20 , " addr migration failed" ),
10501081 {ok , 5 } = quicer :send (Stm0 , <<" ping2" >>),
10511082 receive
10521083 {quic , <<" ping2" >>, Stm0 , _ , _ , _ } ->
@@ -1061,6 +1092,52 @@ tc_setopt_conn_local_addr(Config) ->
10611092 SPid ! done ,
10621093 ensure_server_exit_normal (Ref ).
10631094
1095+ tc_setopt_conn_local_addr_in_use (Config ) ->
1096+ Port = 4578 ,
1097+ Owner = self (),
1098+ {SPid , Ref } = spawn_monitor (fun () -> echo_server (Owner , Config , Port ) end ),
1099+ {ok , Conn } = quicer :connect (" 127.0.0.1" , Port , default_conn_opts (), 5000 ),
1100+ {ok , Stm0 } = quicer :start_stream (Conn , [{active , true }]),
1101+ {ok , 5 } = quicer :send (Stm0 , <<" ping1" >>),
1102+ receive
1103+ {quic , <<" ping1" >>, Stm0 , _ , _ , _ } ->
1104+ ok
1105+ after 1000 ->
1106+ ct :fail (" recv ping1 timeout" )
1107+ end ,
1108+ {ok , OldAddr } = quicer :sockname (Stm0 ),
1109+ % % change local addr with a new random port (0)
1110+ ? assertEqual (ok , quicer :setopt (Conn , param_conn_local_address , " 127.0.0.1:0" )),
1111+ % % sleep is needed to finish migration at protocol level
1112+ timer :sleep (50 ),
1113+ {ok , NewAddr } = quicer :sockname (Stm0 ),
1114+ ? assertNotEqual (OldAddr , NewAddr ),
1115+ ? assertNotEqual ({ok , {{127 ,0 ,0 ,1 }, 50600 }}, NewAddr ),
1116+ ? assertNotEqual ({ok , {{127 ,0 ,0 ,1 }, 50600 }}, OldAddr ),
1117+
1118+ % % Occupy 50600
1119+ {ok , ESocket } = gen_udp :open (50600 , [{ip , element (1 , NewAddr )}]),
1120+ % % change local addr with a new port 5060
1121+ ? assertEqual ({error ,address_in_use }, quicer :setopt (Conn , param_conn_local_address , " 127.0.0.1:50600" )),
1122+
1123+ % gen_udp:close(ESocket),
1124+
1125+ % % sleep is needed to finish migration at protocol level
1126+ ct :pal (" send after migration failed" ),
1127+ {ok , 5 } = quicer :send (Stm0 , <<" ping2" >>),
1128+ receive
1129+ {quic , <<" ping2" >>, Stm0 , _ , _ , _ } ->
1130+ ok
1131+ after 1000 ->
1132+ ct :fail (" recv ping2 timeout" )
1133+ end ,
1134+ % % check with server if peer addr is correct.
1135+ SPid ! {peer_addr , self ()},
1136+ receive {peer_addr , Peer } -> ok end ,
1137+ ? assertEqual ({ok , NewAddr }, Peer ),
1138+ SPid ! done ,
1139+ ensure_server_exit_normal (Ref ).
1140+
10641141tc_app_echo_server (Config ) ->
10651142 Port = 8888 ,
10661143 application :ensure_all_started (quicer ),
@@ -1451,6 +1528,17 @@ active_recv(Stream, Len, BinList) ->
14511528 end
14521529end .
14531530
1531+ retry_with (_Fun , 0 , ErrorInfo ) ->
1532+ ct :fail (ErrorInfo );
1533+ retry_with (Fun , Retry , ErrorInfo ) ->
1534+ case Fun () of
1535+ true ->
1536+ ok ;
1537+ false ->
1538+ retry_with (Fun , Retry - 1 , ErrorInfo );
1539+ {false , NewErrorInfo } ->
1540+ retry_with (Fun , Retry - 1 , NewErrorInfo )
1541+ end .
14541542% %%_* Emacs ====================================================================
14551543% %% Local Variables:
14561544% %% allout-layout: t
0 commit comments