1 /*
2  *  Rsrv.h : constants and macros for Rserve client/server architecture
3  *  Copyright (C) 2002-13 Simon Urbanek
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU Lesser General Public License as published
7  *  by the Free Software Foundation; version 2.1 of the License
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Note: This header file is licensed under LGPL to allow other
19  *        programs to use it under LGPL. Rserve itself is licensed under GPL.
20  *
21  *  $Id$
22  */
23 
24 /* external defines:
25    MAIN - should be defined in just one file that will contain the fn definitions and variables
26  */
27 
28 #ifndef __RSRV_H__
29 #define __RSRV_H__
30 
31 #ifndef NO_CONFIG_H
32 #include "config.h"
33 #endif
34 
35 #define RSRV_VER 0x010801 /* Rserve v1.8-1 */
36 
37 #define default_Rsrv_port 6311
38 
39 /* Rserve communication is done over any reliable connection-oriented
40    protocol (usually TCP/IP or local sockets). After the connection is
41    established, the server sends 32 bytes of ID-string defining the
42    capabilities of the server. Each attribute of the ID-string is 4 bytes
43    long and is meant to be user-readable (i.e. don't use special characters),
44    and it's a good idea to make "\r\n\r\n" the last attribute
45 
46    the ID string must be of the form:
47 
48    [0] "Rsrv" - R-server ID signature
49    [4] "0100" - version of the R server
50    [8] "QAP1" - protocol used for communication (here Quad Attributes Packets v1)
51    [12] any additional attributes follow. \r\n<space> and '-' are ignored.
52 
53    optional attributes
54    (in any order; it is legitimate to put dummy attributes, like "----" or
55     "    " between attributes):
56 
57    "R151" - version of R (here 1.5.1)
58    "ARpt" - authorization required (here "pt"=plain text, "uc"=unix crypt,
59             "m5"=MD5)
60             connection will be closed if the first packet is not CMD_login.
61 	    if more AR.. methods are specified, then client is free to
62 	    use the one he supports (usually the most secure)
63    "K***" - key if encoded authentification is challenged (*** is the key)
64             for unix crypt the first two letters of the key are the salt
65 	    required by the server */
66 
67 /* QAP1 transport protocol header structure
68 
69    all int and double entries throughout the transfer are in
70    Intel-endianess format: int=0x12345678 -> char[4]=(0x78,0x56,x34,0x12)
71    functions/macros for converting from native to protocol format
72    are available below
73 
74    Please note also that all values muse be quad-aligned, i.e. the length
75    must be divisible by 4. This is automatically assured for int/double etc.,
76    but care must be taken when using strings and byte streams.
77 
78  */
79 
80 struct phdr {   /* always 16 bytes */
81 	int cmd;    /* command */
82 	int len;    /* length of the packet minus header (ergo -16) */
83 	int msg_id; /* message id (since 1.8) [WAS:data offset behind header (ergo usually 0)] */
84 	int res; /* high 32-bit of the packet length (since 0103
85 				and supported on 64-bit platforms only)
86 				aka "lenhi", but the name was not changed to
87 				maintain compatibility */
88 };
89 
90 /* each entry in the data section (aka parameter list) is preceded by 4 bytes:
91    1 byte : parameter type
92    3 bytes: length
93    parameter list may be terminated by 0/0/0/0 but doesn't have to since "len"
94    field specifies the packet length sufficiently (hint: best method for parsing is
95    to allocate len+4 bytes, set the last 4 bytes to 0 and trverse list of parameters
96    until (int)0 occurs
97 
98    since 0102:
99    if the 7-th bit (0x40) in parameter type is set then the length is encoded
100    in 7 bytes enlarging the header by 4 bytes.
101  */
102 
103 /* macros for handling the first int - split/combine (24-bit version only!) */
104 #define PAR_TYPE(X) ((X) & 255)
105 #define PAR_LEN(X) (((unsigned int)(X)) >> 8)
106 #define PAR_LENGTH PAR_LEN
107 #define SET_PAR(TY,LEN) ((((unsigned int) (LEN) & 0xffffff) << 8) | ((TY) & 255))
108 
109 #define CMD_STAT(X) (((X) >> 24)&127) /* returns the stat code of the response */
110 #define SET_STAT(X,s) ((X) | (((s) & 127) << 24)) /* sets the stat code */
111 
112 #define CMD_RESP 0x10000  /* all responses have this flag set */
113 
114 #define RESP_OK (CMD_RESP|0x0001) /* command succeeded; returned parameters depend
115 				     on the command issued */
116 #define RESP_ERR (CMD_RESP|0x0002) /* command failed, check stats code
117 				      attached string may describe the error */
118 
119 #define CMD_OOB  0x20000  /* out-of-band data - i.e. unsolicited messages */
120 #define OOB_SEND (CMD_OOB | 0x1000) /* OOB send - unsolicited SEXP sent from the R instance to the client. 12 LSB are reserved for application-specific code */
121 #define OOB_MSG  (CMD_OOB | 0x2000) /* OOB message - unsolicited message sent from the R instance to the client requiring a response. 12 LSB are reserved for application-specific code */
122 
123 #define IS_OOB_SEND(X)  (((X) & 0x0ffff000) == OOB_SEND)
124 #define IS_OOB_MSG(X)   (((X) & 0x0ffff000) == OOB_MSG)
125 #define OOB_USR_CODE(X) ((X) & 0xfff)
126 
127 /* flag for create_server: Use QAP object-cap mode */
128 #define SRV_QAP_OC 0x40
129 /* mask of all flags that are relevant to QAP (so they can be passed through) */
130 #define SRV_QAP_FLAGS (SRV_QAP_OC)
131 
132 /* stat codes; 0-0x3f are reserved for program specific codes - e.g. for R
133    connection they correspond to the stat of Parse command.
134    the following codes are returned by the Rserv itself
135 
136    codes <0 denote Rerror as provided by R_tryEval
137  */
138 #define ERR_auth_failed      0x41 /* auth.failed or auth.requested but no
139 				     login came. in case of authentification
140 				     failure due to name/pwd mismatch,
141 				     server may send CMD_accessDenied instead
142 				  */
143 #define ERR_conn_broken      0x42 /* connection closed or broken packet killed it */
144 #define ERR_inv_cmd          0x43 /* unsupported/invalid command */
145 #define ERR_inv_par          0x44 /* some parameters are invalid */
146 #define ERR_Rerror           0x45 /* R-error occured, usually followed by
147 				     connection shutdown */
148 #define ERR_IOerror          0x46 /* I/O error */
149 #define ERR_notOpen          0x47 /* attempt to perform fileRead/Write
150 				     on closed file */
151 #define ERR_accessDenied     0x48 /* this answer is also valid on
152 				     CMD_login; otherwise it's sent
153 				     if the server deosn;t allow the user
154 				     to issue the specified command.
155 				     (e.g. some server admins may block
156 				     file I/O operations for some users) */
157 #define ERR_unsupportedCmd   0x49 /* unsupported command */
158 #define ERR_unknownCmd       0x4a /* unknown command - the difference
159 				     between unsupported and unknown is that
160 				     unsupported commands are known to the
161 				     server but for some reasons (e.g.
162 				     platform dependent) it's not supported.
163 				     unknown commands are simply not recognized
164 				     by the server at all. */
165 /* The following ERR_.. exist since 1.23/0.1-6 */
166 #define ERR_data_overflow    0x4b /* incoming packet is too big.
167 				     currently there is a limit as of the
168 				     size of an incoming packet. */
169 #define ERR_object_too_big   0x4c /* the requested object is too big
170 				     to be transported in that way.
171 				     If received after CMD_eval then
172 				     the evaluation itself was successful.
173 				     optional parameter is the size of the object
174 				  */
175 /* since 1.29/0.1-9 */
176 #define ERR_out_of_mem       0x4d /* out of memory. the connection is usually
177 									 closed after this error was sent */
178 
179 /* since 0.6-0 */
180 #define ERR_ctrl_closed      0x4e /* control pipe to the master process is closed or broken */
181 
182 /* since 0.4-0 */
183 #define ERR_session_busy     0x50 /* session is still busy */
184 #define ERR_detach_failed    0x51 /* unable to detach seesion (cannot determine
185 									 peer IP or problems creating a listening
186 									 socket for resume) */
187 /* since 1.7 */
188 #define ERR_disabled         0x61 /* feature is disabled */
189 #define ERR_unavailable      0x62 /* feature is not present in this build */
190 #define ERR_cryptError       0x63 /* crypto-system error */
191 #define ERR_securityClose    0x64 /* server-initiated close due to security
192 									 violation (too many attempts, excessive
193 									 timeout etc.) */
194 
195 /* availiable commands */
196 
197 #define CMD_login        0x001 /* "name\npwd" : - */
198 #define CMD_voidEval     0x002 /* string : - */
199 #define CMD_eval         0x003 /* string | encoded SEXP : encoded SEXP */
200 #define CMD_shutdown     0x004 /* [admin-pwd] : - */
201 
202 /* security/encryption - all since 1.7-0 */
203 #define CMD_switch       0x005 /* string (protocol)  : - */
204 #define CMD_keyReq       0x006 /* string (request) : bytestream (key) */
205 #define CMD_secLogin     0x007 /* bytestream (encrypted auth) : - */
206 
207 #define CMD_OCcall       0x00f /* SEXP : SEXP  -- it is the only command
208 								  supported in object-capability mode
209 								  and it requires that the SEXP is a
210 								  language construct with OC reference
211 								  in the first position */
212 #define CMD_OCinit  0x434f7352 /* SEXP -- 'RsOC' - command sent from
213 								  the server in OC mode with the packet
214 								  of initial capabilities. */
215 
216 /* file I/O routines. server may answe */
217 #define CMD_openFile     0x010 /* fn : - */
218 #define CMD_createFile   0x011 /* fn : - */
219 #define CMD_closeFile    0x012 /* - : - */
220 #define CMD_readFile     0x013 /* [int size] : data... ; if size not present,
221 				  server is free to choose any value - usually
222 				  it uses the size of its static buffer */
223 #define CMD_writeFile    0x014 /* data : - */
224 #define CMD_removeFile   0x015 /* fn : - */
225 
226 /* object manipulation */
227 #define CMD_setSEXP      0x020 /* string(name), REXP : - */
228 #define CMD_assignSEXP   0x021 /* string(name), REXP : - ; same as setSEXP
229 								  except that the name is parsed */
230 
231 /* session management (since 0.4-0) */
232 #define CMD_detachSession    0x030 /* : session key */
233 #define CMD_detachedVoidEval 0x031 /* string : session key; doesn't */
234 #define CMD_attachSession    0x032 /* session key : - */
235 
236 /* control commands (since 0.6-0) - passed on to the master process */
237 /* Note: currently all control commands are asychronous, i.e. RESP_OK
238    indicates that the command was enqueued in the master pipe, but there
239    is no guarantee that it will be processed. Moreover non-forked
240    connections (e.g. the default debug setup) don't process any
241    control commands until the current client connection is closed so
242    the connection issuing the control command will never see its
243    result.
244 */
245 #define CMD_ctrl            0x40  /* -- not a command - just a constant -- */
246 #define CMD_ctrlEval        0x42  /* string : - */
247 #define CMD_ctrlSource      0x45  /* string : - */
248 #define CMD_ctrlShutdown    0x44  /* - : - */
249 
250 /* 'internal' commands (since 0.1-9) */
251 #define CMD_setBufferSize 0x081  /* [int sendBufSize]
252 				  this commad allow clients to request
253 				  bigger buffer sizes if large data is to be
254 				  transported from Rserve to the client.
255 				  (incoming buffer is resized automatically)
256 				 */
257 #define CMD_setEncoding   0x082  /* string (one of "native","latin1","utf8") : -; since 0.5-3 */
258 
259 /* special commands - the payload of packages with this mask does not contain defined parameters */
260 
261 #define CMD_SPECIAL_MASK 0xf0
262 
263 #define CMD_serEval      0xf5 /* serialized eval - the packets are raw serialized data without data header */
264 #define CMD_serAssign    0xf6 /* serialized assign - serialized list with [[1]]=name, [[2]]=value */
265 #define CMD_serEEval     0xf7 /* serialized expression eval - like serEval with one additional evaluation round */
266 
267 /* data types for the transport protocol (QAP1)
268    do NOT confuse with XT_.. values. */
269 
270 #define DT_INT        1  /* int */
271 #define DT_CHAR       2  /* char */
272 #define DT_DOUBLE     3  /* double */
273 #define DT_STRING     4  /* 0 terminted string */
274 #define DT_BYTESTREAM 5  /* stream of bytes (unlike DT_STRING may contain 0) */
275 #define DT_SEXP       10 /* encoded SEXP */
276 #define DT_ARRAY      11 /* array of objects (i.e. first 4 bytes specify how many
277 			    subsequent objects are part of the array; 0 is legitimate) */
278 #define DT_CUSTOM     32 /* custom types not defined in the protocol but used
279 							by applications */
280 #define DT_LARGE      64 /* new in 0102: if this flag is set then the length of the object
281 			    is coded as 56-bit integer enlarging the header by 4 bytes */
282 
283 /* XpressionTypes
284    REXP - R expressions are packed in the same way as command parameters
285    transport format of the encoded Xpressions:
286    [0] int type/len (1 byte type, 3 bytes len - same as SET_PAR)
287    [4] REXP attr (if bit 8 in type is set)
288    [4/8] data .. */
289 
290 #define XT_NULL          0  /* P  data: [0] */
291 #define XT_INT           1  /* -  data: [4]int */
292 #define XT_DOUBLE        2  /* -  data: [8]double */
293 #define XT_STR           3  /* P  data: [n]char null-term. strg. */
294 #define XT_LANG          4  /* -  data: same as XT_LIST */
295 #define XT_SYM           5  /* -  data: [n]char symbol name */
296 #define XT_BOOL          6  /* -  data: [1]byte boolean
297 							     (1=TRUE, 0=FALSE, 2=NA) */
298 #define XT_S4            7  /* P  data: [0] */
299 
300 #define XT_VECTOR        16 /* P  data: [?]REXP,REXP,.. */
301 #define XT_LIST          17 /* -  X head, X vals, X tag (since 0.1-5) */
302 #define XT_CLOS          18 /* P  X formals, X body  (closure; since 0.1-5) */
303 #define XT_SYMNAME       19 /* s  same as XT_STR (since 0.5) */
304 #define XT_LIST_NOTAG    20 /* s  same as XT_VECTOR (since 0.5) */
305 #define XT_LIST_TAG      21 /* P  X tag, X val, Y tag, Y val, ... (since 0.5) */
306 #define XT_LANG_NOTAG    22 /* s  same as XT_LIST_NOTAG (since 0.5) */
307 #define XT_LANG_TAG      23 /* s  same as XT_LIST_TAG (since 0.5) */
308 #define XT_VECTOR_EXP    26 /* s  same as XT_VECTOR (since 0.5) */
309 #define XT_VECTOR_STR    27 /* -  same as XT_VECTOR (since 0.5 but unused, use XT_ARRAY_STR instead) */
310 
311 #define XT_ARRAY_INT     32 /* P  data: [n*4]int,int,.. */
312 #define XT_ARRAY_DOUBLE  33 /* P  data: [n*8]double,double,.. */
313 #define XT_ARRAY_STR     34 /* P  data: string,string,.. (string=byte,byte,...,0) padded with '\01' */
314 #define XT_ARRAY_BOOL_UA 35 /* -  data: [n]byte,byte,..  (unaligned! NOT supported anymore) */
315 #define XT_ARRAY_BOOL    36 /* P  data: int(n),byte,byte,... */
316 #define XT_RAW           37 /* P  data: int(n),byte,byte,... */
317 #define XT_ARRAY_CPLX    38 /* P  data: [n*16]double,double,... (Re,Im,Re,Im,...) */
318 
319 #define XT_UNKNOWN       48 /* P  data: [4]int - SEXP type (as from TYPEOF(x)) */
320 /*                             |
321                                +--- interesting flags for client implementations:
322                                     P = primary type
323                                     s = secondary type - its decoding is identical to
324 									    a primary type and thus the client doesn't need to
325 										decode it separately.
326 									- = deprecated/removed. if a client doesn't need to
327 									    support old Rserve versions, those can be safely
328 										skipped.
329   Total primary: 4 trivial types (NULL, STR, S4, UNKNOWN) + 6 array types + 3 recursive types
330 */
331 
332 #define XT_LARGE         64 /* new in 0102: if this flag is set then the length of the object
333 			       is coded as 56-bit integer enlarging the header by 4 bytes */
334 #define XT_HAS_ATTR      128 /* flag; if set, the following REXP is the
335 				attribute */
336 /* the use of attributes and vectors results in recursive storage of REXPs */
337 
338 #define BOOL_TRUE  1
339 #define BOOL_FALSE 0
340 #define BOOL_NA    2
341 
342 #define GET_XT(X) ((X)&63)
343 #define GET_DT(X) ((X)&63)
344 #define HAS_ATTR(X) (((X)&XT_HAS_ATTR)>0)
345 #define IS_LARGE(X) (((X)&XT_LARGE)>0)
346 
347 #if defined sun && ! defined ALIGN_DOUBLES
348 #define ALIGN_DOUBLES
349 #endif
350 
351 /* this is the type used to calculate pointer distances */
352 /* note: we may want to use size_t or something more compatible */
353 typedef unsigned long rlen_t;
354 
355 #ifdef ULONG_MAX
356 #define rlen_max ULONG_MAX
357 #else
358 #ifdef __LP64__
359 #define rlen_max 0xffffffffffffffffL
360 #else
361 #define rlen_max 0xffffffffL
362 #endif /* __LP64__ */
363 #endif /* ULONG_MAX */
364 
365 
366 /* functions/macros to convert native endianess of int/double for transport
367    currently ony PPC style and Intel style are supported */
368 
369 /* Since 0.4-5 we no longer use configure-time endianness tests to allow cross-compilation.
370    Either BS_xx_ENDIAN constant is defined by configure and thus should be relied upon only if
371    the compiler contants don't work */
372 #if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN_
373 #define SWAPEND 1
374 #elif defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN_ || defined BS_LITTLE_ENDIAN
375 /* #undef SWAPEND */
376 #elif defined BS_BIG_ENDIAN
377 #define SWAPEND 1
378 #elif __ia64__ || __i386__ || __x86_64__ /* take a guess based on the architecture (Intel-like) */
379 #define __LITTLE_ENDIAN__ 1
380 #elif __ppc__ || __ppc64__ /* any ppc */
381 #define __BIG_ENDIAN__ 1
382 #define SWAPEND 1
383 #elif ! defined Win32 /* Windows is little-endian is most cases, anywhere else we're stuck */
384 #error "Cannot determine endianness. Make sure config.h is included or __{BIG|LITTLE}_ENDIAN__ is defined ."
385 #endif
386 
387 /* FIXME: all the mess below needs more efficient implementation - the current one is so messy to work around alignment problems on some platforms like Sun and HP 9000 */
388 
389 #ifdef SWAPEND  /* swap endianness - for PPC and co. */
390 #ifdef MAIN
itop(unsigned int i)391 unsigned int itop(unsigned int i) { char b[4]; b[0]=((char*)&i)[3]; b[3]=((char*)&i)[0]; b[1]=((char*)&i)[2]; b[2]=((char*)&i)[1]; return *((unsigned int*)b); }
dtop(double i)392 double dtop(double i) { char b[8]; b[0]=((char*)&i)[7]; b[1]=((char*)&i)[6]; b[2]=((char*)&i)[5]; b[3]=((char*)&i)[4]; b[7]=((char*)&i)[0]; b[6]=((char*)&i)[1]; b[5]=((char*)&i)[2]; b[4]=((char*)&i)[3]; return *((double*)b); }
fixdcpy(void * t,void * s)393 void fixdcpy(void *t,void *s) { int i=0; while (i<8) { ((char*)t)[7-i]=((char*)s)[i]; i++; } }
394 #else
395 extern unsigned int itop(unsigned int i);
396 extern double dtop(double i);
397 extern void fixdcpy(void *t,void *s);
398 #endif
399 #define ptoi(X) itop(X) /* itop*itop=id */
400 #define ptod(X) dtop(X)
401 #else
402 #define itop(X) (X)
403 #define ptoi(X) (X)
404 #define dtop(X) (X)
405 #define ptod(X) (X)
406 #define fixdcpy(T,S) ((double*)(T))[0]=((double*)(S))[0];
407 #define NATIVE_COPY 1
408 #endif
409 
410 #ifndef HAVE_CONFIG_H
411 /* this tiny function can be used to make sure that the endianess
412    is correct (it is not included if the package was configured with
413    autoconf since then it should be fine anyway) */
414 #ifdef MAIN
isByteSexOk()415 int isByteSexOk() {
416     int i;
417     i=itop(0x12345678);
418     return (*((char*)&i)==0x78);
419 }
420 #else
421 extern int isByteSexOk();
422 #endif
423 
424 #else
425 #define isByteSexOk 1
426 #endif
427 
428 /* STANDALONE_RSERVE takes precedence over RSERVE_PKG */
429 #if defined STANDALONE_RSERVE && defined RSERVE_PKG
430 #undef RSERVE_PKG
431 #endif
432 
433 #endif
434 
435 /*--- The following makes the indenting behavior of emacs compatible
436       with Xcode's 4/4 setting ---*/
437 /* Local Variables: */
438 /* indent-tabs-mode: t */
439 /* tab-width: 4 */
440 /* c-basic-offset: 4 */
441 /* End: */
442