1 /* SILC Buffer Stream tests */
3 #include "silcruntime.h"
9 SilcFSMEventStruct sema;
10 SilcFSMEventStruct s_sema;
11 SilcFSMEventStruct c_sema;
12 SilcFSMThreadStruct thread;
13 SilcNetListener server;
14 SilcStream client_stream;
17 SilcResult client_status;
18 SilcStream server_stream;
21 SilcResult server_status;
25 SILC_FSM_STATE(test_st_start);
26 SILC_FSM_STATE(test_st_second);
27 SILC_FSM_STATE(test_st_finish);
29 SILC_FSM_STATE(test_st_connect);
30 SILC_FSM_STATE(test_st_connected);
32 SILC_FSM_STATE(test_st_s_send_buffers);
33 SILC_FSM_STATE(test_st_s_receive_buffers);
34 SILC_FSM_STATE(test_st_c_send_buffers);
35 SILC_FSM_STATE(test_st_c_receive_buffers);
37 static void test_accept_connection(SilcResult status, SilcStream stream,
41 SILC_LOG_DEBUG(("Accepted new connection"));
42 f->client_status = status;
43 f->client_stream = stream;
44 SILC_FSM_EVENT_SIGNAL(&f->sema);
47 static void test_connected(SilcResult status, SilcStream stream,
51 SILC_LOG_DEBUG(("Connected to server"));
52 f->server_status = status;
53 f->server_stream = stream;
54 SILC_FSM_CALL_CONTINUE(&f->thread);
57 static void receive_s_buffer(SilcResult status, SilcStream stream,
58 SilcBuffer buffer, void *context)
61 SILC_LOG_DEBUG(("Received buffer"));
62 silc_buffer_free(buffer);
63 SILC_FSM_EVENT_SIGNAL(&f->s_sema);
66 static void receive_c_buffer(SilcResult status, SilcStream stream,
67 SilcBuffer buffer, void *context)
70 SILC_LOG_DEBUG(("Received buffer"));
71 silc_buffer_free(buffer);
72 SILC_FSM_EVENT_SIGNAL(&f->c_sema);
75 SILC_FSM_STATE(test_st_connect)
79 SILC_LOG_DEBUG(("test_st_connect"));
80 SILC_LOG_DEBUG(("Connecting to server"));
82 silc_fsm_next(fsm, test_st_connected);
83 SILC_FSM_CALL(silc_net_tcp_connect(NULL, "localhost", 5000,
84 silc_fsm_get_schedule(fsm),
88 SILC_FSM_STATE(test_st_connected)
91 const char *host, *ip;
94 SILC_LOG_DEBUG(("test_st_connected"));
96 if (f->server_status != SILC_OK) {
97 SILC_LOG_DEBUG(("Creating connection failed"));
98 return SILC_FSM_FINISH;
101 silc_socket_stream_get_info(f->server_stream, NULL, &host, &ip, &port);
102 SILC_LOG_DEBUG(("Connected to server %s, %s:%d", host, ip, port));
104 f->sbuf = silc_buffer_stream_create(f->server_stream,
105 receive_c_buffer, f);
107 silc_fsm_next(fsm, test_st_finish);
108 return SILC_FSM_CONTINUE;
111 silc_fsm_next(fsm, test_st_c_receive_buffers);
112 return SILC_FSM_CONTINUE;
115 SILC_FSM_STATE(test_st_start)
119 SilcUInt16 *ret_ports;
120 SilcUInt32 port_count;
122 SILC_LOG_DEBUG(("test_st_start"));
124 SILC_LOG_DEBUG(("Creating network listener to ports 2000, 3000 and 4000"));
128 f->server = silc_net_tcp_create_listener2(NULL, ports, 3, FALSE, TRUE, TRUE,
129 silc_fsm_get_schedule(fsm),
130 test_accept_connection, f);
132 /** Creating network listener failed */
133 SILC_LOG_DEBUG(("Listener creation failed"));
134 silc_fsm_next(fsm, test_st_finish);
135 return SILC_FSM_CONTINUE;
138 ret_ports = silc_net_listener_get_port(f->server, &port_count);
140 SILC_LOG_DEBUG(("Listener does not work"));
141 silc_fsm_next(fsm, test_st_finish);
142 return SILC_FSM_CONTINUE;
144 SILC_LOG_DEBUG(("Bound to port %d", ret_ports[0]));
145 SILC_LOG_DEBUG(("Bound to port %d", ret_ports[1]));
146 SILC_LOG_DEBUG(("Bound to port %d", ret_ports[2]));
147 silc_free(ret_ports);
149 /* Close this listener and create new one */
150 silc_net_close_listener(f->server);
152 SILC_LOG_DEBUG(("Creating network listener"));
153 f->server = silc_net_tcp_create_listener(NULL, 0, 5000, TRUE, TRUE,
154 silc_fsm_get_schedule(fsm),
155 test_accept_connection, f);
157 /** Creating network listener failed */
158 SILC_LOG_DEBUG(("Listener creation failed"));
159 silc_fsm_next(fsm, test_st_finish);
160 return SILC_FSM_CONTINUE;
163 /* Create thread to connect to the listener */
164 silc_fsm_thread_init(&f->thread, fsm, f, NULL, NULL, FALSE);
165 silc_fsm_start(&f->thread, test_st_connect);
167 /** Start waiting connection */
168 SILC_LOG_DEBUG(("Start waiting for incoming connections"));
169 silc_fsm_event_init(&f->sema, fsm);
170 silc_fsm_next(fsm, test_st_second);
171 return SILC_FSM_CONTINUE;
174 SILC_FSM_STATE(test_st_second)
177 const char *ip, *host;
180 SILC_LOG_DEBUG(("test_st_second"));
182 SILC_FSM_EVENT_WAIT(&f->sema);
184 if (f->client_status != SILC_OK) {
185 /** Accepting new connection failed */
186 SILC_LOG_DEBUG(("Accepting failed %d", f->client_status));
187 silc_fsm_next(fsm, test_st_finish);
188 return SILC_FSM_CONTINUE;
191 silc_socket_stream_get_info(f->client_stream, NULL, &host, &ip, &port);
192 SILC_LOG_DEBUG(("Accepted new connection %s, %s:%d", host, ip, port));
194 f->cbuf = silc_buffer_stream_create(f->client_stream,
195 receive_s_buffer, f);
197 silc_fsm_next(fsm, test_st_finish);
198 return SILC_FSM_CONTINUE;
201 silc_fsm_next(fsm, test_st_s_send_buffers);
202 return SILC_FSM_CONTINUE;
205 SILC_FSM_STATE(test_st_s_send_buffers)
211 SILC_LOG_DEBUG(("test_st_s_send_buffers"));
213 for (i = 0; i < 10; i++) {
214 buffer = silc_buffer_alloc_size(99 * (i + 1));
216 silc_fsm_next(fsm, test_st_finish);
217 return SILC_FSM_CONTINUE;
220 SILC_LOG_HEXDUMP(("Send buffer %d to client", i + 1),
221 silc_buffer_data(buffer), silc_buffer_len(buffer));
223 if (!silc_buffer_stream_send(f->cbuf, buffer)) {
224 silc_fsm_next(fsm, test_st_finish);
225 return SILC_FSM_CONTINUE;
228 silc_buffer_free(buffer);
231 silc_fsm_next(fsm, test_st_s_receive_buffers);
232 return SILC_FSM_CONTINUE;
235 SILC_FSM_STATE(test_st_s_receive_buffers)
239 SILC_LOG_DEBUG(("test_st_s_receive_buffers"));
241 SILC_FSM_EVENT_WAIT(&f->s_sema);
244 SILC_LOG_DEBUG(("Received buffer %d", f->s_num_buf));
245 if (f->s_num_buf < 10)
246 return SILC_FSM_CONTINUE;
248 /** Wait thread to terminate */
250 silc_fsm_next(fsm, test_st_finish);
251 return SILC_FSM_CONTINUE;
254 SILC_FSM_STATE(test_st_c_receive_buffers)
258 SILC_LOG_DEBUG(("test_st_c_receive_buffers"));
260 SILC_FSM_EVENT_WAIT(&f->c_sema);
263 SILC_LOG_DEBUG(("Received buffer %d", f->c_num_buf));
264 if (f->c_num_buf < 10)
265 return SILC_FSM_CONTINUE;
267 silc_fsm_next(fsm, test_st_c_send_buffers);
268 return SILC_FSM_CONTINUE;
271 SILC_FSM_STATE(test_st_c_send_buffers)
277 SILC_LOG_DEBUG(("test_st_c_send_buffers"));
279 for (i = 0; i < 10; i++) {
280 buffer = silc_buffer_alloc_size(13 * (i + 1));
284 SILC_LOG_HEXDUMP(("Send buffer %d to server", i + 1),
285 silc_buffer_data(buffer), silc_buffer_len(buffer));
287 if (!silc_buffer_stream_send(f->sbuf, buffer)) {
288 silc_fsm_next(fsm, test_st_finish);
289 return SILC_FSM_CONTINUE;
292 silc_buffer_free(buffer);
295 return SILC_FSM_FINISH;
298 SILC_FSM_STATE(test_st_finish)
302 SILC_LOG_DEBUG(("test_st_finish"));
305 silc_stream_destroy(f->sbuf);
307 silc_stream_destroy(f->cbuf);
308 if (f->server_stream) {
309 silc_stream_close(f->server_stream);
310 silc_stream_destroy(f->server_stream);
312 if (f->client_stream) {
313 silc_stream_close(f->client_stream);
314 silc_stream_destroy(f->client_stream);
317 SILC_LOG_DEBUG(("Closing network listener"));
318 silc_net_close_listener(f->server);
320 SILC_LOG_DEBUG(("Finish machine"));
321 return SILC_FSM_FINISH;
324 static void destructor(SilcFSM fsm, void *fsm_context,
325 void *destructor_context)
327 SILC_LOG_DEBUG(("FSM destructor, stopping scheduler"));
329 silc_schedule_stop(schedule);
332 int main(int argc, char **argv)
334 SilcBool success = FALSE;
338 if (argc > 1 && !strcmp(argv[1], "-d")) {
339 silc_log_debug(TRUE);
340 silc_log_debug_hexdump(TRUE);
341 silc_log_set_debug_string("*net*,*stream*,*errno*");
344 SILC_LOG_DEBUG(("Allocating scheduler"));
345 schedule = silc_schedule_init(0, NULL, NULL, NULL);
347 f = silc_calloc(1, sizeof(*f));
351 SILC_LOG_DEBUG(("Allocating FSM context"));
352 fsm = silc_fsm_alloc(f, destructor, NULL, schedule);
355 silc_fsm_start(fsm, test_st_start);
358 silc_fsm_event_init(&f->s_sema, fsm);
359 silc_fsm_event_init(&f->c_sema, fsm);
361 SILC_LOG_DEBUG(("Running scheduler"));
362 silc_schedule(schedule);
367 silc_schedule_uninit(schedule);
373 SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
374 fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");