From 4562e816f0ba7b8fb71645b03a8c8ea54eb1faf4 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Fri, 30 Oct 2015 23:06:45 +0100 Subject: [PATCH] Add code to create a socket pair and send filedescriptors --- include/tr/socket.h | 5 +++- src/Makefile.am | 2 ++ src/socket_accept.c | 4 ---- src/socket_get_fd.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ src/socket_pair.c | 6 ----- src/socket_send_fd.c | 52 +++++++++++++++++++++++++++++++++++++++++ src/tcp_socket.c | 5 +--- 7 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 src/socket_get_fd.c create mode 100644 src/socket_send_fd.c diff --git a/include/tr/socket.h b/include/tr/socket.h index 275bc96..799bf56 100644 --- a/include/tr/socket.h +++ b/include/tr/socket.h @@ -66,6 +66,7 @@ TR_CLASS(TR_Socket) { socklen_t addrlen; int handle; TR_SocketFin fin_state; + int fd_getter; }; TR_INSTANCE_INIT(TR_Socket); TR_CLASSVARS_DECL(TR_Socket) {}; @@ -81,6 +82,7 @@ TR_CLASSVARS_DECL(TR_Socket) {}; #define TR_socketAddrlen(socket) ((socket)->addrlen) #define TR_socketHandle(socket) ((socket)->handle) #define TR_socketFinState(socket) ((socket)->fin_state) +#define TR_socketFdGetter(socket) ((socket)->fd_getter) #define TR_socketFinRd(socket) \ ((TR_socketFinState(socket) & TR_FIN_RD) == TR_FIN_RD) #define TR_socketFinWr(socket) \ @@ -118,7 +120,6 @@ TR_CLASSVARS_DECL(TR_Socket) {}; TR_CLASS(TR_TcpSocket) { TR_EXTENDS(TR_Socket); - int listen; int connected; }; TR_INSTANCE_INIT(TR_TcpSocket); @@ -151,6 +152,8 @@ TR_TcpSocket TR_socketAccept(TR_TcpSocket); (TR_socketInit((socket), NULL)) void TR_socketPair(TR_Socket[2], int); +void TR_socketSendFd(TR_Socket, int); +int TR_socketGetFd(TR_Socket); #endif // __TR_SOCKET_H__ diff --git a/src/Makefile.am b/src/Makefile.am index d57384d..e8ee8de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,8 @@ TRIO = stream.c \ socket_nonblock.c \ socket_close.c \ socket_pair.c \ + socket_send_fd.c \ + socket_get_fd.c \ socket_shutdown.c \ socket_shutdown_read.c \ socket_shutdown_write.c \ diff --git a/src/socket_accept.c b/src/socket_accept.c index 95ca50c..c4d22e3 100644 --- a/src/socket_accept.c +++ b/src/socket_accept.c @@ -42,7 +42,6 @@ TR_socketAccept(TR_TcpSocket this) { TR_Socket remote = TR_new(TR_TcpSocket, TR_socketLog((TR_Socket)this), NULL, 0, 0); - //int flags; remote->addrlen = ((TR_Socket)this)->addrlen; remote->handle = accept( @@ -50,9 +49,6 @@ TR_socketAccept(TR_TcpSocket this) &(remote->addr.info), &(remote->addrlen)); - //flags = fcntl(remote->handle, F_GETFL, 0); - //fcntl(remote->handle, F_SETFL, flags | O_NONBLOCK); - if (-1 == remote->handle) { TR_delete(remote); } else { diff --git a/src/socket_get_fd.c b/src/socket_get_fd.c new file mode 100644 index 0000000..dcdd962 --- /dev/null +++ b/src/socket_get_fd.c @@ -0,0 +1,55 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include // for errno +#include +#include + +#include "tr/socket.h" +#include "tr/logger.h" + +int +TR_socketGetFd(TR_Socket this) +{ + struct msghdr msg; + struct cmsghdr * cmsg; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; + int fd = 0; + + memset(&msg, 0, sizeof(msg)); + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + + if (0 > recvmsg(TR_socketHandle(this), &msg, 0)) { + return -1; + } + + cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg == NULL || cmsg->cmsg_type != SCM_RIGHTS) { + return -1; + } + + memcpy(&fd, CMSG_DATA(cmsg), sizeof(int)); + return fd; +} + +// vim: set ts=4 sw=4: diff --git a/src/socket_pair.c b/src/socket_pair.c index bd0a5f2..e03b75f 100644 --- a/src/socket_pair.c +++ b/src/socket_pair.c @@ -20,12 +20,6 @@ * along with this program. If not, see . */ -//#include -//#include -//#include -//#include -//#include - #include #include #include diff --git a/src/socket_send_fd.c b/src/socket_send_fd.c new file mode 100644 index 0000000..cb692d5 --- /dev/null +++ b/src/socket_send_fd.c @@ -0,0 +1,52 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include // for errno +#include +#include + +#include "tr/socket.h" +#include "tr/logger.h" + +void +TR_socketSendFd(TR_Socket this, int fd) +{ + struct msghdr msg; + struct cmsghdr * cmsg; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; + + memset(&msg, 0, sizeof(msg)); + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); // necessary for CMSG_FIRSTHDR to + // return the correct value + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); + msg.msg_controllen = cmsg->cmsg_len; // total size of all control blocks + + sendmsg(TR_socketHandle(this), &msg, 0); + /* TODO error handling... */ +} + +// vim: set ts=4 sw=4: diff --git a/src/tcp_socket.c b/src/tcp_socket.c index 086571a..4036a89 100644 --- a/src/tcp_socket.c +++ b/src/tcp_socket.c @@ -41,10 +41,7 @@ tcpSocketCtor(void * _this, va_list * params) TR_TcpSocket this = _this; TR_PARENTCALL(TR_TcpSocket, _this, TR_Class, ctor, params); - TR_socketType((TR_Socket)this) = SOCK_STREAM; - this->listen = FALSE; - this->connected = FALSE; return 0; } @@ -66,7 +63,7 @@ tcpSocketBind(void * _this) // error return -1; } - this->listen = TRUE; + ((TR_Socket)this)->fd_getter = TRUE; return 0; }