1 /*	$Id: transaction.h 20856 2012-01-23 12:06:27Z m-oki $	*/
2 
3 /*
4  * Copyright (c) 2012, Internet Initiative Japan, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef __TRANSACTION_TRANSACTION_H__
31 #define __TRANSACTION_TRANSACTION_H__
32 /*
33  * pm_type as each arms-message type.
34  * compatible with classic libarms protocol part.
35  *
36  *  type:         "hoge-start" or "hoge-done"
37  *  pm.pm_string: "hoge"
38  *  ARMS message: <hoge-start-request>, -start-req, -done-req, -done-res
39  */
40 #include <sys/types.h>
41 #include <sys/queue.h>
42 #include <sys/socket.h>
43 #include <openssl/ssl.h>
44 
45 #include <axp_extern.h>
46 #include <libarms_resource.h>
47 
48 struct arms_method;
49 struct arms_schedule;
50 
51 typedef struct tr_ctx {
52 	AXP *axp;	  /* must be axp_destroy before release transaction */
53 	void *arg;	  /* must be pm_release before release transaction */
54 	int parse_state;
55 	int read_done;
56 	int write_done;
57 	int pm_type;
58 	struct arms_method *pm;
59 	/* ARMS result (SA -> RS) */
60 	int result;
61 	/* ARMS result (RS -> SA) */
62 	int res_result;
63 	/* transaction id */
64 	int id;
65 } transaction_context_t;
66 typedef transaction_context_t tr_ctx_t;
67 
68 /*
69  * buffer memory chain for retransmit
70  */
71 struct mem_block {
72 	TAILQ_ENTRY(mem_block) next;
73 	int len;
74 	int wrote;
75 	char buf[8192];
76 	char nul;
77 };
78 
79 /*
80  * Transaction class.
81  */
82 typedef struct transaction {
83 	LIST_ENTRY(transaction) next;
84 	int num;
85 
86 	/* SSL data */
87 	SSL_CTX *ssl_ctx;
88 	SSL *ssl;
89 	int zero;
90 
91 	/* HTTP BASIC Authorizatoin data */
92 	const char *user;
93 	const char *passwd;
94 
95 	/*
96 	 * state:
97 	 *  - TR_REQUEST
98 	 *  - TR_RESPONSE
99 	 *  - TR_START_REQUSET
100 	 *  - TR_START_RESPONSE
101 	 *  - TR_DONE_REQUEST
102 	 *  - TR_DONE_RESPONSE
103 	 */
104 	int state;
105 	/*
106 	 * compatible struct.
107 	 */
108 	tr_ctx_t tr_ctx;
109 	/*
110 	 * parser and builder function.
111 	 */
112 	int (*parser)(struct transaction *, const char *, int);
113 	int (*builder)(struct transaction *, char *, int, int *);
114 
115 	/*
116 	 * message releated data (MALLOCED)
117 	 * freely used by parser and builder.
118 	 */
119 	void *data;
120 	int (*release_data)(struct transaction *);
121 
122 	/*
123 	 * retry related information (for http client)
124 	 *
125 	 *    for (retry = 0; retry <= retry_max; retry++)
126 	 *      for (cur_uri = 0; cur_uri < nuri; cur_uri++)
127 	 *	  acess uriinfo[cur_uri];
128 	 *	wait retry_interval**retry [sec]
129 	 */
130 #if CONF_MAX_LS_LIST > CONF_MAX_RS_LIST
131 #define MAX_URIINFO	CONF_MAX_LS_LIST
132 #else
133 #define MAX_URIINFO	CONF_MAX_RS_LIST
134 #endif
135 	char *uriinfo[MAX_URIINFO];/* XXX MAX_LS,MAX_RS */
136 	int cur_uri; /* counter */
137 	int nuri;
138 
139 	int retry; /* counter */
140 	int retry_max;
141 	int retry_interval;  /* base value */
142 	int retry_remaining; /* calculated interval */
143 
144 	TAILQ_HEAD(mem_list, mem_block) head;
145 	struct mem_block *block;
146 	int total; /* content length */
147 
148 	/* for configure.  rollback state. */
149 	int rollbacked;
150 
151 	/* for ssltunnel, chunk id */
152 	int chunk_id;
153 
154 	/* message read/write buffer */
155 	int len;
156 	char *wp;
157 	char buf[8192];
158 	char term;	/* always NUL */
159 
160 	/* for push-endpoint */
161 	char sa_address[128]; /* XXX */
162 	int sa_af;
163 } transaction;
164 
165 #if 0/*DEBUG*/
166 #define SET_TR_BUILDER(t, b) \
167  printf("SET_TR_BUILDER(%s:%d:%s) = " #b "\n",__FILE__,__LINE__,__func__);\
168  t->builder = b
169 #define SET_TR_PARSER(t, p) \
170  printf("SET_TR_PARSER(%s:%d:%s) = " #p "\n",__FILE__,__LINE__,__func__);\
171  t->parser = p
172 #else
173 #define SET_TR_BUILDER(t, b) \
174  t->builder = b
175 #define SET_TR_PARSER(t, p) \
176  t->parser = p
177 #endif
178 
179 #define TR_REQUEST	   1
180 #define TR_RESPONSE        2
181 #define TR_DIR_MASK        0xff
182 #define TR_DIR(state)      ((state) & TR_DIR_MASK)
183 
184 #define TR_LSPULL          (1<<8)
185 #define TR_RSPULL          (2<<8)
186 #define TR_PUSH_READY      (3<<8)
187 #define TR_START           (4<<8)
188 #define TR_DONE            (5<<8)
189 
190 #define TR_PULL_DONE       (6<<8)
191 #define TR_PUSH_WAIT       (7<<8)
192 #define TR_BOOT_FAIL       (8<<8)
193 #define TR_TERM            (9<<8)
194 #define TR_REBOOT          (10<<8)
195 
196 #define TR_METHOD_QUERY	   (11<<8)
197 #define TR_CONFIRM_START   (12<<8)
198 #define TR_CONFIRM_DONE    (13<<8)
199 
200 #define TR_TYPE_MASK       (0xff<<8)
201 #define TR_TYPE(state)     ((state) & TR_TYPE_MASK)
202 
203 #define TR_OUT(state) (state == TR_LSPULL_REQUEST || \
204 		       state == TR_RSPULL_REQUEST || \
205 		       state == TR_METHOD_QUERY_REQUEST || \
206 		       state == TR_CONFIRM_START_REQUEST || \
207 		       state == TR_CONFIRM_DONE_RESPONSE || \
208 		       state == TR_START_RESPONSE || \
209 		       state == TR_RESPONSE || \
210 		       state == TR_DONE_REQUEST)
211 
212 #define TR_LSPULL_REQUEST        (TR_LSPULL|TR_REQUEST)
213 #define TR_LSPULL_RESPONSE       (TR_LSPULL|TR_RESPONSE)
214 #define TR_RSPULL_REQUEST        (TR_RSPULL|TR_REQUEST)
215 #define TR_RSPULL_RESPONSE       (TR_RSPULL|TR_RESPONSE)
216 #define TR_PUSH_READY_REQUEST    (TR_PUSH_READY|TR_REQUEST)
217 #define TR_PUSH_READY_RESPONSE   (TR_PUSH_READY|TR_RESPONSE)
218 #define TR_METHOD_QUERY_REQUEST  (TR_METHOD_QUERY|TR_REQUEST)
219 #define TR_METHOD_QUERY_RESPONSE (TR_METHOD_QUERY|TR_RESPONSE)
220 #define TR_CONFIRM_START_REQUEST  (TR_CONFIRM_START|TR_REQUEST)
221 #define TR_CONFIRM_START_RESPONSE (TR_CONFIRM_START|TR_RESPONSE)
222 #define TR_CONFIRM_DONE_REQUEST  (TR_CONFIRM_DONE|TR_REQUEST)
223 #define TR_CONFIRM_DONE_RESPONSE (TR_CONFIRM_DONE|TR_RESPONSE)
224 #define TR_START_REQUEST         (TR_START|TR_REQUEST)
225 #define TR_START_RESPONSE        (TR_START|TR_RESPONSE)
226 #define TR_DONE_REQUEST          (TR_DONE|TR_REQUEST)
227 #define TR_DONE_RESPONSE         (TR_DONE|TR_RESPONSE)
228 
229 
230 enum { TR_RESERVE,
231        TR_HTTP_AUTH_ERROR,
232        TR_WANT_READ,
233        TR_READ_DONE,
234        TR_WANT_WRITE,
235        TR_WRITE_DONE,
236        TR_WANT_RETRY,
237        TR_WANT_ROLLBACK,
238        TR_WANT_STOP,
239        TR_PARSE_ERROR,
240        TR_FATAL_ERROR,
241 };
242 
243 LIST_HEAD(tr_list, transaction);
244 struct tr_list *get_tr_list(void);
245 
246 #ifndef HAVE_STRUCT_SOCKADDR_STORAGE
247 #define sockaddr_storage sockaddr_in
248 #define ss_family sin_family
249 #endif
250 
251 int arms_line_connect(arms_context_t *, int, int, struct timeval *);
252 int arms_line_disconnect(arms_context_t *, int, int, struct timeval *);
253 void arms_line_next(arms_context_t *, int);
254 
255 int new_ls_pull_transaction(arms_context_t *, const char *);
256 int new_rs_pull_transaction(arms_context_t *, const char *);
257 int new_push_ready_transaction(arms_context_t *, const char *);
258 int new_method_query_transaction(arms_context_t *, const char *);
259 int new_push_transaction(int, struct sockaddr_storage *, socklen_t,
260 			 const char *);
261 int new_confirm_start_transaction(arms_context_t *, const char *,
262 				  const char *, int);
263 
264 int arms_retry_wait(transaction *);
265 void arms_set_global_state(int);
266 int arms_get_global_state(void);
267 
268 int ssl_client_retry(struct arms_schedule *, transaction *);
269 void arms_transaction_setup(transaction *);
270 void arms_transaction_free(transaction *);
271 void arms_tr_reset_callback_state(transaction *);
272 void arms_tr_ctx_free(tr_ctx_t *);
273 
274 #endif /* __TRANSACTION_TRANSACTION_H__ */
275