Coda Distributed File System
Loading...
Searching...
No Matches
codatunneld.private.h
Go to the documentation of this file.
1/* BLURB lgpl
2
3 Coda File System
4 Release 8
5
6 Copyright (c) 2017-2026 Carnegie Mellon University
7 Additional copyrights listed below
8
9This code is distributed "AS IS" without warranty of any kind under
10the terms of the GNU Library General Public Licence Version 2, as
11shown in the file LICENSE. The technical and financial contributors to
12Coda are listed in the file CREDITS.
13
14 Additional copyrights
15
16#*/
17
18#ifndef _CODATUNNELD_PRIVATE_H_
19#define _CODATUNNELD_PRIVATE_H_
20
21#include <sys/types.h>
22#include <sys/socket.h>
23#include <assert.h>
24#include <sys/time.h>
25#include <stdlib.h>
26#include <uv.h>
27#include <gnutls/gnutls.h>
28
29#include "ctp.h"
30
31int mapthread(uv_thread_t);
32
33#if 0 /* per-packet/per-record trace; off by default (see TLOG below) */
34#define DEBUG(...) \
35 do { \
36 struct timeval tt; \
37 gettimeofday(&tt, 0); \
38 int myid = mapthread(uv_thread_self()); \
39 fprintf(stderr, "[%d] %ld.%06ld %s:%d ", myid, (long)tt.tv_sec, \
40 (long)tt.tv_usec, __FUNCTION__, __LINE__); \
41 fprintf(stderr, __VA_ARGS__); \
42 fflush(stderr); \
43 } while (0)
44#else
45#define DEBUG(...)
46#endif
47
48#define ERROR(...) \
49 do { \
50 fprintf(stderr, "%s:%d ", __FUNCTION__, __LINE__); \
51 fprintf(stderr, __VA_ARGS__); \
52 fflush(stderr); \
53 } while (0)
54
55/* Timeline log for the daemon-driven file transfer and the per-packet tunnel
56 * trace. Gated behind the CODATUNNEL_TLOG env var (default OFF) so a normal
57 * build is silent and disk-safe; set CODATUNNEL_TLOG to any value to turn on
58 * the full trace for a debugging session (no rebuild needed to toggle). Every
59 * line is prefixed with a gettimeofday stamp (sec.usec) so client and server
60 * daemon logs can be turned into timelines and correlated. */
61static inline int ct_tlog_enabled(void)
62{
63 static int en = -1;
64
65 if (en < 0)
66 en = (getenv("CODATUNNEL_TLOG") != NULL);
67 return en;
68}
69
70#define TLOG(...) \
71 do { \
72 if (ct_tlog_enabled()) { \
73 struct timeval tt; \
74 gettimeofday(&tt, 0); \
75 fprintf(stderr, "%ld.%06ld ", (long)tt.tv_sec, (long)tt.tv_usec); \
76 fprintf(stderr, __VA_ARGS__); \
77 fflush(stderr); \
78 } \
79 } while (0)
80
81/* the actual tunnel daemon (defined in codatunneld.c) */
82void codatunneld(int codatunnel_sockfd, const char *tcp_bindaddr,
83 const char *udp_bindaddr, const char *bind_service,
84 int onlytcp, const char *sslcertdir) __attribute__((noreturn));
85
86/* Format of encapsulated UDP packets sent on Unix domain connections
87 (i.e., between Venus and codatunneld, and between codasrv and
88 codatunneld.) All fields are in the clear. This header is followed
89 by `msglen` encrypted bytes of the RPC2 packet that is sent or
90 received. On the network, this header is NOT sent in UDP packets; but
91 it IS sent in TCP-tunneled packets
92*/
93/* The framing struct ctp_t, the ct_opcode enum, and CT_MAX_RECORD live in
94 "ctp.h" (pure wire protocol; no tunnel dependencies). */
95
96/* Transitions always: FREE --> ALLOCATED --> (optionally)TCPATTEMPTING -->
97 * TLSHANDSHAKE --> TCPACTIVE --> TCPCLOSING --> FREE */
99{
100 FREE = 0, /* this entry is not allocated */
101 ALLOCATED = 1, /* entry allocated, but TCP is not active; UDP works */
102 TCPATTEMPTING = 2, /* entry allocated, tcp connect is being attempted;
103 UDP works */
104 TLSHANDSHAKE = 3, /* tcp connection is good; TLS handshake in progress */
105 TCPACTIVE = 4, /* entry allocated, its tcphandle is good, and TLS
106 handshake successful */
107 TLSERROR = 5, /* an error occurred in TLS worker threads */
108 TCPCLOSING = 6, /* now closing, and waiting to become FREE */
109};
110
111const char *tcpstatename(enum deststate);
112
113typedef struct {
114 uv_buf_t b; /* b.len is max size of buffer, not useful bytes */
115 int numbytes; /* number of useful bytes pointed to by b->base */
116} enq_data_t;
117
118typedef struct remotedest {
121 const char *fqdn; /* passed by INIT0 packet on client, NULL on server */
122
123 enum deststate state; /* All destinations are assumed to be capable of
124 becoming TCPACTIVE; Setting TCPACTIVE should be a
125 commit point: all fields below should have been
126 set before that happens, to avoid race conditions */
127 char certvalidation_failed; /* when certificate validation fails we
128 suppress UDP, but will retry TLS connections
129 for INIT0 packets*/
130
131 uv_tcp_t *tcphandle; /* only valid if state is TCPACTIVE or TLSHANDSHAKE */
132
133 gnutls_session_t my_tls_session;
134 size_t max_data_payload; /* largest CT_TRANSFER_DATA payload this session's
135 * negotiated TLS record max can carry:
136 * gnutls_record_get_max_size() minus the ctp_t and
137 * ct_transfer_data headers. Captured at handshake
138 * (before TCPACTIVE); a sender caps each record to
139 * min(CT_CHUNKMAX, this) so it fits in one fragment */
140 char *decrypted_record; /* pointer to malloced array of size CT_MAX_RECORD;
141 filled by gnutls_record_recv() by reassembly from
142 calls to eat_uvbytes(); must be preserved across
143 successive calls to gnutls_record_recv() for
144 reassembly to work properly */
145
146 /* Space to buffer packets from recv_tcp_cb() en route to
147 gnutls_record_recv(). enq_uvbuf() appends packets to this list.
148 eat_uvbytes() peels off bytes in these packets. We use a simple
149 array, because we don't expect this queue to get very long. Most
150 common case will be an exact match: one input packet waiting,
151 that is completely consumed in one call. If the future proves
152 otherwise, change to a linked list structure instead of array. */
153
154#define UVBUFLIMIT 10 /* drop packets beyond this limit */
155 enq_data_t enqarray[UVBUFLIMIT]; /* array of structures */
156 int uvcount; /* how many elements in use in above array */
157 uv_mutex_t uvcount_mutex; /* protects uvcount */
158 uv_cond_t uvcount_nonzero; /* signaled when uvcount goes above zero */
159 int uvoffset; /* array index of next unused byte in ((enqarray[0].b)->base[] */
160
161 /* Mutexes below ensure that only one gnutls_recv_record() and
162 one gnutls_send_record() can be in progress at a time; this is needed because
163 gnutls serializes data records on the TCP stream; currently, this appears to be
164 a 5-byte header that indicates a length, followed by that many bytes; however,
165 this may change in the future to be something more complex; use of a mutex eliminates
166 dependence on the exact serialization format; it is essential that
167 all the pieces of a serialized record appear consecutively in the TCP stream;
168 interleaving in an multi-threaded environment could be disastrous */
170 uv_mutex_t tls_send_mutex;
171 /* Guards the gnutls session itself: gnutls is not thread-safe, so
172 * gnutls_record_send() (worker thread) and gnutls_record_recv()
173 * (peel-off worker thread) must never run concurrently on the same
174 * session, even though the two record mutexes above are distinct */
177
178 uv_async_t wakeup; /* wakeup for outgoing packets or dest_t teardown */
180 uv_mutex_t outbound_mutex;
181
182 /* Receive backpressure (TCPACTIVE only): when the enqarray recv queue
183 * fills, we stop pulling from the socket (so it stays in the kernel
184 * buffer and pushes back on the writer) instead of dropping; when the
185 * queue drains to zero the thread pool resumes the read. read_paused and
186 * resume_read are guarded by uvcount_mutex. */
187 int read_paused; /* read stopped because recv queue is full */
188 uv_async_t resume_read; /* queue drained -> loop resumes uv_read_start */
189 /* Restart file transfers deferred while this channel was handshaking.
190 * Sent from setuptls() (a worker) once the channel commits TCPACTIVE; the
191 * callback runs on the loop because starting a pump is loop-only. */
192 uv_async_t redrive;
194
195static inline void free_tcphandle(uv_handle_t *handle)
196{
197 free(handle);
198}
199
200void outbound_worker_cb(uv_async_t *async);
201void resume_read_cb(uv_async_t *async);
202void ct_redrive_cb(uv_async_t *async);
203
204/* Stuff for destination management */
205void initdestarray(uv_loop_t *mainloop);
206dest_t *getdest(const struct sockaddr_storage *, socklen_t);
208 const char *peername);
209void free_dest(dest_t *d);
210
211/* Procedures to add and remove buffered data from a dest.
212 These operate in producer-consumer manner.
213 recv_tcp_cb() calls enq_uvbuf() as producer.
214 gnutls_record_recv() calls eat_uvbytes() as consumer.
215 During TLS handshake, eat_uvbytes() is also called as consumer.
216*/
217void enq_element(dest_t *, const uv_buf_t *, int);
218ssize_t eat_uvbytes(gnutls_transport_ptr_t, void *, size_t);
219int poll_uvbytes(gnutls_transport_ptr_t gtp, unsigned int ms);
220
223
224/* Helper/debugging functions */
225void hexdump(char *desc, void *addr, int len);
227
228#endif /* _CODATUNNELD_PRIVATE_H_ */
void initdestarray(uv_loop_t *mainloop)
Definition remotedest.c:60
void printsockaddr(const struct sockaddr_storage *, socklen_t)
dest_t * getdest(const struct sockaddr_storage *, socklen_t)
Definition remotedest.c:121
const char * tcpstatename(enum deststate)
Definition remotedest.c:406
void codatunneld(int codatunnel_sockfd, const char *tcp_bindaddr, const char *udp_bindaddr, const char *bind_service, int onlytcp, const char *sslcertdir) __attribute__((noreturn))
Definition codatunneld.c:2386
void drain_outbound_queues(dest_t *d)
Definition codatunneld.c:294
void outbound_worker_cb(uv_async_t *async)
Definition codatunneld.c:1469
void enq_element(dest_t *, const uv_buf_t *, int)
Definition remotedest.c:235
struct remotedest dest_t
void resume_read_cb(uv_async_t *async)
Definition codatunneld.c:2021
void hexdump(char *desc, void *addr, int len)
Definition codatunneld.c:2548
void ct_fail_dest_transfers(dest_t *d)
Definition codatunneld.c:1086
void free_dest(dest_t *d)
Definition remotedest.c:197
int mapthread(uv_thread_t)
Definition remotedest.c:384
dest_t * createdest(const struct sockaddr_storage *, socklen_t, const char *peername)
Definition remotedest.c:138
void ct_redrive_cb(uv_async_t *async)
Definition codatunneld.c:1789
ssize_t eat_uvbytes(gnutls_transport_ptr_t, void *, size_t)
Definition remotedest.c:314
deststate
Definition codatunneld.private.h:99
@ TLSHANDSHAKE
Definition codatunneld.private.h:104
@ TCPATTEMPTING
Definition codatunneld.private.h:102
@ TLSERROR
Definition codatunneld.private.h:107
@ TCPACTIVE
Definition codatunneld.private.h:105
@ ALLOCATED
Definition codatunneld.private.h:101
@ FREE
Definition codatunneld.private.h:100
@ TCPCLOSING
Definition codatunneld.private.h:108
int poll_uvbytes(gnutls_transport_ptr_t gtp, unsigned int ms)
Definition remotedest.c:291
#define UVBUFLIMIT
Definition codatunneld.private.h:154
int socklen_t
Definition mariner.cc:73
Definition codatunneld.private.h:113
uv_buf_t b
Definition codatunneld.private.h:114
int numbytes
Definition codatunneld.private.h:115
Definition codatunneld.c:179
Definition codatunneld.private.h:118
uv_async_t resume_read
Definition codatunneld.private.h:188
void * tls_send_queue
Definition codatunneld.private.h:176
uv_mutex_t uvcount_mutex
Definition codatunneld.private.h:157
uv_cond_t uvcount_nonzero
Definition codatunneld.private.h:158
uv_tcp_t * tcphandle
Definition codatunneld.private.h:131
struct minicb_tcp_req * outbound_queue
Definition codatunneld.private.h:179
int read_paused
Definition codatunneld.private.h:187
char certvalidation_failed
Definition codatunneld.private.h:127
char * decrypted_record
Definition codatunneld.private.h:140
uv_async_t wakeup
Definition codatunneld.private.h:178
socklen_t destlen
Definition codatunneld.private.h:120
size_t max_data_payload
Definition codatunneld.private.h:134
int uvcount
Definition codatunneld.private.h:156
uv_mutex_t outbound_mutex
Definition codatunneld.private.h:180
enum deststate state
Definition codatunneld.private.h:123
struct sockaddr_storage destaddr
Definition codatunneld.private.h:119
const char * fqdn
Definition codatunneld.private.h:121
uv_mutex_t tls_receive_record_mutex
Definition codatunneld.private.h:169
enq_data_t enqarray[UVBUFLIMIT]
Definition codatunneld.private.h:155
gnutls_session_t my_tls_session
Definition codatunneld.private.h:133
uv_mutex_t tls_session_mutex
Definition codatunneld.private.h:175
uv_async_t redrive
Definition codatunneld.private.h:192
int uvoffset
Definition codatunneld.private.h:159
uv_mutex_t tls_send_mutex
Definition codatunneld.private.h:170
Definition rpc2.private.h:63
char d
Definition tdb.c:54
const char * sslcertdir
Definition venus.cc:93
#define NULL
Definition voltypes.h:44