Moved silc_client_ch[u]mode[_char] to client library from silc/.
[silc.git] / apps / silcd / route.c
1 /*
2
3   route.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 2000 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /* 
21  * Route cache routines. Server uses these to route packets to specific
22  * routes. If route entry doesn't exist for a specific destination, server
23  * uses primary route (default route).
24  */
25 /*
26  * $Id$
27  * $Log$
28  * Revision 1.4  2000/07/12 05:59:41  priikone
29  *      Major rewrite of ID Cache system. Support added for the new
30  *      ID cache system. Major rewrite of ID List stuff on server.  All
31  *      SilcXXXList's are now called SilcXXXEntry's and they are pointers
32  *      by default. A lot rewritten ID list functions.
33  *
34  * Revision 1.3  2000/07/05 06:14:01  priikone
35  *      Global costemic changes.
36  *
37  * Revision 1.2  2000/07/04 08:30:24  priikone
38  *      Added silc_server_get_route to return communication object
39  *      for fastest route.
40  *
41  * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
42  *      Imported from internal CVS/Added Log headers.
43  *
44  *
45  */
46
47 #include "serverincludes.h"
48 #include "server_internal.h"
49 #include "route.h"
50
51 /* Route cache hash table */
52 SilcServerRouteTable silc_route_cache[SILC_SERVER_ROUTE_SIZE];
53
54 /* Adds new route to the route cache. The argument `index' is the
55    index value generated by silc_server_route_hash. */
56
57 void silc_server_route_add(unsigned int index, unsigned int dest,
58                            SilcServerEntry router)
59 {
60   silc_route_cache[index].dest = dest;
61   silc_route_cache[index].router = router;
62 }
63
64 /* Checksk whether destination has a specific router. Returns the
65    router data if found, NULL otherwise. */
66
67 SilcServerEntry silc_server_route_check(unsigned int dest, 
68                                         unsigned short port)
69 {
70   unsigned int index;
71
72   index = silc_server_route_hash(dest, port);
73
74   if (silc_route_cache[index].router != NULL &&
75       silc_route_cache[index].dest == dest)
76     return silc_route_cache[index].router;
77
78   return NULL;
79 }
80
81 /* Returns the connection object for the fastest route for the given ID.
82    If we are normal server then this just returns our primary route. If
83    we are router we will do route lookup. */
84
85 SilcSocketConnection silc_server_get_route(SilcServer server, void *id,
86                                            SilcIdType id_type)
87 {
88   unsigned int dest = 0;
89   unsigned short port = 0;
90   SilcServerEntry router = NULL;
91
92   if (server->server_type == SILC_SERVER)
93     return (SilcSocketConnection)server->id_entry->router->connection;
94   
95   switch(id_type) {
96   case SILC_ID_CLIENT:
97     dest = ((SilcClientID *)id)->ip.s_addr;
98     port = server->id->port;
99     break;
100   case SILC_ID_SERVER:
101     dest = ((SilcServerID *)id)->ip.s_addr;
102     port = ((SilcServerID *)id)->port;
103     break;
104   case SILC_ID_CHANNEL:
105     dest = ((SilcChannelID *)id)->ip.s_addr;
106     port = ((SilcChannelID *)id)->port;
107     break;
108   default:
109     return NULL;
110   }
111
112   router = silc_server_route_check(dest, port);
113   if (!router)
114     return (SilcSocketConnection)server->id_entry->router->connection;
115
116   return (SilcSocketConnection)router->connection;
117 }