PHP SSL“旧”流套接字意外关闭

iovurdzv  于 5个月前  发布在  PHP
关注(0)|答案(1)|浏览(66)

我正在开发一个SSL WebSocket服务器,PHP 8.2.
我可以接受SSL连接没有问题。
问题是:
连接A,然后是B,然后是C,最后是D被接受。
当连接C关闭时(客户端断开连接,而不是服务器),连接A和B意外关闭(但不是D)。
流套接字A或B上的“fread”将引发此警告:fread():SSL操作失败,代码为1. OpenSSL错误消息:错误:140943 FC:SSL例程:ssl3_read_bytes:sslv 3 alert bad record mac in.
插座D上的阅读仍正常。
这只会发生在SSL连接中,而不会发生在未加密连接中。
事实上,所有在关闭套接字之前打开的套接字也都是关闭的。
我的代码示例:

$transport = 'tlsv1.3';
$ssl = ['ssl' => [
'local_cert'  => $sslCert,       
'local_pk'    => $sslKey,    
'disable_compression' => true,
'verify_peer'         => false,
'allow_self_signed'         => true,            
'ssltransport' => $transport,
] ];
    
$context = stream_context_create($ssl);
        
$socketS = stream_socket_server(
'ssl://0.0.0.0:'.$wssPort,
$errno,
$errstr,
STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
$context
);


....

do {
$tCpy = array($socketS);
$retSocket=stream_select($tCpy, $null, $null, 20, 0);
if ($retSocket>0 ) {
    // New conection
    stream_set_blocking($socketS, true);
    $cliSocket = stream_socket_accept($socketS,5,$ip);

        ...

        $pid = pcntl_fork();
        
        if ($pid>0) {
         //  OK
           echo("Fork ok");
           continue;
       } else if ($pid < 0) {
          echo("Error fork");
          continue;
       } else break;
}
} while(true);

// Do something with newly connected client...

字符串
有主意吗?谢谢!

mum43rcc

mum43rcc1#

好吧,看来我发现了这个问题,所以我张贴的答复,如果它可以帮助别人:
关键是加密必须在fork语句之后开始。
代码如下:

$transport = 'tlsv1.3';
$ssl = ['ssl' => [
  'local_cert'  => $sslCert,       
  'local_pk'    => $sslKey,    
  'disable_compression' => true,
  'verify_peer'         => false,
  'allow_self_signed'         => true,            
  'ssltransport' => $transport,
]];
        
$context = stream_context_create($ssl);
     
// Change from ssl:// to tcp://    
    
$socketS = stream_socket_server(
  'tcp://0.0.0.0:'.$wssPort,
  $errno,
  $errstr,
  STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
  $context
);

....
    
do {
  $tCpy = array($socketS);
  $retSocket=stream_select($tCpy, $null, $null, 20, 0);
  if ($retSocket>0 ) {
    // New conection
    stream_set_blocking($socketS, true);
    $cliSocket = stream_socket_accept($socketS,5,$ip);
    
    ...
    
    $pid = pcntl_fork();
            
    if ($pid>0) {
      //  OK
      echo("Fork ok");
      continue;
    } else if ($pid < 0) {
      echo("Error fork");
      continue;
    } else break;
  }
} while(true);
    
// Do something with newly connected client...
// Here we start the crypto using the context 
    
stream_socket_enable_crypto($cliSocket, true, STREAM_CRYPTO_METHOD_TLS_SERVER);

字符串

相关问题