root / trunk / code / projects / colonet / ColonetServer / ConnectionPool.cpp @ 59
History | View | Annotate | Download (14.3 KB)
1 | 11 | emarinel | /**
|
---|---|---|---|
2 | 29 | jknichel | * @file ConnectionPool.cpp
|
3 | *
|
||
4 | 11 | emarinel | * @author Jason Knichel
|
5 | * @date 7/22/07
|
||
6 | */
|
||
7 | |||
8 | #include <sys/select.h> |
||
9 | #include <ctype.h> |
||
10 | #include <errno.h> |
||
11 | #include <unistd.h> |
||
12 | #include <string.h> |
||
13 | #include <stdlib.h> |
||
14 | #include <stdio.h> |
||
15 | |||
16 | #include "includes/ConnectionPool.h" |
||
17 | #include "includes/client.h" |
||
18 | #include "../lib/colonet_defs.h" |
||
19 | |||
20 | 29 | jknichel | /**
|
21 | * @brief The default constructor for ConnectionPool
|
||
22 | */
|
||
23 | 11 | emarinel | ConnectionPool::ConnectionPool() { |
24 | max_file_descriptor = 0;
|
||
25 | next_available_slot = 0;
|
||
26 | number_clients_ready = 0;
|
||
27 | |||
28 | FD_ZERO(&ready_set); |
||
29 | FD_ZERO(&read_set); |
||
30 | FD_ZERO(&write_set); |
||
31 | |||
32 | memset(&client_file_descriptor_array, 0, sizeof(int)*MAX_CONNECTIONS); |
||
33 | memset(&read_buffer, 0, sizeof(char *)*MAX_CONNECTIONS); |
||
34 | memset(&read_buffer_size, 0, sizeof(int)*MAX_CONNECTIONS); |
||
35 | memset(&write_buffer, 0, sizeof(char *)*MAX_CONNECTIONS); |
||
36 | memset(&write_buffer_size, 0, sizeof(int)*MAX_CONNECTIONS); |
||
37 | } |
||
38 | |||
39 | 29 | jknichel | /**
|
40 | * @brief The destructor for ConnectionPool
|
||
41 | */
|
||
42 | 11 | emarinel | ConnectionPool::~ConnectionPool() { |
43 | } |
||
44 | |||
45 | 29 | jknichel | /**
|
46 | * @brief Adds a client to the connection pool
|
||
47 | *
|
||
48 | * @param client_file_descriptor The file descriptor to add to the connection pool
|
||
49 | *
|
||
50 | * @return 0 on success, negative error code on failure
|
||
51 | */
|
||
52 | 11 | emarinel | int ConnectionPool::add_client(int client_file_descriptor) { |
53 | if (client_file_descriptor < 0) { |
||
54 | return ERROR_INVALID_CLIENT_DESCRIPTOR;
|
||
55 | } |
||
56 | |||
57 | if (next_available_slot == MAX_CONNECTIONS) {
|
||
58 | return ERROR_TOO_MANY_CLIENTS;
|
||
59 | } |
||
60 | |||
61 | if (client_file_descriptor > max_file_descriptor) {
|
||
62 | max_file_descriptor = client_file_descriptor; |
||
63 | } |
||
64 | |||
65 | FD_SET(client_file_descriptor, &ready_set); |
||
66 | |||
67 | int next_slot = next_available_slot;
|
||
68 | |||
69 | client_file_descriptor_array[next_slot] = client_file_descriptor; |
||
70 | read_buffer[next_slot] = (char*) malloc(sizeof(char) * READ_BUFFER_SIZE); |
||
71 | if (!(read_buffer[next_slot])) {
|
||
72 | return ERROR_ALLOCATING_MEMORY;
|
||
73 | } |
||
74 | read_buffer_size[next_slot] = 0;
|
||
75 | write_buffer[next_slot] = (char *)malloc(sizeof(char) * WRITE_BUFFER_SIZE); |
||
76 | |||
77 | if (!(write_buffer[next_slot])) {
|
||
78 | free(read_buffer[next_slot]); |
||
79 | return ERROR_ALLOCATING_MEMORY;
|
||
80 | } |
||
81 | |||
82 | write_buffer_size[next_slot] = 0;
|
||
83 | |||
84 | next_available_slot++; |
||
85 | |||
86 | return 0; |
||
87 | } |
||
88 | |||
89 | 29 | jknichel | /**
|
90 | * @brief Removes a client from the connection pool
|
||
91 | *
|
||
92 | * @param The index in the pool of the client to remove
|
||
93 | *
|
||
94 | * @return 0 on success, negative error code on failure
|
||
95 | */
|
||
96 | 27 | jknichel | int ConnectionPool::remove_client(int pool_index) { |
97 | if (pool_index < 0 || pool_index >= next_available_slot) { |
||
98 | 11 | emarinel | return ERROR_INVALID_CLIENT_DESCRIPTOR;
|
99 | } |
||
100 | |||
101 | 27 | jknichel | int client_file_descriptor = client_file_descriptor_array[pool_index];
|
102 | 11 | emarinel | |
103 | 27 | jknichel | if (FD_ISSET(client_file_descriptor, &ready_set)) {
|
104 | FD_CLR(client_file_descriptor, &ready_set); |
||
105 | 11 | emarinel | } |
106 | 27 | jknichel | if (FD_ISSET(client_file_descriptor, &read_set)) {
|
107 | FD_CLR(client_file_descriptor, &read_set); |
||
108 | 11 | emarinel | } |
109 | 27 | jknichel | if (FD_ISSET(client_file_descriptor, &write_set)) {
|
110 | FD_CLR(client_file_descriptor, &write_set); |
||
111 | 11 | emarinel | } |
112 | |||
113 | 27 | jknichel | free(read_buffer[pool_index]); |
114 | free(write_buffer[pool_index]); |
||
115 | for (int j = pool_index; j < next_available_slot - 1; j++) { |
||
116 | client_file_descriptor_array[pool_index] = client_file_descriptor_array[pool_index+1];
|
||
117 | read_buffer[pool_index] = read_buffer[pool_index+1];
|
||
118 | read_buffer_size[pool_index] = read_buffer_size[pool_index+1];
|
||
119 | write_buffer[pool_index] = write_buffer[pool_index+1];
|
||
120 | write_buffer_size[pool_index] = write_buffer_size[pool_index+1];
|
||
121 | 11 | emarinel | } |
122 | next_available_slot--; |
||
123 | int temp_max_file_descriptor = 0; |
||
124 | |||
125 | for (int j = 0; j < next_available_slot; j++) { |
||
126 | if (client_file_descriptor_array[j] > temp_max_file_descriptor)
|
||
127 | temp_max_file_descriptor = client_file_descriptor_array[j]; |
||
128 | } |
||
129 | max_file_descriptor = temp_max_file_descriptor; |
||
130 | |||
131 | printf("Removing client.\n");
|
||
132 | |||
133 | return 0; |
||
134 | } |
||
135 | |||
136 | 29 | jknichel | /**
|
137 | * @brief Checks the status of the clients
|
||
138 | *
|
||
139 | * Sees is any clients are ready to read from their file descriptor or are
|
||
140 | * ready to write to their file descriptor.
|
||
141 | *
|
||
142 | * @param wireless A pointer to the wireless object
|
||
143 | *
|
||
144 | * @return 0 on success, negative error code on error
|
||
145 | */
|
||
146 | 11 | emarinel | //TODO: test that it drops commands properly if it gets sent too much data
|
147 | // do we want it to drop the data or drop the connection?
|
||
148 | 22 | jknichel | int ConnectionPool::check_clients(ColonetWireless * wireless) {
|
149 | 27 | jknichel | char temporary_buffer[READ_BUFFER_SIZE];
|
150 | char temporary_command_buffer[READ_BUFFER_SIZE+1]; |
||
151 | 11 | emarinel | int i;
|
152 | int client_file_descriptor;
|
||
153 | 27 | jknichel | int num_bytes_read;
|
154 | int length;
|
||
155 | 11 | emarinel | int sent;
|
156 | 27 | jknichel | int command_length;
|
157 | 11 | emarinel | |
158 | for (i = 0; i < next_available_slot; i++) { |
||
159 | client_file_descriptor = client_file_descriptor_array[i]; |
||
160 | |||
161 | if (FD_ISSET(client_file_descriptor, &read_set)) {
|
||
162 | 27 | jknichel | num_bytes_read = read(client_file_descriptor, temporary_buffer, READ_BUFFER_SIZE); |
163 | 11 | emarinel | |
164 | 27 | jknichel | if (num_bytes_read == 0 || (num_bytes_read == -1 && errno == ECONNRESET)) { |
165 | 11 | emarinel | remove_client(i); |
166 | i--; |
||
167 | continue;
|
||
168 | } |
||
169 | |||
170 | 27 | jknichel | while (num_bytes_read > 0) { |
171 | length = num_bytes_read; |
||
172 | 11 | emarinel | |
173 | 27 | jknichel | if (length + read_buffer_size[i] > READ_BUFFER_SIZE) {
|
174 | length = READ_BUFFER_SIZE - read_buffer_size[i]; |
||
175 | 11 | emarinel | } |
176 | |||
177 | 27 | jknichel | memcpy(read_buffer[i]+read_buffer_size[i], temporary_buffer, length); |
178 | read_buffer_size[i] += length; |
||
179 | num_bytes_read -= length; |
||
180 | 11 | emarinel | |
181 | 27 | jknichel | if (num_bytes_read > 0) { |
182 | memmove(temporary_buffer, temporary_buffer+length, READ_BUFFER_SIZE - length); |
||
183 | 11 | emarinel | } |
184 | |||
185 | printf("Read buffer is %s\n", read_buffer[i]);
|
||
186 | |||
187 | 27 | jknichel | char* newline_position;
|
188 | 11 | emarinel | |
189 | 27 | jknichel | while ((newline_position = strstr(read_buffer[i], "\n"))) { |
190 | 11 | emarinel | |
191 | //if no newline if found in the entire readbuffer (when its full),
|
||
192 | //toss out the command
|
||
193 | // because either the command being given is too long or someone is trying
|
||
194 | // to do something bad to the server
|
||
195 | //TODO: this is from before all this code was put in the loop. reconsider
|
||
196 | // how to check this error condition and do it elsewhere
|
||
197 | 27 | jknichel | if (!newline_position && (read_buffer_size[i] == READ_BUFFER_SIZE)) {
|
198 | 11 | emarinel | read_buffer_size[i] = 0;
|
199 | break;
|
||
200 | } |
||
201 | |||
202 | //if no newline is found then there is not a command in the buffer
|
||
203 | 27 | jknichel | if (!newline_position) {
|
204 | 11 | emarinel | break;
|
205 | } |
||
206 | |||
207 | 27 | jknichel | command_length = (newline_position - read_buffer[i])+1;
|
208 | 11 | emarinel | |
209 | //the newline was found in garbage in the currently not used portion
|
||
210 | // of the read buffer
|
||
211 | 27 | jknichel | if (command_length > read_buffer_size[i]) {
|
212 | 11 | emarinel | break;
|
213 | } |
||
214 | |||
215 | 27 | jknichel | memcpy(temporary_command_buffer, read_buffer[i], command_length); |
216 | //do command_length-1 to get rid of the newline terminating the command
|
||
217 | temporary_command_buffer[command_length-1] = '\0'; |
||
218 | 11 | emarinel | //did this because telnet was putting a \r\n on the end instead of just \n
|
219 | 27 | jknichel | if (isspace(temporary_command_buffer[command_length-2])) { |
220 | temporary_command_buffer[command_length-2] = '\0'; |
||
221 | 11 | emarinel | } |
222 | |||
223 | 27 | jknichel | memmove(read_buffer[i], read_buffer[i]+command_length, read_buffer_size[i] - command_length); |
224 | read_buffer_size[i] -= command_length; |
||
225 | 11 | emarinel | |
226 | 27 | jknichel | if (command_length > MAX_COMMAND_LEN) {
|
227 | 11 | emarinel | printf("The command was too long. Tossing command out.\n");
|
228 | break;
|
||
229 | } |
||
230 | |||
231 | 27 | jknichel | if (parse_command(temporary_command_buffer, i, wireless) < 0) { |
232 | 11 | emarinel | printf("There was an error parsing command\n");
|
233 | break;
|
||
234 | } |
||
235 | } |
||
236 | } |
||
237 | } |
||
238 | |||
239 | if (FD_ISSET(client_file_descriptor, &write_set)) {
|
||
240 | if (write_buffer_size[i] == 0) { |
||
241 | continue;
|
||
242 | } |
||
243 | |||
244 | sent = write(client_file_descriptor, write_buffer[i], write_buffer_size[i]); |
||
245 | memmove(write_buffer[i], write_buffer[i]+sent, WRITE_BUFFER_SIZE - sent); |
||
246 | write_buffer_size[i] -= sent; |
||
247 | } |
||
248 | } |
||
249 | |||
250 | return 0; |
||
251 | } |
||
252 | |||
253 | 29 | jknichel | /**
|
254 | * @brief Puts text into a write buffer that will be written to a client's file
|
||
255 | * descriptor sometime when the client is ready to write.
|
||
256 | *
|
||
257 | * @param pool_index Index in the pool of the client to write to
|
||
258 | * @param message The message to be written
|
||
259 | * @param length The length of the message
|
||
260 | *
|
||
261 | * @return 0 on success, negative error code on failure
|
||
262 | */
|
||
263 | 14 | jknichel | int ConnectionPool::write_to_client(int pool_index, char * message, int length) { |
264 | 22 | jknichel | if (pool_index < 0 || pool_index >= next_available_slot) { |
265 | return ERROR_INVALID_CLIENT_ID;
|
||
266 | } |
||
267 | |||
268 | if (!message) {
|
||
269 | return ERROR_INVALID_MESSAGE;
|
||
270 | } |
||
271 | |||
272 | if (length < 0) { |
||
273 | return ERROR_INVALID_MESSAGE_LENGTH;
|
||
274 | } |
||
275 | |||
276 | 34 | emarinel | if (length > (WRITE_BUFFER_SIZE-write_buffer_size[pool_index])) {
|
277 | //TODO: make this a logging statement instead of a print statement
|
||
278 | printf("There is not enough room in the write buffer to send the data to the client.\n");
|
||
279 | return ERROR_NOT_ENOUGH_ROOM;
|
||
280 | } |
||
281 | 11 | emarinel | |
282 | 14 | jknichel | memcpy(write_buffer[pool_index], message, length); |
283 | write_buffer_size[pool_index] += length; |
||
284 | |||
285 | return 0; |
||
286 | } |
||
287 | |||
288 | 29 | jknichel | /**
|
289 | * @brief Sets the socket to listen on
|
||
290 | *
|
||
291 | * @param listen_socket The socket to listen on
|
||
292 | *
|
||
293 | * @return void
|
||
294 | */
|
||
295 | 11 | emarinel | void ConnectionPool::set_listen_socket_in_ready_set(int listen_socket) { |
296 | 58 | jknichel | if (listen_socket < 0) |
297 | return;
|
||
298 | |||
299 | 11 | emarinel | FD_SET(listen_socket, &ready_set); |
300 | } |
||
301 | |||
302 | 29 | jknichel | /**
|
303 | * @brief Find out what file descriptors are ready to write to and read from
|
||
304 | *
|
||
305 | * @param listen_socket The socket to listen on
|
||
306 | * @param select_timeout The timeout for the select statement
|
||
307 | *
|
||
308 | * @return 0
|
||
309 | */
|
||
310 | 58 | jknichel | int ConnectionPool::perform_select(int listen_socket) { |
311 | 11 | emarinel | read_set = ready_set; |
312 | write_set = ready_set; |
||
313 | |||
314 | 58 | jknichel | struct timeval select_timeout;
|
315 | memset(&select_timeout, 0, sizeof(select_timeout)); |
||
316 | |||
317 | 11 | emarinel | //TODO(Jason): think about why I put this there
|
318 | if (max_file_descriptor < listen_socket)
|
||
319 | max_file_descriptor = listen_socket; |
||
320 | |||
321 | 58 | jknichel | number_clients_ready = select(max_file_descriptor+1, &(read_set), &(write_set), NULL, &select_timeout); |
322 | 11 | emarinel | |
323 | 59 | jknichel | if (number_clients_ready < 0) { |
324 | perror(__FUNCTION__); |
||
325 | } |
||
326 | |||
327 | 11 | emarinel | return 0; |
328 | } |
||
329 | |||
330 | int ConnectionPool::is_socket_ready_to_read(int socket) { |
||
331 | return FD_ISSET(socket, &read_set);
|
||
332 | } |
||
333 | |||
334 | int ConnectionPool::is_socket_ready_to_write(int socket) { |
||
335 | return FD_ISSET(socket, &write_set);
|
||
336 | } |
||
337 | |||
338 | int ConnectionPool::get_max_file_descriptor() {
|
||
339 | return max_file_descriptor;
|
||
340 | } |
||
341 | |||
342 | void ConnectionPool::set_max_file_descriptor(int new_max_file_descriptor) { |
||
343 | max_file_descriptor = new_max_file_descriptor; |
||
344 | } |
||
345 | |||
346 | int ConnectionPool::get_next_available_slot() {
|
||
347 | return next_available_slot;
|
||
348 | } |
||
349 | |||
350 | int ConnectionPool::get_number_clients_ready() {
|
||
351 | return number_clients_ready;
|
||
352 | } |
||
353 | |||
354 | void ConnectionPool::set_number_clients_ready(int new_number_clients_ready) { |
||
355 | number_clients_ready = new_number_clients_ready; |
||
356 | } |
||
357 | |||
358 | fd_set ConnectionPool::get_ready_set() { |
||
359 | return ready_set;
|
||
360 | } |
||
361 | |||
362 | fd_set ConnectionPool::get_read_set() { |
||
363 | return read_set;
|
||
364 | } |
||
365 | |||
366 | void ConnectionPool::set_read_set(fd_set new_set) {
|
||
367 | read_set = new_set; |
||
368 | } |
||
369 | |||
370 | fd_set ConnectionPool::get_write_set() { |
||
371 | return write_set;
|
||
372 | } |
||
373 | |||
374 | void ConnectionPool::set_write_set(fd_set new_set) {
|
||
375 | write_set = new_set; |
||
376 | } |
||
377 | |||
378 | 58 | jknichel | //TODO: write a function to write data into the write buffers (jason: what was this referring to?)
|
379 | 22 | jknichel | int ConnectionPool::parse_command(char* command, int pool_index, ColonetWireless * wireless) { |
380 | 11 | emarinel | char tokens[MAX_TOKENS][MAX_TOKEN_SIZE];
|
381 | 56 | jknichel | unsigned char int_tokens[MAX_TOKENS]; |
382 | 58 | jknichel | int number_tokens = 0; |
383 | char* end_pointer = NULL; |
||
384 | int command_id;
|
||
385 | 11 | emarinel | int i;
|
386 | 58 | jknichel | unsigned char arguments[PACKET_DATA_LEN]; |
387 | 11 | emarinel | |
388 | 58 | jknichel | memset(arguments, 1, PACKET_DATA_LEN);
|
389 | 11 | emarinel | |
390 | if (!command) {
|
||
391 | return -1; |
||
392 | } |
||
393 | |||
394 | if (pool_index < 0) { |
||
395 | return -1; |
||
396 | } |
||
397 | |||
398 | if (pool_index >= next_available_slot) {
|
||
399 | return -1; |
||
400 | } |
||
401 | |||
402 | 58 | jknichel | if ((number_tokens = tokenize_command(command, tokens)) < 0) { |
403 | 11 | emarinel | return -1; |
404 | } |
||
405 | |||
406 | //the 10 in the function call indicates number is base 10
|
||
407 | 58 | jknichel | command_id = strtol(tokens[0], &end_pointer, 10); |
408 | 11 | emarinel | |
409 | 58 | jknichel | if (!end_pointer || *end_pointer != '\0') { |
410 | 11 | emarinel | printf("There was an error converting first token into a number.\n");
|
411 | return -1; |
||
412 | } |
||
413 | |||
414 | 58 | jknichel | if (command_id == SEND_TO_ROBOT || REQUEST_FROM_ROBOT) {
|
415 | int number_int_tokens = number_tokens;
|
||
416 | 11 | emarinel | |
417 | /* Convert tokens to ints */
|
||
418 | 58 | jknichel | for (i = ROBOT_COMMAND_OFFSET; i < number_int_tokens; i++) {
|
419 | 11 | emarinel | int_tokens[i-ROBOT_COMMAND_OFFSET] = atoi(tokens[i]); |
420 | } |
||
421 | 58 | jknichel | if (command_id == REQUEST_FROM_ROBOT) {
|
422 | 11 | emarinel | if (i < MAX_TOKENS) {
|
423 | for (;i >= 4; i--) { |
||
424 | int_tokens[i] = int_tokens[i-1];
|
||
425 | } |
||
426 | int_tokens[3] = pool_index;
|
||
427 | 58 | jknichel | number_int_tokens++; |
428 | 11 | emarinel | } else {
|
429 | //TODO: send an error back to client here also
|
||
430 | fprintf(stderr, "Client attempted to request data from the robot but there was not enough room to put in the client's id.\n");
|
||
431 | return -1; |
||
432 | } |
||
433 | } |
||
434 | |||
435 | 58 | jknichel | /* Fill arguments buffer with arguments */
|
436 | for (i = ROBOT_COMMAND_LEN; i < number_int_tokens-ROBOT_COMMAND_OFFSET; i++) {
|
||
437 | arguments[i-ROBOT_COMMAND_LEN] = int_tokens[i]; |
||
438 | 11 | emarinel | } |
439 | |||
440 | /* Check the tokens */
|
||
441 | 58 | jknichel | if (check_tokens(int_tokens, number_int_tokens) < 0) { |
442 | 11 | emarinel | fprintf(stderr, "%s: Error - Invalid command/request.\n", __FUNCTION__);
|
443 | return 0; |
||
444 | } |
||
445 | |||
446 | /* Send packet to robot */
|
||
447 | 58 | jknichel | fprintf(stderr, "Calling wireless->send(%d, %d, %d, arguments)\n",
|
448 | 11 | emarinel | int_tokens[0], int_tokens[1], int_tokens[2]); |
449 | 58 | jknichel | wireless->send(int_tokens[0], int_tokens[1], int_tokens[2], arguments); |
450 | 11 | emarinel | } |
451 | |||
452 | return 0; |
||
453 | } |
||
454 | |||
455 | 55 | jknichel | /**
|
456 | * @brief Breaks a command up into tokens
|
||
457 | *
|
||
458 | * @param command The command to tokenize
|
||
459 | * @param tokens A two dimensional character array to store the tokens in
|
||
460 | *
|
||
461 | * @return 0 on success, negative error code on failure
|
||
462 | */
|
||
463 | 11 | emarinel | int ConnectionPool::tokenize_command(char* command, char tokens[MAX_TOKENS][MAX_TOKEN_SIZE]) { |
464 | 58 | jknichel | char* next_token = command;
|
465 | char* end_token = NULL; |
||
466 | int number_tokens = 0; |
||
467 | 11 | emarinel | |
468 | if (!command) {
|
||
469 | return -1; |
||
470 | } |
||
471 | |||
472 | 58 | jknichel | while ((end_token = strstr(next_token, " "))) { |
473 | *end_token = '\0';
|
||
474 | 11 | emarinel | |
475 | 58 | jknichel | if (strlen(next_token) > MAX_TOKEN_SIZE-1) { |
476 | 11 | emarinel | return -1; |
477 | } |
||
478 | |||
479 | 58 | jknichel | strcpy(tokens[number_tokens], next_token); |
480 | 11 | emarinel | |
481 | 58 | jknichel | number_tokens++; |
482 | next_token = end_token + 1;
|
||
483 | 11 | emarinel | |
484 | 58 | jknichel | while (isspace(*next_token) && *next_token != '\0') { |
485 | next_token++; |
||
486 | 11 | emarinel | } |
487 | } |
||
488 | |||
489 | 58 | jknichel | if (end_token == NULL && *next_token != '\0') { |
490 | if (strlen(next_token) > MAX_TOKEN_SIZE-1) { |
||
491 | 11 | emarinel | return -1; |
492 | } |
||
493 | |||
494 | 58 | jknichel | strcpy(tokens[number_tokens], next_token); |
495 | 11 | emarinel | |
496 | 58 | jknichel | number_tokens++; |
497 | 11 | emarinel | } |
498 | |||
499 | 58 | jknichel | return number_tokens;
|
500 | 11 | emarinel | } |
501 | |||
502 | 55 | jknichel | /**
|
503 | * @brief checks a list of tokens to see if it's valid
|
||
504 | 11 | emarinel | *
|
505 | 55 | jknichel | * @param tokens The tokens to check
|
506 | 58 | jknichel | * @param number_tokens The number of tokens contained in the tokens parameter
|
507 | 55 | jknichel | *
|
508 | 11 | emarinel | * @return 0 if tokens is valid
|
509 | */
|
||
510 | 58 | jknichel | int ConnectionPool::check_tokens(unsigned char* tokens, int number_tokens) { |
511 | if (number_tokens > 3 + PACKET_DATA_LEN) { |
||
512 | 11 | emarinel | /* Too many tokens */
|
513 | return -1; |
||
514 | } |
||
515 | |||
516 | 58 | jknichel | if (number_tokens < 3) { |
517 | 11 | emarinel | /* Not enough tokens */
|
518 | return -1; |
||
519 | } |
||
520 | |||
521 | if (tokens[1] != COLONET_REQUEST && tokens[1] != COLONET_COMMAND) { |
||
522 | /* Invalid message type */
|
||
523 | return -1; |
||
524 | } |
||
525 | |||
526 | return 0; |
||
527 | } |