Coda Distributed File System
codatunnel.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 _CODATUNNEL_PRIVATE_H_
19#define _CODATUNNEL_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
29int mapthread(uv_thread_t);
30
31#if 0
32#define DEBUG(...) \
33 do { \
34 struct timeval tt; \
35 gettimeofday(&tt, 0); \
36 int myid = mapthread(uv_thread_self()); \
37 fprintf(stderr, "[%d] %ld:%ld %s:%d ", myid, tt.tv_sec, tt.tv_usec, \
38 __FUNCTION__, __LINE__); \
39 fprintf(stderr, __VA_ARGS__); \
40 fflush(stderr); \
41 } while (0)
42#else
43#define DEBUG(...)
44#endif
45
46#define ERROR(...) \
47 do { \
48 fprintf(stderr, "%s:%d ", __FUNCTION__, __LINE__); \
49 fprintf(stderr, __VA_ARGS__); \
50 fflush(stderr); \
51 } while (0)
52
53/* the actual tunnel daemon (defined in codatunneld.c) */
54void codatunneld(int codatunnel_sockfd, const char *tcp_bindaddr,
55 const char *udp_bindaddr, const char *bind_service,
56 int onlytcp, const char *sslcertdir) __attribute__((noreturn));
57
58/* Format of encapsulated UDP packets sent on Unix domain connections
59 (i.e., between Venus and codatunneld, and between codasrv and
60 codatunneld.) All fields are in the clear. This header is followed
61 by `msglen` encrypted bytes of the RPC2 packet that is sent or
62 received. On the network, this header is NOT sent in UDP packets; but
63 it IS sent in TCP-tunneled packets
64*/
65typedef struct codatunnel_packet {
66 char magic[8];
67 uint32_t is_retry; /* 1 if this is a resend, 0 otherwise */
69 is_init0; /* 1 if this packet identifies peer hostname, 0 otherwise */
70 uint32_t msglen; /* actual number of bytes in the packet */
71 uint32_t addrlen; /* verbatim from sendto() or recvfrom () */
72 struct sockaddr_storage addr; /* verbatim from sendto() or recvfrom () */
74
75#define MAXRECEIVE (4500 + sizeof(ctp_t))
76/* WARNING: gross hack! Above field is space for received packet
77 that may be assembled piecemeal from multiple TCP reads; the
78 figure of 4500 is RPC2_MAXPACKETSIZE; there are many cleverer
79 ways of allocating this space, but the simplicity of this
80 approach is fine for initial implementation; get it working
81 first, and then fix later
82*/
83
84/* Transitions always: FREE --> ALLOCATED --> (optionally)TCPATTEMPTING -->
85 * TLSHANDSHAKE --> TCPACTIVE --> TCPCLOSING --> FREE */
87{
88 FREE = 0, /* this entry is not allocated */
89 ALLOCATED = 1, /* entry allocated, but TCP is not active; UDP works */
90 TCPATTEMPTING = 2, /* entry allocated, tcp connect is being attempted;
91 UDP works */
92 TLSHANDSHAKE = 3, /* tcp connection is good; TLS handshake in progress */
93 TCPACTIVE = 4, /* entry allocated, its tcphandle is good, and TLS
94 handshake successful */
95 TLSERROR = 5, /* an error occurred in TLS worker threads */
96 TCPCLOSING = 6, /* now closing, and waiting to become FREE */
97};
98
99const char *tcpstatename(enum deststate);
100
101typedef struct {
102 uv_buf_t b; /* b.len is max size of buffer, not useful bytes */
103 int numbytes; /* number of useful bytes pointed to by b->base */
104} enq_data_t;
105
106typedef struct remotedest {
109 const char *fqdn; /* passed by INIT0 packet on client, NULL on server */
110
111 enum deststate state; /* All destinations are assumed to be capable of
112 becoming TCPACTIVE; Setting TCPACTIVE should be a
113 commit point: all fields below should have been
114 set before that happens, to avoid race conditions */
115 char certvalidation_failed; /* when certificate validation fails we
116 suppress UDP, but will retry TLS connections
117 for INIT0 packets*/
118
119 uv_tcp_t *tcphandle; /* only valid if state is TCPACTIVE or TLSHANDSHAKE */
120
121 gnutls_session_t my_tls_session;
122
123 char *decrypted_record; /* pointer to malloced array of size MAXRECEIVE;
124 filled by gnutls_record_recv() by reassembly from
125 calls to eat_uvbytes(); must be preserved across
126 successive calls to gnutls_record_recv() for
127 reassembly to work properly */
128
129 /* Space to buffer packets from recv_tcp_cb() en route to
130 gnutls_record_recv(). enq_uvbuf() appends packets to this list.
131 eat_uvbytes() peels off bytes in these packets. We use a simple
132 array, because we don't expect this queue to get very long. Most
133 common case will be an exact match: one input packet waiting,
134 that is completely consumed in one call. If the future proves
135 otherwise, change to a linked list structure instead of array. */
136
137#define UVBUFLIMIT 10 /* drop packets beyond this limit */
138 enq_data_t enqarray[UVBUFLIMIT]; /* array of structures */
139 int uvcount; /* how many elements in use in above array */
140 uv_mutex_t uvcount_mutex; /* protects uvcount */
141 uv_cond_t uvcount_nonzero; /* signaled when uvcount goes above zero */
142 int uvoffset; /* array index of next unused byte in ((enqarray[0].b)->base[] */
143
144 /* Mutexes below ensure that only one gnutls_recv_record() and
145 one gnutls_send_record() can be in progress at a time; this is needed because
146 gnutls serializes data records on the TCP stream; currently, this appears to be
147 a 5-byte header that indicates a length, followed by that many bytes; however,
148 this may change in the future to be something more complex; use of a mutex eliminates
149 dependence on the exact serialization format; it is essential that
150 all the pieces of a serialized record appear consecutively in the TCP stream;
151 interleaving in an multi-threaded environment could be disastrous */
153 uv_mutex_t tls_send_mutex;
155
156 uv_async_t wakeup; /* wakeup for outgoing packets or dest_t teardown */
158 uv_mutex_t outbound_mutex;
160
161static inline void free_tcphandle(uv_handle_t *handle)
162{
163 free(handle);
164}
165
166void outbound_worker_cb(uv_async_t *async);
167
168/* Stuff for destination management */
170dest_t *getdest(const struct sockaddr_storage *, socklen_t);
172 const char *peername);
173void free_dest(dest_t *d);
174
175/* Procedures to add and remove buffered data from a dest.
176 These operate in producer-consumer manner.
177 recv_tcp_cb() calls enq_uvbuf() as producer.
178 gnutls_record_recv() calls eat_uvbytes() as consumer.
179 During TLS handshake, eat_uvbytes() is also called as consumer.
180*/
181void enq_element(dest_t *, const uv_buf_t *, int);
182ssize_t eat_uvbytes(gnutls_transport_ptr_t, void *, size_t);
183int poll_uvbytes(gnutls_transport_ptr_t gtp, unsigned int ms);
184
186
187/* Helper/debugging functions */
188void hexdump(char *desc, void *addr, int len);
190
191#endif /* _CODATUNNEL_PRIVATE_H_ */
unsigned int uint32_t
Definition: coda.h:105
void printsockaddr(const struct sockaddr_storage *, socklen_t)
dest_t * getdest(const struct sockaddr_storage *, socklen_t)
Definition: remotedest.c:115
const char * tcpstatename(enum deststate)
Definition: remotedest.c:362
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:1257
void drain_outbound_queues(dest_t *d)
Definition: codatunneld.c:199
void outbound_worker_cb(uv_async_t *async)
Definition: codatunneld.c:550
void enq_element(dest_t *, const uv_buf_t *, int)
Definition: remotedest.c:226
struct remotedest dest_t
void hexdump(char *desc, void *addr, int len)
Definition: codatunneld.c:1410
void free_dest(dest_t *d)
Definition: remotedest.c:191
void initdestarray()
int mapthread(uv_thread_t)
Definition: remotedest.c:340
dest_t * createdest(const struct sockaddr_storage *, socklen_t, const char *peername)
Definition: remotedest.c:132
ssize_t eat_uvbytes(gnutls_transport_ptr_t, void *, size_t)
Definition: remotedest.c:281
deststate
Definition: codatunnel.private.h:87
@ TLSHANDSHAKE
Definition: codatunnel.private.h:92
@ TCPATTEMPTING
Definition: codatunnel.private.h:90
@ TLSERROR
Definition: codatunnel.private.h:95
@ TCPACTIVE
Definition: codatunnel.private.h:93
@ ALLOCATED
Definition: codatunnel.private.h:89
@ FREE
Definition: codatunnel.private.h:88
@ TCPCLOSING
Definition: codatunnel.private.h:96
struct codatunnel_packet ctp_t
int poll_uvbytes(gnutls_transport_ptr_t gtp, unsigned int ms)
Definition: remotedest.c:258
#define UVBUFLIMIT
Definition: codatunnel.private.h:137
int socklen_t
Definition: mariner.cc:73
desc
Definition: gensrvstats.py:254
Definition: codatunnel.private.h:65
struct sockaddr_storage addr
Definition: codatunnel.private.h:72
char magic[8]
Definition: codatunnel.private.h:66
uint32_t is_init0
Definition: codatunnel.private.h:69
uint32_t msglen
Definition: codatunnel.private.h:70
uint32_t addrlen
Definition: codatunnel.private.h:71
uint32_t is_retry
Definition: codatunnel.private.h:67
Definition: codatunnel.private.h:101
uv_buf_t b
Definition: codatunnel.private.h:102
int numbytes
Definition: codatunnel.private.h:103
Definition: codatunneld.c:95
Definition: codatunnel.private.h:106
void * tls_send_queue
Definition: codatunnel.private.h:154
uv_mutex_t uvcount_mutex
Definition: codatunnel.private.h:140
uv_cond_t uvcount_nonzero
Definition: codatunnel.private.h:141
uv_tcp_t * tcphandle
Definition: codatunnel.private.h:119
struct minicb_tcp_req * outbound_queue
Definition: codatunnel.private.h:157
char certvalidation_failed
Definition: codatunnel.private.h:115
char * decrypted_record
Definition: codatunnel.private.h:123
uv_async_t wakeup
Definition: codatunnel.private.h:156
socklen_t destlen
Definition: codatunnel.private.h:108
int uvcount
Definition: codatunnel.private.h:139
uv_mutex_t outbound_mutex
Definition: codatunnel.private.h:158
enum deststate state
Definition: codatunnel.private.h:111
struct sockaddr_storage destaddr
Definition: codatunnel.private.h:107
const char * fqdn
Definition: codatunnel.private.h:109
uv_mutex_t tls_receive_record_mutex
Definition: codatunnel.private.h:152
enq_data_t enqarray[UVBUFLIMIT]
Definition: codatunnel.private.h:138
gnutls_session_t my_tls_session
Definition: codatunnel.private.h:121
int uvoffset
Definition: codatunnel.private.h:142
uv_mutex_t tls_send_mutex
Definition: codatunnel.private.h:153
Definition: rpc2.private.h:63
char d
Definition: tdb.c:54
const char * sslcertdir
Definition: venus.cc:93