Created
August 16, 2020 09:25
-
-
Save devilholk/8b1474dcf832f678222ec370478b5029 to your computer and use it in GitHub Desktop.
Test of receiving file descriptors from another process using AF_UNIX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AUTO_DELETE = False #Change this to True to delete the socket before usage in case it was never cleaned up for some reason | |
import socketserver, os, struct | |
from socket import * | |
class my_handler(socketserver.StreamRequestHandler): | |
def handle(self): | |
print('New request!', self.request) | |
while True: | |
msg, ancdata, flags, addr = self.request.recvmsg(1024, 1024) | |
#Print out message | |
print(msg, ancdata, flags, addr) | |
#Check if it was fit | |
if flags & MSG_TRUNC: | |
print('Oh noes! Message was truncated!') | |
if flags & MSG_CTRUNC: | |
print('Oh noes! Ancillary data was truncated!') | |
elif ancdata: | |
#Go throuhg ancillary data | |
for cmsg_level, cmsg_type, cmsg_data in ancdata: | |
#Make sure we understand it | |
assert (cmsg_level, cmsg_type) == (SOL_SOCKET, SCM_RIGHTS) | |
#Go through the file descriptors and check them out | |
for (fd,) in struct.iter_unpack('I', cmsg_data): | |
f = os.fdopen(fd) | |
print(f'File descriptor: {fd} File handle: {f} Pos: {f.tell()}') | |
f.close() | |
#If we get an empty message we will close | |
if not msg: | |
self.request.close() | |
print('Closing', self.request) | |
return | |
#socketserver.UnixStreamServer is actually SOCK_STREAM and even though SOCK_DGRAM will not be out of order on most systems it does not guarantee it per definition | |
#Therefore we will use SOCK_SEQPACKET which is a stream of messages that arrives in order | |
class my_server(socketserver.ThreadingMixIn, socketserver.UnixStreamServer): | |
socket_type = SOCK_SEQPACKET | |
#Try to remove socket reference before running (yes, we should only do this in case we need to but this is just a PoC) | |
if AUTO_DELETE: | |
try: | |
os.unlink('/tmp/fd_test.sock') | |
except: | |
pass | |
try: | |
server = my_server('/tmp/fd_test.sock', my_handler) | |
server.serve_forever() | |
finally: | |
#Clean up | |
os.unlink('/tmp/fd_test.sock') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment