简体   繁体   English

我可以通过 socket_sendmsg (sendmsg) 将 TCP 套接字资源传递给 AF_UNIX 本地套接字吗?如果可以,如何传递

[英]Can I pass a TCP socket resource via socket_sendmsg (sendmsg) to a AF_UNIX local socket and if so how

My goal is to pass along a socket connection (once 'handshaken' (http upgraded) and 'authenticated' (my own function that does a challenge using the provided details against my db))to another php script process (not forked) so that it can add it to its own array of socket resource "authenticated clients" and take over the connection.我的目标是将套接字连接(一旦“握手”(http 升级)和“经过身份验证”(我自己的函数使用针对我的数据库提供的详细信息进行挑战))传递给另一个 php 脚本进程(未分叉),以便它可以将其添加到自己的套接字资源“经过身份验证的客户端”数组中并接管连接。 Once it's sent via the php wrapper of sendmsg (socket_sendmsg - who's PHP documentation is inaccurate and so I've mostly been looking at people trying to do the same in c)一旦它通过 sendmsg 的 php 包装器发送(socket_sendmsg - 谁的 PHP 文档不准确,所以我主要是在看人们试图在 c 中做同样的事情)

If I send:如果我发送:

socket_sendmsg($hsSocket, ["iov" => [json_encode(array('action'=>'add','uID'=>$messageObj->uID,'uDatID'=>$messageObj->uDatID,'sessID'=>$messageObj->sessID))], "control" => [["level" => SOL_SOCKET, "type" => SCM_RIGHTS, "data" => [$authlogfd]]]], 0);

which is sending the File Descriptor of an open log file, if I then do (after socket_select on that resourceArray):这是发送打开的日志文件的文件描述符,如果我然后这样做(在该资源阵列上的 socket_select 之后):

    if(socket_recvmsg($arrayOfSocketResources, $hsSocketData,MSG_DONTWAIT)){
                printf("SS:HS: got recvmsg control data\n");
                print_r($hsSocketData);
                if(isset($hsSocketData['control'][0]['data'][0])){
                $newlogfd=$hsSocketData['control'][0]['data'][0];   
                $msg=json_decode($hsSocketData['iov'][0],true);
                if(isset($msg['action'])&&$msg['action']=='add'){
                $sendmsg=PHP_EOL."from second script".PHP_EOL;
                fwrite($newlogfd,$sendmsg,strlen($sendmsg));
                printf("SS:HS: got descriptor %s action:%s uID:%s uDatID:%s sessID:%s\n",$newlogfd,$msg['action'],$msg['uID'],$msg['uDatID'],$msg['sessID']);
                }

Then I see the message "from second script" in the log (so I'm able to write to the file descriptor passed - even after the passer is closed (there's a count for every process attached to the File Description or something that gets incremented)).然后我在日志中看到“来自第二个脚本”的消息(所以我能够写入传递的文件描述符 - 即使在传递器关闭之后(每个进程附加到文件描述或增加的东西都有一个计数) ))。 This also works to STDOUT if I send that from the passer instead of the log File Descriptor.如果我从传递者而不是日志文件描述符发送它,这也适用于 STDOUT。

When I change to sending one of the authenticated tcp socket client resources, it shows a resource id if I dump:当我更改为发送经过身份验证的 tcp 套接字客户端资源之一时,如果我转储,它会显示一个资源 ID:

          Array(
[name] => 
[control] => Array
    ([0] => Array
            (
                [level] => 1
                [type] => 1
                [data] => Array
                    (
                        [0] => Resource id #12
                    )

            )

    )

[iov] => Array
    (
        [0] => {"action":"add","uID":"816-2554846393-11","uDatID":"fe1eba892f2144b3c9ce49f79c7a8386","sessID":"9mpr38o5nrmqke0mfejvn3801l"}
    )

[flags] => 0

) )

The problem is when I try to use the passed socket resource "Resource id #12" I get问题是当我尝试使用传递的套接字资源“Resource id #12”时,我得到

socket_send(): supplied resource is not a valid Socket

A socket_select with "Resource id #12" added to its read resource array also borks complaining that it's invalid.将“Resource id #12”添加到其读取资源数组中的 socket_select 也会抱怨它无效。

Is what I'm trying to do with passing the socket in some way different here?我在这里尝试以某种方式传递套接字是否有所不同? What am I missing (besides the obvious things).我错过了什么(除了显而易见的事情)。

$r = socket_sendmsg($authSocket, ["iov" => [json_encode(array('uID'=>$socketMYSQL->unboxID($messageObj->uID),'uDatID'=>$messageObj->uDatID,'sessID'=>$messageObj->sessID))], "control" => [["level" => SOL_SOCKET, "type" => SCM_RIGHTS, "data" => [socket_export_stream($newSocketArrayResource),STDOUT]]]], 0);

socket_export_stream() is the magic I was missing (I think it encapsulates the socket in the stream object) now when I var_dump on the received fd I get socket_export_stream() 是我缺少的魔法(我认为它将套接字封装在流对象中)现在当我在收到的 fd 上进行 var_dump 时我得到

resource(13) of type (Socket)

instead of代替

resource(13) of type (stream)

and socket_getpeername() works和 socket_getpeername() 工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM