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

问题描述 投票:0回答:1

我正在开发一个 SSL websocket 服务器,PHP 8.2。

我可以毫无问题地接受 SSL 连接。

问题是:

连接 A、B、C、D 均被接受。

当连接 C 关闭时(是客户端而不是服务器断开连接),连接 A 和 B 会意外关闭(但 D 不会)。

流套接字 A 或 B 上的“fread”将引发此警告: fread(): SSL 操作失败,代码为 1。OpenSSL 错误消息: 错误:140943FC:SSL 例程:ssl3_read_bytes:sslv3 警报坏记录 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...

有什么想法吗?谢谢!

php sockets ssl stream
1个回答
0
投票

嗯,看来我发现了这个问题,所以我发布回复,如果它可以帮助其他人:

关键是加密必须在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);

© www.soinside.com 2019 - 2024. All rights reserved.