1 /* This file is #include'd by libtlspool.c */
2 #define closesocket(s) close(s)
4 int os_sendmsg_command(int poolfd, struct tlspool_command *cmd, int fd) {
7 struct msghdr mh = { 0 };
9 iov.iov_len = sizeof(struct tlspool_command);
13 char anc[CMSG_SPACE(sizeof(int))];
15 mh.msg_controllen = sizeof (anc);
16 cmsg = CMSG_FIRSTHDR (&mh);
17 cmsg->cmsg_level = SOL_SOCKET;
18 cmsg->cmsg_type = SCM_RIGHTS;
19 *(int *)CMSG_DATA(cmsg) = fd;
20 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
22 return sendmsg (poolfd, &mh, MSG_NOSIGNAL);
26 int os_recvmsg_command(int poolfd, struct tlspool_command *cmd) {
29 struct msghdr mh = { 0 };
31 iov.iov_len = sizeof (struct tlspool_command);
34 //NOT-USED// mh.msg_control = anc;
35 //NOT-USED// mh.msg_controllen = sizeof (anc);
36 return recvmsg (poolfd, &mh, MSG_NOSIGNAL);
39 * converts IPPROTO_* to SOCK_*, returns -1 if invalid protocol
41 int ipproto_to_sockettype(uint8_t ipproto) {
42 return ipproto == IPPROTO_TCP ? SOCK_STREAM : ipproto == IPPROTO_UDP ? SOCK_DGRAM : ipproto == IPPROTO_SCTP ? SOCK_SEQPACKET : -1;
46 * The namedconnect() function is called by tlspool_starttls() when the
47 * identities have been exchanged, and established, in the TLS handshake.
48 * This is the point at which a connection to the plaintext side is
49 * needed, and a callback to namedconnect() is made to find a handle for
50 * it. The function is called with a version of the tlsdata that has
51 * been updated by the TLS Pool to hold the local and remote identities.
53 * When the namedconnect argument passed to tlspool_starttls() is NULL,
54 * this default function is used instead of the possible override by the
55 * caller. This interprets the privdata handle as an (int *) holding
56 * a file descriptor. If its value is valid, that is, >= 0, it will be
57 * returned directly; otherwise, a socketpair is constructed, one of the
58 * sockets is stored in privdata for use by the caller and the other is
59 * returned as the connected file descriptor for use by the TLS Pool.
60 * This means that the privdata must be properly initialised for this
61 * use, with either -1 (to create a socketpair) or the TLS Pool's
62 * plaintext file descriptor endpoint. The file handle returned in
63 * privdata, if it is >= 0, should be closed by the caller, both in case
64 * of success and failure.
66 * The return value should be -1 on error, with errno set, or it should
67 * be a valid file handle that can be passed back to the TLS Pool to
70 int tlspool_namedconnect_default (starttls_t *tlsdata, void *privdata) {
73 int type = ipproto_to_sockettype (tlsdata->ipproto);
78 if (socketpair (AF_UNIX, type, 0, soxx) == 0)
80 // printf("DEBUG: socketpair succeeded\n");
81 /* Socketpair created */
83 * (int *) privdata = soxx [1];
85 /* Socketpair failed */
86 // printf("DEBUG: socketpair failed\n");
92 /* Determine an upper limit for simultaneous STARTTLS threads, based on the
93 * number of available file descriptors. Note: The result is cached, so
94 * don't use root to increase beyond max in setrlimit() after calling this.
96 int tlspool_simultaneous_starttls(void) {
99 struct rlimit rlimit_nofile;
100 if (getrlimit (RLIMIT_NOFILE, &rlimit_nofile) == -1) {
101 syslog (LOG_NOTICE, "Failed to determine simultaneous STARTTLS: %s", strerror (errno));
102 rlimit_nofile.rlim_max = 1024; // Pick something
104 simu = rlimit_nofile.rlim_max / 2; // 2 FDs per STARTTLS
109 int os_usleep(unsigned int usec) {
113 int open_pool (void *path) {
114 struct sockaddr_un sun;
116 // Setup path information -- value and size were checked
117 memset (&sun, 0, sizeof (sun));
118 strcpy (sun.sun_path, (char *) path);
119 sun.sun_family = AF_UNIX;
120 int newpoolfd = socket (AF_UNIX, SOCK_STREAM, 0);
121 if (newpoolfd >= 0) {
122 if (connect (newpoolfd, (struct sockaddr *) &sun, SUN_LEN (&sun)) != 0) {
123 tlspool_close_poolhandle (newpoolfd);
127 // printf ("DEBUG: Trying new poolfd %d for path %s\n", newpoolfd, sun.sun_path);