1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
|
/* Copyright (c) 2001, Stanford University
* All rights reserved.
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#ifndef CR_NET_H
#define CR_NET_H
#ifdef WINDOWS
#define WIN32_LEAN_AND_MEAN
# ifndef VBOX
#pragma warning( push, 3 ) /* shut up about warnings in YOUR OWN HEADER FILES!!! */
#include <winsock.h>
# else
# include <iprt/win/winsock.h>
# endif /* VBOX */
#endif
#include <stdio.h>
#ifndef WINDOWS
#include <sys/socket.h>
#ifndef DARWIN
#ifdef AF_INET6
/* getaddrinfo & co appeared with ipv6 */
#define ADDRINFO
#endif
#endif
#include <netinet/in.h>
#endif
#ifdef SunOS
#include <sys/types.h>
#endif
#include "cr_protocol.h"
#include "cr_threads.h"
#include <iprt/types.h>
#include <iprt/thread.h>
#include <iprt/list.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DEFAULT_SERVER_PORT 7000
/* If you change this, update DefaultMothershipPort in mothership.py */
#define DEFAULT_MOTHERSHIP_PORT 10000
typedef struct CRConnection CRConnection;
typedef enum {
CR_NO_CONNECTION,
CR_SDP,
CR_TCPIP,
CR_UDPTCPIP,
CR_FILE,
CR_GM,
CR_IB,
CR_TEAC,
CR_TCSCOMM,
CR_VBOXHGCM,
CR_DROP_PACKETS
} CRConnectionType;
#if defined(WINDOWS)
typedef SOCKET CRSocket;
#else
typedef int CRSocket;
#endif
typedef void (*CRVoidFunc)( void );
typedef int (*CRNetReceiveFunc)( CRConnection *conn, CRMessage *msg, unsigned int len );
typedef int (*CRNetConnectFunc)( CRConnection *conn );
typedef void (*CRNetCloseFunc)( unsigned int sender_id );
typedef struct __recvFuncList {
CRNetReceiveFunc recv;
struct __recvFuncList *next;
} CRNetReceiveFuncList;
typedef struct __closeFuncList {
CRNetCloseFunc close;
struct __closeFuncList *next;
} CRNetCloseFuncList;
typedef struct __messageListNode {
CRMessage *mesg; /* the actual message (header + payload) */
unsigned int len; /* length of message (header + payload) */
CRConnection *conn; /* some messages are assoc. with specific connections*/
struct __messageListNode *next; /* next in list */
} CRMessageListNode;
typedef struct {
CRMessageListNode *head, *tail;
int numMessages;
CRmutex lock;
CRcondition nonEmpty;
} CRMessageList;
/**
* Used to accumulate CR_MESSAGE_MULTI_BODY/TAIL chunks into one big buffer.
*/
typedef struct CRMultiBuffer {
unsigned int len; /* current length (<= max) (with sizeof_buffer_header) */
unsigned int max; /* size in bytes of data buffer */
void *buf; /* data buffer */
} CRMultiBuffer;
#ifdef VBOX_WITH_CRHGSMI
# ifdef IN_GUEST
typedef struct CRVBOXHGSMI_CLIENT {
struct VBOXUHGSMI *pHgsmi;
struct VBOXUHGSMI_BUFFER *pCmdBuffer;
struct VBOXUHGSMI_BUFFER *pHGBuffer;
void *pvHGBuffer;
struct CRBufferPool_t *bufpool;
} CRVBOXHGSMI_CLIENT, *PCRVBOXHGSMI_CLIENT;
#endif /* IN_GUEST */
#endif /* #ifdef VBOX_WITH_CRHGSMI */
/**
* Chromium network connection (bidirectional).
*/
struct CRConnection {
int ignore;
CRConnectionType type;
unsigned int id; /* obtained from the mothership (if brokered) */
/* List of messages that we've received on the network connection but
* nobody has yet consumed.
*/
CRMessageList messageList;
CRMultiBuffer multi;
unsigned int mtu; /* max transmission unit size (in bytes) */
unsigned int buffer_size;
unsigned int krecv_buf_size;
int broker; /* is connection brokered through mothership? */
int threaded; /* is this a threaded connection? */
int endianness, swap;
int actual_network; /* is this a real network? */
unsigned char *userbuf;
int userbuf_len;
char *hostname;
int port;
/* To allocate a data buffer of size conn->buffer_size bytes */
void *(*Alloc)( CRConnection *conn );
/* To indicate the client's done with a data buffer */
void (*Free)( CRConnection *conn, void *buf );
/* To send a data buffer. If bufp is non-null, it must have been obtained
* from Alloc() and it'll be freed when Send() returns.
*/
void (*Send)( CRConnection *conn, void **buf, const void *start, unsigned int len );
/* To send a data buffer than can optionally be dropped on the floor */
void (*Barf)( CRConnection *conn, void **buf, const void *start, unsigned int len );
/* To send 'len' bytes from buffer at 'start', no funny business */
void (*SendExact)( CRConnection *conn, const void *start, unsigned int len );
/* To receive data. 'len' bytes will be placed into 'buf'. */
void (*Recv)( CRConnection *conn, void *buf, unsigned int len );
/* To receive one message on the connection */
void (*RecvMsg)( CRConnection *conn );
/* What's this??? */
void (*InstantReclaim)( CRConnection *conn, CRMessage *mess );
/* Called when a full CR_MESSAGE_MULTI_HEAD/TAIL message has been received */
void (*HandleNewMessage)( CRConnection *conn, CRMessage *mess, unsigned int len );
/* To accept a new connection from a client */
void (*Accept)( CRConnection *conn, const char *hostname, unsigned short port );
/* To connect to a server (return 0 if error, 1 if success) */
int (*Connect)( CRConnection *conn );
/* To disconnect from a server */
void (*Disconnect)( CRConnection *conn );
unsigned int sizeof_buffer_header;
/* logging */
int total_bytes_sent;
int total_bytes_recv;
int recv_count;
int opcodes_count;
/* credits for flow control */
int send_credits;
int recv_credits;
/* TCP/IP */
CRSocket tcp_socket;
int index;
CRSocket sdp_socket;
/* UDP/IP */
CRSocket udp_socket;
#ifndef ADDRINFO
struct sockaddr_in remoteaddr;
#else
struct sockaddr_storage remoteaddr;
#endif
/* UDP/TCP/IP */
unsigned int seq;
unsigned int ack;
void *udp_packet;
int udp_packetlen;
/* FILE Tracing */
enum { CR_FILE_WRITE, CR_FILE_READ } file_direction;
char *filename;
int fd;
/* Myrinet GM */
unsigned int gm_node_id;
unsigned int gm_port_num;
/* Mellanox IB */
unsigned int ib_node_id;
unsigned int ib_port_num;
/* Quadrics Elan3 (teac) */
int teac_id;
int teac_rank;
/* Quadrics Elan3 (tcscomm) */
int tcscomm_id;
int tcscomm_rank;
/* VBox HGCM */
uint32_t u32ClientID;
uint8_t *pBuffer;
uint32_t cbBuffer;
uint8_t *pHostBuffer;
uint32_t cbHostBufferAllocated;
uint32_t cbHostBuffer;
#ifdef IN_GUEST
uint32_t u32InjectClientID;
# ifdef VBOX_WITH_CRHGSMI
CRVBOXHGSMI_CLIENT HgsmiClient;
struct VBOXUHGSMI *pExternalHgsmi;
# endif
#else
# ifdef VBOX_WITH_CRHGSMI
struct _crclient *pClient; /* back reference, just for simplicity */
CRVBOXHGSMI_CMDDATA CmdData;
# endif
RTLISTANCHOR PendingMsgList;
#endif
/* Used on host side to indicate that we are not allowed to store above pointers for later use
* in crVBoxHGCMReceiveMessage. As those messages are going to be processed after the corresponding
* HGCM call is finished and memory is freed. So we have to store a copy.
* This happens when message processing for client associated with this connection
* is blocked by another client, which has send us glBegin call and we're waiting to receive glEnd.
*/
uint8_t allow_redir_ptr;
uint32_t vMajor, vMinor; /*Protocol version*/
};
/*
* Network functions
*/
extern DECLEXPORT(int) crGetHostname( char *buf, unsigned int len );
extern DECLEXPORT(void) crNetInit( CRNetReceiveFunc recvFunc, CRNetCloseFunc closeFunc );
extern DECLEXPORT(void) crNetTearDown(void);
extern DECLEXPORT(void) *crNetAlloc( CRConnection *conn );
extern DECLEXPORT(void) crNetFree( CRConnection *conn, void *buf );
extern DECLEXPORT(void) crNetAccept( CRConnection *conn, const char *hostname, unsigned short port );
extern DECLEXPORT(int) crNetConnect( CRConnection *conn );
extern DECLEXPORT(void) crNetDisconnect( CRConnection *conn );
extern DECLEXPORT(void) crNetFreeConnection( CRConnection *conn );
extern DECLEXPORT(void) crCloseSocket( CRSocket sock );
extern DECLEXPORT(void) crNetSend( CRConnection *conn, void **bufp, const void *start, unsigned int len );
extern DECLEXPORT(void) crNetBarf( CRConnection *conn, void **bufp, const void *start, unsigned int len );
extern DECLEXPORT(void) crNetSendExact( CRConnection *conn, const void *start, unsigned int len );
extern DECLEXPORT(void) crNetSingleRecv( CRConnection *conn, void *buf, unsigned int len );
extern DECLEXPORT(unsigned int) crNetGetMessage( CRConnection *conn, CRMessage **message );
extern DECLEXPORT(unsigned int) crNetPeekMessage( CRConnection *conn, CRMessage **message );
extern DECLEXPORT(int) crNetNumMessages(CRConnection *conn);
extern DECLEXPORT(void) crNetReadline( CRConnection *conn, void *buf );
extern DECLEXPORT(int) crNetRecv(
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
CRConnection *conn
#else
void
#endif
);
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
#define CR_WRITEBACK_WAIT(_conn, _writeback) do { \
while (_writeback) { \
RTThreadYield(); \
crNetRecv(_conn); \
} \
} while (0)
#else
#define CR_WRITEBACK_WAIT(_conn, _writeback) do { \
while (_writeback) { \
RTThreadYield(); \
crNetRecv(); \
} \
} while (0)
#endif
#ifdef IN_GUEST
extern DECLEXPORT(uint32_t) crNetHostCapsGet(void);
#endif
extern DECLEXPORT(void) crNetDefaultRecv( CRConnection *conn, CRMessage *msg, unsigned int len );
extern DECLEXPORT(void) crNetDispatchMessage( CRNetReceiveFuncList *rfl, CRConnection *conn, CRMessage *msg, unsigned int len );
extern DECLEXPORT(CRConnection *) crNetConnectToServer( const char *server, unsigned short default_port, int mtu, int broker
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
, struct VBOXUHGSMI *pHgsmi
#endif
);
extern DECLEXPORT(CRConnection *) crNetAcceptClient( const char *protocol, const char *hostname, unsigned short port, unsigned int mtu, int broker );
extern DECLEXPORT(void) crInitMessageList(CRMessageList *list);
extern DECLEXPORT(void) crEnqueueMessage(CRMessageList *list, CRMessage *msg, unsigned int len, CRConnection *conn);
extern DECLEXPORT(void) crDequeueMessage(CRMessageList *list, CRMessage **msg, unsigned int *len, CRConnection **conn);
extern DECLEXPORT(void) crNetRecvReadPixels( const CRMessageReadPixels *rp, unsigned int len );
/*
* Quadrics stuff
*/
#define CR_QUADRICS_DEFAULT_LOW_CONTEXT 32
#define CR_QUADRICS_DEFAULT_HIGH_CONTEXT 35
extern DECLEXPORT(void) crNetSetRank( int my_rank );
extern DECLEXPORT(void) crNetSetContextRange( int low_context, int high_context );
extern DECLEXPORT(void) crNetSetNodeRange( const char *low_node, const char *high_node );
extern DECLEXPORT(void) crNetSetKey( const unsigned char* key, const int keyLength );
/*
* Socket callback facility
*/
#define CR_SOCKET_CREATE 1
#define CR_SOCKET_DESTROY 2
typedef void (*CRSocketCallbackProc)(int mode, int socket);
extern DECLEXPORT(void) crRegisterSocketCallback(int mode, CRSocketCallbackProc proc);
#ifdef __cplusplus
}
#endif
#endif /* CR_NET_H */
|