@@ -29,10 +29,30 @@ $ethertype = pack("n", 0x9000);
2929$ payload = "no port test " ;
3030$ frame = str_pad ($ dst_mac . $ src_mac . $ ethertype . $ payload , 60 , "\x00" );
3131
32+ // ETH_P_ALL sockets on loopback can observe unrelated localhost traffic from
33+ // the parallel test runner. Read until we see our own frame, then validate the
34+ // address returned by recvfrom() without the optional port argument.
35+ function recv_matching (Socket $ s , string $ header , int $ maxlen = 65536 , ?string &$ addr = null , &$ bytes = null ): string |false {
36+ socket_set_nonblock ($ s );
37+ $ deadline = microtime (true ) + 5.0 ;
38+ while (microtime (true ) < $ deadline ) {
39+ $ recvBytes = @socket_recvfrom ($ s , $ buf , $ maxlen , 0 , $ addr );
40+ if ($ recvBytes !== false && is_string ($ buf ) && str_starts_with ($ buf , $ header )) {
41+ $ bytes = $ recvBytes ;
42+ return $ buf ;
43+ }
44+ if ($ recvBytes === false ) {
45+ usleep (1000 );
46+ }
47+ }
48+ return false ;
49+ }
50+
3251socket_sendto ($ s_send , $ frame , strlen ($ frame ), 0 , "lo " , 1 );
3352
3453// recvfrom without the optional 6th argument (port/ifindex).
35- $ bytes = socket_recvfrom ($ s_recv , $ buf , 65536 , 0 , $ addr );
54+ $ bytes = 0 ;
55+ $ buf = recv_matching ($ s_recv , $ dst_mac . $ src_mac . $ ethertype , 65536 , $ addr , $ bytes );
3656var_dump ($ bytes >= 60 );
3757var_dump ($ addr === 'lo ' );
3858
0 commit comments