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