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