]> git.evergreen-ils.org Git - Evergreen.git/blob - OpenSRF/src/router/router.c
fixed some a bug in jserver, added some debug lines
[Evergreen.git] / OpenSRF / src / router / router.c
1 #include "router.h"
2 #include <sys/types.h>
3 #include <signal.h>
4
5 #define ROUTER_MAX_MSGS_PER_PACKET 12
6 char* router_resource;
7 transport_router_registrar* routt;
8 void _build_trusted_sites( transport_router_registrar* router );
9
10
11 void sig_hup_handler( int a ) { 
12         router_registrar_free( routt ); 
13         config_reader_free();   
14         log_free();
15         free( router_resource );
16         exit(0); 
17 }
18
19
20 int main( int argc, char* argv[] ) {
21
22         if( argc < 2 ) {
23                 fatal_handler( "Usage: %s <path_to_config_file>", argv[0] );
24                 exit(0);
25         }
26
27         config_reader_init( "opensrf.router", argv[1] );        
28         if( conf_reader == NULL ) fatal_handler( "main(): Config is NULL" ); 
29
30         /* laod the config options */
31         char* server                    = config_value("opensrf.router", "//router/transport/server");
32         char* port                              = config_value("opensrf.router", "//router/transport/port");
33         char* username                  = config_value("opensrf.router", "//router/transport/username");
34         char* password                  = config_value("opensrf.router", "//router/transport/password");
35         router_resource         = config_value("opensrf.router", "//router/transport/resource");
36         char* con_timeout               = config_value("opensrf.router", "//router/transport/connect_timeout" );
37         char* max_retries               = config_value("opensrf.router", "//router/transport/max_reconnect_attempts" );
38         char* component         = config_value("opensrf.router", "//router/component" );
39
40
41         /* set up the logger */
42         char* level = config_value("opensrf.router","//log/level");
43         char* log_file = config_value("opensrf.router","//log/file");
44         int llevel = atoi(level);
45         fprintf(stderr, "Level %d; file %s\n", llevel, log_file );
46
47         if(!log_init( llevel, log_file )) 
48                 fprintf(stderr, "Unable to init logging, going to stderr...\n" );
49
50
51         free(level);
52         free(log_file);
53
54         fprintf(stderr, "Router connecting as \nserver: %s \nport: %s \nuser:%s \nresource:%s\n", 
55                         server, port, username, router_resource );
56
57         int iport                       = atoi( port );
58         int con_itimeout        = atoi( con_timeout );
59         int max_retries_        = atoi(max_retries);
60         int icomponent = 0;
61         if(component) 
62                 icomponent = atoi(component);
63
64         if( iport < 1 ) { 
65                 fatal_handler( "Port is negative or 0" );
66                 return 99;
67         }
68
69
70         /* build the router_registrar */
71         transport_router_registrar* router_registrar = 
72                 router_registrar_init( server, iport, username, password, router_resource, 0, con_itimeout, icomponent ); 
73
74         routt = router_registrar;
75
76         free(server);
77         free(port);
78         free(username);
79         free(password);
80         free(con_timeout);
81         free(max_retries);
82
83         signal(SIGHUP,sig_hup_handler);
84
85
86         int counter = 0;
87         /* wait for incoming... */
88         while( ++counter <= max_retries_ ) {
89
90                 /* connect to jabber */
91                 if( router_registrar_connect( router_registrar ) )  {
92                         info_handler( "Connected..." );
93                         fprintf(stderr, "- Connected -\n");
94                         counter = 0;
95                         listen_loop( router_registrar );
96                 } else  
97                         fatal_handler( "Could not connect to Jabber Server" );
98
99                 /* this should never happen */
100                 warning_handler( "Jabber server probably went away, attempting reconnect" );
101
102                 sleep(5);
103         }
104
105
106         router_registrar_free( router_registrar );
107         config_reader_free();   
108         return 1;
109
110 }
111
112 transport_router_registrar* router_registrar_init( char* server, 
113                 int port, char* username, char* password, 
114                 char* resource, int client_timeout, int con_timeout, int component ) {
115
116         if( server == NULL ) { return NULL; }
117         
118         /* allocate a new router_registrar object */
119         size_t size = sizeof( transport_router_registrar );
120         transport_router_registrar* router_registrar = (transport_router_registrar*) safe_malloc( size );
121
122         router_registrar->client_timeout        = client_timeout;
123         router_registrar->jabber = jabber_connect_init( server, port, username, password, resource, con_timeout, component );
124         _build_trusted_sites( router_registrar );
125         info_handler( "Trusted stuff %s, %s, %s", router_registrar->trusted_servers[0], 
126                 router_registrar->trusted_clients[0], router_registrar->trusted_clients[1] );
127         return router_registrar;
128
129 }
130
131 void _build_trusted_sites( transport_router_registrar* router ) {
132
133         router->trusted_servers = (char**) safe_malloc(sizeof(char**));
134         router->trusted_clients = (char**) safe_malloc(sizeof(char**));
135
136         *(router->trusted_servers) = (char*) safe_malloc(ROUTER_MAX_TRUSTED);
137         *(router->trusted_clients) = (char*) safe_malloc(ROUTER_MAX_TRUSTED);
138
139         int i = 0;
140         while( ++i ) {
141                 char* server = config_value("opensrf.router","//router/trusted_domains/server%d", i );
142                 if(server == NULL)
143                         break;
144                 
145                 router->trusted_servers[i-1] = server;
146         }
147
148         i = 0;
149         while( ++i ) {
150                 char* client = config_value( "opensrf.router","//router/trusted_domains/client%d", i );
151                 if(client == NULL)
152                         break;
153                 router->trusted_clients[i-1] = client;
154         }
155
156         if( router->trusted_servers[0] == NULL ||
157                         router->trusted_clients[0] == NULL )
158
159                 fatal_handler( "You must specify at least one trusted server and client in the config file");
160 }
161
162
163 jabber_connect* jabber_connect_init( char* server, 
164                 int port, char* username, char* password, char* resource, int connect_timeout, int component ) {
165
166         size_t len = sizeof(jabber_connect);
167         jabber_connect* jabber = (jabber_connect*) safe_malloc( len );
168
169         jabber->port                            = port;
170         jabber->connect_timeout = connect_timeout;
171
172         jabber->server                          = strdup(server);
173         jabber->username                        = strdup(username);
174         jabber->password                        = strdup(password);
175         jabber->resource                        = strdup(resource);
176
177         if( jabber->server == NULL || jabber->username == NULL ||
178                         jabber->password == NULL || jabber->resource == NULL ) {
179                 fatal_handler( "jabber_init(): Out of Memory" );
180                 return NULL;
181         }
182
183         /* build the transport client */
184         jabber->t_client = client_init( jabber->server, jabber->port, component );
185
186         return jabber;
187 }
188
189 /* connect the router_registrar to jabber */
190 int router_registrar_connect( transport_router_registrar* router ) {
191         return j_connect( router->jabber );
192 }
193
194 /* connect a jabber_connect object jabber */
195 int j_connect( jabber_connect* jabber ) {
196         if( jabber == NULL ) { return 0; }
197         return client_connect( jabber->t_client, 
198                         jabber->username, jabber->password, jabber->resource, 
199                         jabber->connect_timeout, AUTH_DIGEST );
200 }
201
202 int fill_fd_set( transport_router_registrar* router, fd_set* set ) {
203         
204         int max_fd;
205         FD_ZERO(set);
206
207         int router_fd = router->jabber->t_client->session->sock_obj->sock_fd;
208         max_fd = router_fd;
209         FD_SET( router_fd, set );
210
211         server_class_node* cur_node = router->server_class_list;
212         while( cur_node != NULL ) {
213                 int cur_class_fd = cur_node->jabber->t_client->session->sock_obj->sock_fd;
214                 if( cur_class_fd > max_fd ) 
215                         max_fd = cur_class_fd;
216                 FD_SET( cur_class_fd, set );
217                 cur_node = cur_node->next;
218         }
219
220         FD_CLR( 0, set );
221         return max_fd;
222 }
223
224
225 void listen_loop( transport_router_registrar* router ) {
226
227         if( router == NULL )
228                 return;
229
230         int select_ret;
231         int router_fd = router->jabber->t_client->session->sock_obj->sock_fd;
232         transport_message* cur_msg;
233
234         while(1) {
235
236                 fd_set listen_set;
237                 int max_fd = fill_fd_set( router, &listen_set );
238
239                 if( max_fd < 1 ) 
240                         fatal_handler( "fill_fd_set return bogus max_fd: %d", max_fd );
241
242                 int num_handled = 0;
243                 info_handler( "Going into select" );
244
245                 if( (select_ret=select(max_fd+ 1, &listen_set, NULL, NULL, NULL)) < 0 ) {
246
247                         warning_handler( "Select returned error %d", select_ret );
248                         warning_handler( "Select Error %d on fd %d", errno );
249                         perror( "Select Error" );
250                         warning_handler( "Errors: EBADF %d, EINTR %d, EINVAL %d, ENOMEM %d",
251                                         EBADF, EINTR, EINVAL, ENOMEM );
252                         continue;
253
254                 } else {
255
256                         info_handler( "Select returned %d", select_ret );
257                         
258                         if( FD_ISSET( router_fd, &listen_set ) ) {
259                                 cur_msg = client_recv( router->jabber->t_client, 1 );
260
261                                 /* We only process a message if we have some trusted servers and the current
262                                         message came from one of those servers */
263                                 if(cur_msg) {
264
265                                         if(router->trusted_servers && router->trusted_servers[0]) {
266
267                                                 int i = 0;
268                                                 int found = 0;
269         
270                                                 if( cur_msg->sender ) {
271
272                                                         int len = strlen(cur_msg->sender) + 1; /* there's no way it could be that big, but... */
273                                                         char server_buf[len];
274                                                         memset(server_buf,0,len);
275                                                         jid_get_domain( cur_msg->sender, server_buf );
276                                                         info_handler("Received top level message from %s", server_buf );
277                 
278                                                         while(1) {
279                                                                 if(router->trusted_servers[i] == NULL)
280                                                                         break;
281                                                                 if(!strcmp(router->trusted_servers[i], server_buf)) {
282                                                                         found = 1;
283                                                                         break;
284                                                                 }
285                                                                 i++;
286                                                         }
287                                                 }
288
289                                                 if(found)
290                                                         router_registrar_handle_msg( router, cur_msg );
291                                                 else
292                                                         warning_handler( "Received top level message from unpriveleged sender %s", cur_msg->sender );
293                                         }
294         
295                                         message_free( cur_msg );
296                                 }
297
298                                 if( ++num_handled == select_ret ) 
299                                         continue;
300                         }
301
302                         /* cycle through the children and find any whose fd's are ready for reading */
303                         server_class_node* cur_node = router->server_class_list;
304                         while( cur_node != NULL ) {
305                                 debug_handler( "Checking File Descriptor" );
306                                 int cur_fd = cur_node->jabber->t_client->session->sock_obj->sock_fd;
307
308                                 if( FD_ISSET(cur_fd, &listen_set) ) {
309                                         ++num_handled;
310                                         FD_CLR(cur_fd,&listen_set);
311
312                                         cur_msg = client_recv( cur_node->jabber->t_client, 1 );
313
314                                         if(cur_msg) {
315
316                                                 info_handler( "%s received from %s", cur_node->server_class, cur_msg->sender );
317                                                 int handle_ret = server_class_handle_msg( router, cur_node, cur_msg );
318         
319                                                 if( handle_ret == -1 ) {
320                                                         warning_handler( "server_class_handle_msg() returned -1" );
321                                                         cur_node = router->server_class_list; /*start over*/
322                                                         continue;
323         
324                                                 } else if( handle_ret == 0 ) {
325                                                         /* delete and continue */
326                                                         warning_handler( "server_class_handle_msg() returned 0" );
327                                                         //server_class_node* tmp_node = cur_node->next;
328                                                         remove_server_class( router, cur_node );        
329                                                         debug_handler( "Removed Server Class" );
330                                                         cur_node = router->server_class_list; /*start over*/
331                                                         //cur_node = tmp_node;
332                                                         continue;
333                                                 } 
334         
335                                                 info_handler( "%s handled message successfully", cur_node->server_class );
336                                                 /* dont free message here */
337                                                 if( num_handled == select_ret ) 
338                                                         break;
339                                         }
340
341                                 }
342
343                                 if( num_handled == select_ret ) 
344                                         break;
345
346                                 cur_node = cur_node->next;
347
348                         } /* cycling through the server_class list */
349
350                 } /* no select errors */
351         } 
352 }
353
354
355 /* determine where to route top level messages */
356 int router_registrar_handle_msg( transport_router_registrar* router_registrar, transport_message* msg ) {
357
358         info_handler( "Received class: %s : command %s ", msg->router_class, msg->router_command );
359
360         if( router_registrar == NULL || msg == NULL ) { return 0; }
361
362         if( msg->router_command == NULL || !strcmp(msg->router_command,"") ) {
363                 return router_registrar_handle_app_request( router_registrar, msg );
364         }
365
366         // user issued a ruoter query
367         /* a query command has router_command="query" and the actual query type
368                 is the content of the message */
369         if( !strcmp(msg->router_command,"query")) {
370                 info_handler( "Router received query command" );
371
372                 // user issues a servers query
373                 if( !strcmp(msg->body, "servers")) {
374
375                         info_handler( "Router received servers query command" );
376                         router_return_server_info( router_registrar, msg );
377                         return 1;
378                 }
379         }
380
381
382         info_handler("Looking for server_class_node %s...",msg->router_class);
383         server_class_node* active_class_node = find_server_class( router_registrar, msg->router_class );
384
385         if( active_class_node == NULL ) { 
386                 info_handler("Could not find server_class_node %s, creating one.",msg->router_class);
387
388                 /* there is no server_class for msg->router_class so we build it here */
389                 if( strcmp( msg->router_command, "register") == 0 ) {
390
391                         info_handler("Adding server_class_node for %s",msg->router_class);
392                         active_class_node = 
393                                 init_server_class( router_registrar, msg->sender, msg->router_class ); 
394
395                         if( active_class_node == NULL ) {
396                                 fatal_handler( "router_listen(): active_class_node == NULL for %s", msg->sender );
397                                 return 0;
398                         }
399
400                         if (router_registrar->server_class_list != NULL) {
401                                 active_class_node->next = router_registrar->server_class_list;
402                                 router_registrar->server_class_list->prev = active_class_node;
403                         }
404                         router_registrar->server_class_list = active_class_node;
405
406                         //spawn_server_class( (void*) active_class_node );
407
408                 } else {
409                         warning_handler( "router_register_handler_msg(): Bad Command [%s] for class [%s]",
410                                 msg->router_command, msg->router_class );
411                 }
412
413         } else if( strcmp( msg->router_command, "register") == 0 ) {
414                 /* there is a server_class for msg->router_class so we 
415                         need to either add a new server_node or update the existing one */
416
417                 
418                 server_node* s_node = find_server_node( active_class_node, msg->sender );
419
420                 if( s_node != NULL ) {
421                         s_node->available = 1;
422                         s_node->upd_time = time(NULL);
423                         info_handler( "Found matching registered server: %s. Updating.",
424                                         s_node->remote_id );
425                 } else {
426                         s_node = init_server_node( msg->sender );
427
428                         info_handler( "Adding server_node for: %s.", s_node->remote_id );
429
430                         if (s_node == NULL ) {
431                                 warning_handler( " Could not create new xerver_node for %s.",
432                                         msg->sender );
433                                 return 0;
434                         }
435
436                         s_node->next = active_class_node->current_server_node->next;
437                         s_node->prev = active_class_node->current_server_node;
438
439                         active_class_node->current_server_node->next->prev = s_node;
440                         active_class_node->current_server_node->next = s_node;
441                 }
442
443
444         } else if( strcmp( msg->router_command, "unregister") == 0 ) {
445
446                 if( ! unregister_server_node( active_class_node, msg->sender ) ) {
447                         remove_server_class( router_registrar, active_class_node );
448                         debug_handler( "Removed server class after final unregister");
449                 }
450
451         } else {
452                 warning_handler( "router_register_handler_msg(): Bad Command [%s] for class [%s]",
453                         msg->router_command, msg->router_class );
454         }
455
456         return 1;
457 }
458
459
460 /* removes a server class node from the top level router_registrar */
461 int unregister_server_node( server_class_node* active_class_node, char* remote_id ) {
462
463         server_node* d_node = find_server_node( active_class_node, remote_id );
464
465         if ( d_node != NULL ) {
466
467                 info_handler( "Removing server_node for: %s.", d_node->remote_id );
468
469                 if ( d_node->next == NULL ) {
470                         warning_handler( "NEXT is NULL in ring [%s] -- "
471                                 "THIS SHOULD NEVER HAPPEN",
472                                 d_node->remote_id );
473
474                 }
475                 
476                 if ( d_node->prev == NULL ) {
477                         warning_handler( "PREV is NULL in a ring [%s] -- "
478                                 "THIS SHOULD NEVER HAPPEN",
479                                 d_node->remote_id );
480
481                 }
482
483                 if ( d_node->next == d_node && d_node->prev == d_node) {
484                         info_handler( "Last node, setting ring to NULL: %s.",
485                                 d_node->remote_id );
486
487                         active_class_node->current_server_node = NULL;
488
489                         server_node_free( d_node );
490                         return 0;
491
492                 } else {
493                         info_handler( "Nodes remain, splicing: %s, %s",
494                                 d_node->prev->remote_id,
495                                 d_node->next->remote_id);
496
497                 info_handler( "d_node => %x, next => %x, prev => %x",
498                                         d_node, d_node->next, d_node->prev );
499
500
501                         d_node->prev->next = d_node->next;
502                         d_node->next->prev = d_node->prev;
503
504                         info_handler( "prev => %x, prev->next => %x, prev->prev => %x",
505                                 d_node->prev, d_node->prev->next, d_node->prev->prev );
506
507                         info_handler( "next => %x, next->next => %x, next->prev => %x",
508                                 d_node->next, d_node->next->next, d_node->next->prev );
509                                 
510                         if (active_class_node->current_server_node == d_node)
511                                 active_class_node->current_server_node = d_node->next;
512
513
514                         server_node_free( d_node );
515                 }
516         } 
517
518         return 1;
519 }
520
521 server_node * find_server_node ( server_class_node * class, const char * remote_id ) {
522
523         if ( class == NULL ) {
524                 warning_handler(" find_server_node(): bad arg!");
525                 return NULL;
526         }
527
528         server_node * start_node = class->current_server_node;
529         server_node * node = class->current_server_node;
530
531         do {
532                 if (node == NULL)
533                         return NULL;
534
535                 if ( strcmp(node->remote_id, remote_id) == 0 )
536                         return node;
537
538                 node = node->next;
539
540         } while ( node != start_node );
541
542         return NULL;
543 }
544
545 /* if we return -1, then we just deleted the server_class you were looking for
546         if we return 0, then some other error has occured
547         we return 1 otherwise */
548 int remove_server_class( transport_router_registrar* router, server_class_node* class ) {
549         if( class == NULL )
550                 return 0;
551
552         transport_message * msg = NULL;
553         while ( (msg = client_recv(class->jabber->t_client, 0)) != NULL ) {
554                 debug_handler( "Looping on messages to dead class" );
555                 if( server_class_handle_msg(router, class, msg) < 0 ) {
556                   debug_handler( "This class was freed by a recursive call, exiting 'remove_server_class'");
557                   //message_free(msg); - this will be freed by server_class_handle_msg
558                   debug_handler( "Message Freed");
559                   return -1;
560                 }
561                 message_free(msg);
562         }
563         
564
565         free( class->server_class );
566         class->server_class = NULL;
567
568         find_server_class( router, router_resource ); /* find deletes for us */
569         debug_handler( "Successfuly called 'find_server_class' on class to delete" );
570
571         if( router->server_class_list == NULL ) 
572                 return 0;
573         return 1;
574 }
575
576 server_class_node * find_server_class ( transport_router_registrar * router, const char * class_id ) {
577
578         if ( router == NULL ) {
579                 warning_handler(" find_server_class(): bad arg!");
580                 return NULL;
581         }
582
583         info_handler( "Finding server class for %s", class_id );
584         server_class_node * class = router->server_class_list;
585         server_class_node * dead_class = NULL;
586
587         while ( class != NULL ) {
588
589                 if ( class->server_class == NULL ) {
590                         info_handler( "Found an empty server class" );
591
592                         if ( class->prev != NULL ) {
593                                 class->prev->next = class->next;
594                                 if( class->next != NULL ) {
595                                         class->next->prev = class->prev;
596                                 }
597
598                         } else {
599                                 info_handler( "Empty class is the first on the list" );
600                                 if( class->next != NULL ) 
601                                         router->server_class_list = class->next;
602
603                                 else { /* we're the last class node in the class node list */
604                                         info_handler( "Empty class is the last on the list" );
605                                         server_class_node_free( router->server_class_list );
606                                         router->server_class_list = NULL;
607                                         break;
608                                 }
609                                         
610                         }
611
612                         dead_class = class;
613                         class = class->next;
614
615                         info_handler( "Tossing our dead class" );
616                         server_class_node_free( dead_class );
617
618                         if ( class == NULL )
619                                 return NULL;
620                 }
621
622                 if ( strcmp(class->server_class, class_id) == 0 )
623                         return class;
624                 info_handler( "%s != %s", class->server_class, class_id );
625
626                 class = class->next;
627         }
628
629         debug_handler( "Returning NULL from find_server_class()" );
630         return NULL;
631 }
632
633 /* builds a new server class and connects to the jabber server with the new resource */
634 server_class_node* init_server_class( 
635                 transport_router_registrar* router, char* remote_id, char* server_class ) {
636
637         size_t len = sizeof( server_class_node );
638         server_class_node* node = (server_class_node*) safe_malloc( len );
639
640         node->jabber = jabber_connect_init( router->jabber->server,
641                         router->jabber->port, router->jabber->username, 
642                         router->jabber->password, server_class, router->jabber->connect_timeout, router->component );
643
644
645
646         node->server_class = strdup( server_class );
647         if( server_class == NULL ) {
648                 fatal_handler( "imit_server_class(): out of memory for %s", server_class );
649                 return NULL;
650         }
651
652         info_handler( "Received class to init_server_class: %s", server_class );
653         node->current_server_node = init_server_node( remote_id );
654         if( node->current_server_node == NULL ) {
655                 fatal_handler( "init_server_class(): NULL server_node for %s", remote_id );
656                 return NULL;
657         }
658
659
660         if( ! j_connect( node->jabber ) ) {
661                 fatal_handler( "Unable to init server class %s", node->server_class );
662                 return NULL;
663         }
664
665         info_handler( "Jabber address in init for %s : address %x : username %s : resource %s", 
666                         node->server_class, node->jabber->t_client->session->sock_obj->sock_fd, 
667                         node->jabber->username,  node->jabber->resource );
668
669         return node;
670
671 }
672
673 /* builds a new server_node to be added to the ring of server_nodes */
674 server_node* init_server_node(  char* remote_id ) {
675
676         info_handler( "Initing server node for %s", remote_id );
677         server_node* current_server_node;
678         size_t size = sizeof( server_node);
679         current_server_node = (server_node*) safe_malloc( size );
680
681         current_server_node->remote_id = strdup(remote_id);
682         if( current_server_node->remote_id == NULL ) {
683                 fatal_handler("init_server_class(): Out of Memory for %s", remote_id );
684                 return NULL;
685         }
686         
687         current_server_node->reg_time = time(NULL);     
688         current_server_node->available = 1;
689         current_server_node->next = current_server_node;
690         current_server_node->prev = current_server_node;
691
692
693         return current_server_node;
694
695 }
696
697 int  server_class_handle_msg( transport_router_registrar* router, 
698                 server_class_node* s_node, transport_message* msg ) {
699
700         if( s_node->current_server_node == NULL ) {
701                 /* return error to client ??!*/
702                 /* WE have no one to send the message to */
703                 warning_handler( "We no longer have any servers for %s : " 
704                                 "no one to send the message to. Sending error message to %s", s_node->server_class, msg->sender );
705                 free( msg->recipient );  
706
707                 char* rec = strdup( msg->sender );
708                 if( rec == NULL ) {
709                         fatal_handler( "class msg_handler: out of memory");
710                         return 0;
711                 }
712
713                 info_handler( "Building error message to return for %s", s_node->server_class);
714                 msg->recipient = rec;
715                 set_msg_error(msg, "cancel", 501);
716
717                 client_send_message( s_node->jabber->t_client, msg );
718                 message_free( msg );
719
720                 remove_server_class( router, s_node );
721                 debug_handler( "Successfully removed server class" ); 
722
723                 return -1;
724         }
725
726         info_handler( "[%s] Received \nfrom: %s \nto: %s", 
727                         s_node->server_class, msg->sender, msg->recipient );
728
729         if( msg->is_error ) {
730                 warning_handler( "We've received an error message type: %s : code: %d", 
731                                 msg->error_type, msg->error_code );
732
733                 if( strcmp( msg->error_type, "cancel" ) == 0 ) {
734                         warning_handler( "Looks like we've lost a server!" );
735                         server_node* dead_node = find_server_node( s_node, msg->sender );
736
737                         if( dead_node != NULL ) { 
738                                 //message_free( msg );
739                                 transport_message* tmp = dead_node->last_sent;
740
741                                 /* copy over last sent, it will be freed in the unregister function */
742                                 transport_message* tmp2 = message_init( tmp->body, tmp->subject, tmp->thread,
743                                                 tmp->recipient, tmp->sender );
744                                         
745                                 message_set_router_info( tmp2, tmp->router_from,  
746                                                 tmp->router_to, tmp->router_class, tmp->router_command, tmp->broadcast );
747
748                                 if( ! unregister_server_node( s_node, dead_node->remote_id ) ) { 
749                                         /* WE have no one to send the message to */
750                                         warning_handler( "We no longer have any servers for %s : " 
751                                                         "no one to send the message to.", s_node->server_class );
752                                         free( msg->recipient );  
753
754                                         char* rec = strdup( msg->router_from );
755                                         if( rec == NULL ) {
756                                                 fatal_handler( "class msg_handler: out of memory");
757                                                 return 0;
758                                         }
759
760                                         info_handler( "Building error message to return for %s", s_node->server_class);
761                                         msg->recipient = rec;
762                                         client_send_message( s_node->jabber->t_client, msg );
763                                         message_free( tmp2 );
764                                         message_free( msg );
765                                         return 0;
766
767                                 } else {
768                                         msg = tmp2;
769                                 }
770                         }
771                 }
772         } 
773
774
775         server_node* c_node = s_node->current_server_node->next;
776
777         /* not implemented yet */
778         while( ! c_node->available ) {
779                 if( c_node == s_node->current_server_node ) {
780                         warning_handler("No server_node's are available for %s", s_node->server_class );
781                         /* XXX send error message to client */
782                         return 0;
783                 }
784                 c_node = c_node->next;
785         }
786         s_node->current_server_node = c_node;
787
788         transport_message * new_msg =
789                 message_init(   msg->body, msg->subject, msg->thread, 
790                                 s_node->current_server_node->remote_id, msg->sender );
791
792         message_set_router_info( new_msg, msg->sender, NULL, NULL, NULL, 0 );
793
794         info_handler( "[%s] Routing message from [%s]\nto [%s]", s_node->server_class, msg->sender, new_msg->recipient );
795         //info_handler( "New Message Details: sender:%s recipient: %s \nbody: %s", 
796         //              new_msg->sender, new_msg->recipient, new_msg->body );
797
798         message_free( s_node->current_server_node->last_sent );
799         s_node->current_server_node->last_sent = msg;
800
801         if ( new_msg != NULL && client_send_message( s_node->jabber->t_client, new_msg ) ) {
802                 s_node->current_server_node->serve_count++;
803                 s_node->current_server_node->la_time = time(NULL);
804                 message_free( new_msg ); // XXX
805                 return 1;
806         }
807         message_free( new_msg ); // XXX
808
809         return 0;
810 }
811
812
813 int router_return_server_info( 
814                 transport_router_registrar* router, transport_message* msg ) {
815
816         server_class_node* cur_class = router->server_class_list;
817         growing_buffer* buffer = buffer_init(1024);
818
819         while( cur_class != NULL ) {
820
821                 server_node* start_node = cur_class->current_server_node;
822                 server_node* cur_node = start_node;
823                 if( cur_node == NULL ) continue; 
824
825                 do {
826
827                         char tbuf[124];
828                         memset(tbuf,0,124);
829                         sprintf( tbuf, "%d", (int)cur_node->reg_time ); 
830                         buffer_add( buffer, tbuf );
831                         buffer_add( buffer, " | ");
832
833                         memset(tbuf,0,124);
834                         sprintf( tbuf, "%d", (int)cur_node->upd_time ); 
835                         buffer_add( buffer, tbuf );
836                         buffer_add( buffer, " | ");
837
838                         memset(tbuf,0,124);
839                         sprintf( tbuf, "%d", (int)cur_node->la_time );  
840                         buffer_add( buffer, tbuf );
841                         buffer_add( buffer, " | ");
842
843
844                         char sbuf[64];
845                         memset(sbuf,0,64);
846                         sprintf(sbuf,"%d",cur_node->serve_count);
847
848                         buffer_add( buffer, "#" ); 
849                         buffer_add( buffer, sbuf ); 
850                         buffer_add( buffer, " | ");
851
852                         buffer_add( buffer, cur_class->server_class );
853                         buffer_add( buffer, " | ");
854
855                         buffer_add( buffer, cur_node->remote_id );
856
857                         buffer_add( buffer, "\n" );
858                         cur_node = cur_node->next;
859
860                 } while( cur_node != start_node );
861
862                 cur_class = cur_class->next;
863
864         }
865
866         info_handler( "Router returning servers query command: %s", buffer->buf );
867
868         transport_message* new_msg; 
869
870         if( buffer->buf == NULL || strlen(buffer->buf) == 0 )
871                 new_msg = message_init( "0", NULL, NULL, msg->sender, NULL );
872         else
873                 new_msg = message_init( buffer->buf, NULL, NULL, msg->sender, NULL );
874
875         client_send_message( router->jabber->t_client, new_msg );
876         message_free( new_msg );
877
878         return 1;
879
880 }
881
882 int router_registrar_handle_app_request( 
883                 transport_router_registrar* router, transport_message* msg ) {
884
885         osrf_message* arr[ROUTER_MAX_MSGS_PER_PACKET];
886         memset(arr, 0, ROUTER_MAX_MSGS_PER_PACKET );
887         int num_msgs = osrf_message_from_xml( msg->body, arr );
888
889         int i;
890         for( i = 0; i != num_msgs; i++ ) {
891
892                 osrf_message* omsg = arr[i];
893                 osrf_message* success = NULL;
894                 osrf_message** result = NULL;
895                 int num_responses;
896
897                 char* newxml =  osrf_message_to_xml(omsg);
898                 debug_handler( "Received potential app request from client:\n%s\n", newxml ); 
899                 free(newxml);
900
901                 if(omsg->m_type == CONNECT) {
902
903                         success = osrf_message_init( 
904                                         STATUS, omsg->thread_trace, omsg->protocol );
905
906                         osrf_message_set_status_info( 
907                                         success, "oilsConnectStatus", "Connection Successful", OSRF_STATUS_OK );
908
909                 } else if( omsg->m_type == REQUEST ) {
910
911                         result = router_registrar_process_app_request( router, omsg, &num_responses );
912                         
913                 } else if(omsg->m_type == DISCONNECT) { 
914                         success = NULL;
915
916                 } else {
917
918                         success = osrf_message_init( 
919                                         STATUS, omsg->thread_trace, omsg->protocol );
920                         osrf_message_set_status_info( 
921                                         success, "oilsMethodException", "Method Not Found", OSRF_STATUS_NOTFOUND );
922                 }
923
924
925                 /* now send our new message back */
926                 if(success) {
927
928                         char* xml =  osrf_message_to_xml(success);
929                         debug_handler( "Sending XML to client app request:\n%s\n", xml );
930                         transport_message* return_m = message_init( 
931                                 xml, "", msg->thread, msg->sender, "" );
932
933
934                         client_send_message(router->jabber->t_client, return_m);
935
936                         free(xml);
937                         osrf_message_free(success);
938                 } else if(result) {
939                         int i;
940
941                         for(i=0; i!= num_responses; i++){
942                                 char* xml =  osrf_message_to_xml(result[i]);
943                                 debug_handler( "Sending XML to client app request:\n%s\n", xml );
944                                 transport_message* return_m = message_init( 
945                                         xml, "", msg->thread, msg->sender, "" );
946
947
948                                 client_send_message(router->jabber->t_client, return_m);
949
950                                 free(xml);
951                                 osrf_message_free(result[i]);
952                         }
953
954                         osrf_message* complete = osrf_message_init(
955                                 STATUS, result[i-1]->thread_trace, result[i-1]->protocol );
956                         osrf_message_set_status_info( complete, 
957                                         "oilsConnectStatus", "Request Complete", OSRF_STATUS_COMPLETE );
958                         char* complete_xml = osrf_message_to_xml(complete);
959                         transport_message* complete_m = message_init( 
960                                         complete_xml, "", msg->thread, msg->sender, "" );
961                         client_send_message(router->jabber->t_client, complete_m);
962                         free(complete_xml);
963                         osrf_message_free(complete);
964                         free(result);
965
966                 }
967
968         }
969
970         return 1;
971
972 }
973
974
975
976 osrf_message** router_registrar_process_app_request( 
977                 transport_router_registrar* router, osrf_message* omsg, int* num_responses ) {
978
979
980         if( omsg->method_name == NULL )
981                 return NULL;
982
983         osrf_message** result_array = NULL;
984
985
986         debug_handler( "Received method from client: %s", omsg->method_name );
987
988         if(!strcmp(omsg->method_name,"opensrf.router.info.class.list")) {
989
990                 json* result_content = NULL;
991
992                 debug_handler("Processing opensrf.router.info.class.list request");
993
994                 result_content = json_object_new_array();
995                 server_class_node* cur_class = router->server_class_list;
996                 while( cur_class != NULL ) {
997
998                         debug_handler("Adding %s to request list", cur_class->server_class);
999
1000                         json_object_array_add(
1001                                         result_content, json_object_new_string(cur_class->server_class));
1002                         cur_class = cur_class->next;
1003                 }
1004                 result_array = safe_malloc(sizeof(osrf_message*));
1005                 *num_responses = 1;
1006
1007                 result_array[0] = osrf_message_init(
1008                         RESULT, omsg->thread_trace, omsg->protocol );
1009                 osrf_message_set_result_content( result_array[0], 
1010                                 json_object_to_json_string(result_content) );
1011                 json_object_put(result_content);
1012
1013
1014         } else if(!strcmp(omsg->method_name,"opensrf.router.info.stats")) {
1015
1016                 /* we have a server_class array which holds an array of node_objects.
1017                         each node_object contains an array of stats
1018                         */
1019
1020                 debug_handler("Processing opensrf.router.info.stats request");
1021
1022                 json* result_content = NULL;
1023                 result_content = json_object_new_object();
1024                 server_class_node* cur_class = router->server_class_list;
1025
1026                 while( cur_class != NULL ) {
1027
1028                         server_node* start_node = cur_class->current_server_node;
1029                         server_node* cur_node = start_node;
1030                         if( cur_node == NULL ) continue; 
1031
1032                         json* server_object = json_object_new_object();
1033
1034                         do {
1035
1036                                 json* node_stats_array = json_object_new_array();
1037
1038                                 json* json_reg_time = json_object_new_object();
1039                                 json_object_object_add( json_reg_time, "reg_time", 
1040                                                 json_object_new_int((int)cur_node->reg_time));
1041                                 json_object_array_add(  node_stats_array, json_reg_time );
1042
1043                                 json* json_upd_time = json_object_new_object();
1044                                 json_object_object_add( json_upd_time, "upd_time", 
1045                                                 json_object_new_int((int)cur_node->upd_time));
1046                                 json_object_array_add( node_stats_array, json_upd_time );
1047
1048                                 json* json_la_time = json_object_new_object();
1049                                 json_object_object_add( json_la_time, "la_time", 
1050                                                 json_object_new_int((int)cur_node->la_time));
1051                                 json_object_array_add( node_stats_array, json_la_time );
1052
1053                                 json* json_serve_count = json_object_new_object();
1054                                 json_object_object_add( json_serve_count, "serve_count", 
1055                                                 json_object_new_int((int)cur_node->serve_count));
1056                                 json_object_array_add( node_stats_array, json_serve_count );
1057
1058                                 json_object_object_add( server_object, cur_node->remote_id, node_stats_array );
1059
1060                                 cur_node = cur_node->next;
1061         
1062                         } while( cur_node != start_node );
1063
1064                         json_object_object_add( 
1065                                         result_content, cur_class->server_class, server_object ); 
1066         
1067                         cur_class = cur_class->next;
1068
1069                                 
1070                 }
1071
1072                 result_array = safe_malloc(sizeof(osrf_message*));
1073                 *num_responses = 1;
1074
1075                 result_array[0] = osrf_message_init(
1076                         RESULT, omsg->thread_trace, omsg->protocol );
1077                 osrf_message_set_result_content( result_array[0], 
1078                                 json_object_to_json_string(result_content) );
1079                 json_object_put(result_content);
1080
1081
1082         } else if(!strcmp(omsg->method_name,"opensrf.system.method.all")) {
1083
1084                 json* content = json_object_new_object();
1085                 json_object_object_add(content, "api_level", json_object_new_string("1"));
1086                 json_object_object_add(content, "api_name", json_object_new_string("opensrf.router.info.class.list"));
1087                 json_object_object_add(content, "server_class", json_object_new_string("router"));
1088                 json_object_object_add(content, "stream", json_object_new_string("0"));
1089
1090                 json* content2 = json_object_new_object();
1091                 json_object_object_add(content2, "api_level", json_object_new_string("1"));
1092                 json_object_object_add(content2, "api_name", json_object_new_string("opensrf.router.info.stats"));
1093                 json_object_object_add(content2, "server_class", json_object_new_string("router"));
1094                 json_object_object_add(content2, "stream", json_object_new_string("0"));
1095
1096                 json* content3 = json_object_new_object();
1097                 json_object_object_add(content3, "api_level", json_object_new_string("1"));
1098                 json_object_object_add(content3, "api_name", json_object_new_string("opensrf.system.method.all"));
1099                 json_object_object_add(content3, "server_class", json_object_new_string("router"));
1100                 json_object_object_add(content3, "stream", json_object_new_string("1"));
1101
1102                 result_array = safe_malloc(3*sizeof(osrf_message*));
1103                 *num_responses = 3;
1104
1105                 result_array[0] = osrf_message_init(
1106                         RESULT, omsg->thread_trace, omsg->protocol );
1107                 osrf_message_set_result_content( result_array[0], json_object_to_json_string(content) );
1108                 json_object_put(content);
1109
1110                 result_array[1] = osrf_message_init(
1111                         RESULT, omsg->thread_trace, omsg->protocol );
1112                 osrf_message_set_result_content( result_array[1], json_object_to_json_string(content2) );
1113                 json_object_put(content2);
1114
1115                 result_array[2] = osrf_message_init(
1116                         RESULT, omsg->thread_trace, omsg->protocol );
1117                 osrf_message_set_result_content( result_array[1], json_object_to_json_string(content3) );
1118                 json_object_put(content3);
1119
1120
1121         }
1122         
1123         
1124         if( result_array == NULL || result_array[0] == NULL ) 
1125                 return NULL;
1126
1127         return result_array;
1128 }
1129
1130
1131
1132
1133 int router_registrar_free( transport_router_registrar* router_registrar ) {
1134         if( router_registrar == NULL ) return 0;
1135         jabber_connect_free( router_registrar->jabber );
1136
1137         /* free the server_class list XXX */
1138         while( router_registrar->server_class_list != NULL ) {
1139                 remove_server_class(router_registrar, router_registrar->server_class_list);
1140                 debug_handler( "Removed server classes in registrar free");
1141         }
1142
1143         transport_router_registrar* router = router_registrar;
1144
1145         /* make this better 
1146         int i = 0;
1147         while(1) {
1148
1149                 if( router->trusted_servers[i] == NULL &&
1150                                 router->trusted_clients[i] == NULL )
1151                         break;
1152
1153                 if(router->trusted_servers[i] != NULL)
1154                         free(router->trusted_servers[i]);
1155                 if(router->trusted_clients[i] != NULL)
1156                         free(router->trusted_clients[i]);
1157                 i++;
1158         }
1159         */
1160
1161         free( router_registrar );
1162         return 1;
1163 }
1164
1165
1166 int server_class_node_free( server_class_node* node ) {
1167         if( node == NULL ) { return 0; }
1168         if( node->server_class != NULL ) 
1169                 free( node->server_class );
1170
1171         jabber_connect_free( node->jabber );
1172
1173         /* just in case, free the list */
1174         while( node->current_server_node != NULL ) {
1175                 unregister_server_node( node, node->current_server_node->remote_id );
1176         }
1177         free( node );
1178         return 1;
1179 }
1180
1181 int server_node_free( server_node* node ) {
1182         if( node == NULL ) { return 0; }
1183         message_free( node->last_sent );
1184         free( node->remote_id );
1185         free( node );
1186         return 1;
1187 }
1188
1189 int jabber_connect_free( jabber_connect* jabber ) {
1190         if( jabber == NULL ) { return 0; }
1191         client_free( jabber->t_client );
1192         free( jabber->username );
1193         free( jabber->password );
1194         free( jabber->resource );
1195         free( jabber->server );
1196         free( jabber );
1197         return 1;
1198 }
1199
1200