vol: Add timeouts to SYNC server select() calls
[openafs.git] / src / vol / daemon_com.h
1 /*
2  * Copyright 2006-2008, Sine Nomine Associates and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #ifndef _AFS_VOL_DAEMON_COM_H
11 #define _AFS_VOL_DAEMON_COM_H 1
12
13 /*
14  * SYNC protocol constants
15  */
16
17 /* SYNC protocol command codes
18  *
19  * command codes 0-65535 are reserved for
20  * global SYNC package command codes
21  */
22 #define SYNC_COM_CODE_USER_BASE 65536
23 #define SYNC_COM_CODE_DECL(code) (SYNC_COM_CODE_USER_BASE+(code))
24
25 /**
26  * general command codes.
27  */
28 enum SYNCOpCode {
29     SYNC_COM_CHANNEL_CLOSE    = 0,      /**< request sync channel shutdown */
30     SYNC_OP_CODE_END
31 };
32
33
34 /* SYNC protocol response codes
35  *
36  * response codes 0-65535 are reserved for
37  * global SYNC package response codes
38  */
39 #define SYNC_RES_CODE_USER_BASE 65536
40 #define SYNC_RES_CODE_DECL(code) (SYNC_RES_CODE_USER_BASE+(code))
41
42 /**
43  * general response codes.
44  */
45 enum SYNCReasonCode {
46     SYNC_OK                   = 0,  /**< sync call returned ok */
47     SYNC_DENIED               = 1,  /**< sync request denied by server */
48     SYNC_COM_ERROR            = 2,  /**< sync protocol communicaions error */
49     SYNC_BAD_COMMAND          = 3,  /**< sync command code not implemented by server */
50     SYNC_FAILED               = 4,  /**< sync server-side procedure failed */
51     SYNC_RESPONSE_CODE_END
52 };
53
54 /* SYNC protocol reason codes
55  *
56  * reason codes 0-65535 are reserved for
57  * global SYNC package reason codes
58  */
59 #define SYNC_REASON_CODE_USER_BASE 65536
60 #define SYNC_REASON_CODE_DECL(code) (SYNC_REASON_CODE_USER_BASE+(code))
61
62 /* general reason codes */
63 #define SYNC_REASON_NONE                 0
64 #define SYNC_REASON_MALFORMED_PACKET     1   /**< command packet was malformed */
65 #define SYNC_REASON_NOMEM                2   /**< sync server out of memory */
66 #define SYNC_REASON_ENCODING_ERROR       3
67 #define SYNC_REASON_PAYLOAD_TOO_BIG      4   /**< payload too big for response packet buffer */
68
69 /* SYNC protocol flags
70  *
71  * flag bits 0-7 are reserved for
72  * global SYNC package flags
73  */
74 #define SYNC_FLAG_CODE_USER_BASE 8
75 #define SYNC_FLAG_CODE_DECL(code) (1 << (SYNC_FLAG_CODE_USER_BASE+(code)))
76
77 /* general flag codes */
78 #define SYNC_FLAG_CHANNEL_SHUTDOWN   0x1
79 #define SYNC_FLAG_DAFS_EXTENSIONS    0x2   /* signal that other end of socket is compiled
80                                             * with demand attach extensions */
81
82 /* SYNC protocol response buffers */
83 #define SYNC_PROTO_MAX_LEN     768  /* maximum size of sync protocol message */
84
85 /* use a large type to get proper buffer alignment so we can safely cast the pointer */
86 #define SYNC_PROTO_BUF_DECL(buf) \
87     afs_int64 _##buf##_l[SYNC_PROTO_MAX_LEN/sizeof(afs_int64)]; \
88     char * buf = (char *)(_##buf##_l)
89
90 #ifdef AFS_LINUX26_ENV
91 /* Some Linux kernels have a bug where we are not woken up immediately from a
92  * select() when data is available. Work around this by having a low select()
93  * timeout, so we don't hang in those situations. */
94 # define SYNC_SELECT_TIMEOUT 10
95 #else
96 # define SYNC_SELECT_TIMEOUT 86400
97 #endif
98
99 #ifdef USE_UNIX_SOCKETS
100 #include <afs/afsutil.h>
101 #include <sys/un.h>
102 #define SYNC_SOCK_DOMAIN AF_UNIX
103 typedef struct sockaddr_un SYNC_sockaddr_t;
104 #else  /* USE_UNIX_SOCKETS */
105 #define SYNC_SOCK_DOMAIN AF_INET
106 typedef struct sockaddr_in SYNC_sockaddr_t;
107 #endif /* USE_UNIX_SOCKETS */
108
109 /**
110  * sync server endpoint address.
111  */
112 typedef struct SYNC_endpoint {
113     int domain;     /**< socket domain */
114     afs_uint16 in;  /**< localhost ipv4 tcp port number */
115     char * un;      /**< unix domain socket filename (not a full path) */
116 } SYNC_endpoint_t;
117
118 #define SYNC_ENDPOINT_DECL(in_port, un_path) \
119     { SYNC_SOCK_DOMAIN, in_port, un_path }
120
121
122 /**
123  * SYNC server state structure.
124  */
125 typedef struct SYNC_server_state {
126     osi_socket fd;              /**< listening socket descriptor */
127     SYNC_endpoint_t endpoint;   /**< server endpoint address */
128     afs_uint32 proto_version;   /**< our protocol version */
129     int bind_retry_limit;       /**< upper limit on times to retry socket bind() */
130     int listen_depth;           /**< socket listen queue depth */
131     char * proto_name;          /**< sync protocol associated with this conn */
132     SYNC_sockaddr_t addr;       /**< server listen socket sockaddr */
133     afs_uint32 pkt_seq;         /**< packet xmit sequence counter */
134     afs_uint32 res_seq;         /**< response xmit sequence counter */
135 } SYNC_server_state_t;
136
137 /**
138  * SYNC client state structure.
139  */
140 typedef struct SYNC_client_state {
141     osi_socket fd;              /**< client socket descriptor */
142     SYNC_endpoint_t endpoint;   /**< address of sync server */
143     afs_uint32 proto_version;   /**< our protocol version */
144     int retry_limit;            /**< max number of times for SYNC_ask to retry */
145     afs_int32 hard_timeout;     /**< upper limit on time to keep trying */
146     char * proto_name;          /**< sync protocol associated with this conn */
147     byte fatal_error;           /**< nonzero if fatal error on this client conn */
148     afs_uint32 pkt_seq;         /**< packet xmit sequence counter */
149     afs_uint32 com_seq;         /**< command xmit sequence counter */
150 } SYNC_client_state;
151
152 /* wire types */
153 /**
154  * on-wire command packet header.
155  */
156 typedef struct SYNC_command_hdr {
157     afs_uint32 proto_version;   /**< sync protocol version */
158     afs_uint32 pkt_seq;         /**< packet sequence number */
159     afs_uint32 com_seq;         /**< command sequence number */
160     afs_int32 programType;      /**< type of program issuing the request */
161     afs_int32 pid;              /**< pid of requestor */
162     afs_int32 tid;              /**< thread id of requestor */
163     afs_int32 command;          /**< request type */
164     afs_int32 reason;           /**< reason for request */
165     afs_uint32 command_len;     /**< entire length of command */
166     afs_uint32 flags;           /**< miscellanous control flags */
167 } SYNC_command_hdr;
168
169 /**
170  * on-wire response packet header.
171  */
172 typedef struct SYNC_response_hdr {
173     afs_uint32 proto_version;   /**< sync protocol version */
174     afs_uint32 pkt_seq;         /**< packet sequence number */
175     afs_uint32 com_seq;         /**< in response to com_seq... */
176     afs_uint32 res_seq;         /**< response sequence number */
177     afs_uint32 response_len;    /**< entire length of response */
178     afs_int32 response;         /**< response code */
179     afs_int32 reason;           /**< reason for response */
180     afs_uint32 flags;           /**< miscellanous control flags */
181 } SYNC_response_hdr;
182
183
184 /* user-visible types */
185 typedef struct SYNC_command {
186     SYNC_command_hdr hdr;
187     struct {
188         afs_uint32 len;
189         void * buf;
190     } payload;
191     afs_int32 recv_len;
192 } SYNC_command;
193
194 typedef struct SYNC_response {
195     SYNC_response_hdr hdr;
196     struct {
197         afs_uint32 len;
198         void * buf;
199     } payload;
200     afs_int32 recv_len;
201 } SYNC_response;
202
203 /* general prototypes */
204 extern osi_socket SYNC_getSock(SYNC_endpoint_t * endpoint);
205 extern void SYNC_getAddr(SYNC_endpoint_t * endpoint, SYNC_sockaddr_t * addr);
206
207 /* client-side prototypes */
208 extern afs_int32 SYNC_ask(SYNC_client_state *, SYNC_command * com, SYNC_response * res);
209 extern int SYNC_connect(SYNC_client_state *);             /* setup the channel */
210 extern int SYNC_disconnect(SYNC_client_state *);          /* just close the socket */
211 extern afs_int32 SYNC_closeChannel(SYNC_client_state *);  /* do a graceful channel close */
212 extern int SYNC_reconnect(SYNC_client_state *);           /* do a reconnect after a protocol error, or from a forked child */
213
214 /* server-side prototypes */
215 extern int SYNC_getCom(SYNC_server_state_t *, osi_socket fd, SYNC_command * com);
216 extern int SYNC_putRes(SYNC_server_state_t *, osi_socket fd, SYNC_response * res);
217 extern int SYNC_verifyProtocolString(char * buf, size_t len);
218 extern void SYNC_cleanupSock(SYNC_server_state_t * state);
219 extern int SYNC_bindSock(SYNC_server_state_t * state);
220
221 #endif /* _AFS_VOL_DAEMON_COM_H */