ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/uplink.C
Revision: 1.6
Committed: Thu Aug 30 19:56:26 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.5: +3 -2 lines
Log Message:
- put faultcodes into their own namespace
- removed old files
- limited header garbage in atheme.h
- macros to inline bools for connection_t::is_*
- put some connection_t functions into the connection_t class

File Contents

# User Rev Content
1 pippijn 1.1 /*
2     * uplink.C: Uplink management.
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
5 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 pippijn 1.1 */
7    
8 pippijn 1.6 static char const rcsid[] = "$Id: uplink.C,v 1.5 2007-08-30 06:57:25 pippijn Exp $";
9 pippijn 1.5
10     #include <boost/foreach.hpp>
11 pippijn 1.1
12     #include "atheme.h"
13     #include "datastream.h"
14     #include "uplink.h"
15 pippijn 1.6 #include "connection.h"
16 pippijn 1.1
17     list_t uplinks;
18     uplink_t *curr_uplink;
19    
20     static void uplink_close (connection_t *cptr);
21    
22     void
23     init_uplinks (void)
24     {
25 pippijn 1.4 #if 0
26 pippijn 1.1 uplink_heap = BlockHeapCreate (sizeof (uplink_t), 4);
27 pippijn 1.4 #endif
28 pippijn 1.1 }
29    
30     uplink_t *
31     uplink_add (char *name, char *host, char *password, char *vhost, int port)
32     {
33     uplink_t *u;
34     node_t *n;
35    
36     slog (LG_DEBUG, "uplink_add(): %s -> %s:%d", me.name, name, port);
37    
38     if ((u = uplink_find (name)))
39     {
40     if (u->flags & UPF_ILLEGAL)
41     {
42     u->flags &= ~UPF_ILLEGAL;
43 pippijn 1.4 sfree (u->name);
44     sfree (u->host);
45     sfree (u->pass);
46     sfree (u->vhost);
47 pippijn 1.1 }
48     else
49     {
50     slog (LG_INFO, "Duplicate uplink %s.", name);
51     return NULL;
52     }
53     }
54     else
55     {
56 pippijn 1.4 u = new uplink_t;
57 pippijn 1.1 n = node_create ();
58     u->node = n;
59     node_add (u, n, &uplinks);
60     cnt.uplink++;
61     }
62    
63     u->name = sstrdup (name);
64     u->host = sstrdup (host);
65     u->pass = sstrdup (password);
66     if (vhost)
67     u->vhost = sstrdup (vhost);
68     else
69     u->vhost = sstrdup ("0.0.0.0");
70     u->port = port;
71    
72     return u;
73     }
74    
75     void
76     uplink_delete (uplink_t *u)
77     {
78     node_t *n = node_find (u, &uplinks);
79    
80 pippijn 1.4 sfree (u->name);
81     sfree (u->host);
82     sfree (u->pass);
83     sfree (u->vhost);
84 pippijn 1.1
85     node_del (n, &uplinks);
86     node_free (n);
87    
88 pippijn 1.4 delete u;
89 pippijn 1.1 cnt.uplink--;
90     }
91    
92     uplink_t *
93     uplink_find (char *name)
94     {
95     node_t *n;
96    
97     LIST_FOREACH (n, uplinks.head)
98     {
99     uplink_t *u = static_cast<uplink_t *> (n->data);
100    
101     if (!strcasecmp (u->name, name))
102     return u;
103     }
104    
105     return NULL;
106     }
107    
108     void
109     uplink_connect (void)
110     {
111     uplink_t *u;
112    
113     if (curr_uplink == NULL)
114     {
115     if (uplinks.head == NULL)
116     {
117     slog (LG_ERROR, "uplink_connect(): no uplinks configured, exiting. Make sure to have at least one uplink{} block in your configuration file.");
118     exit (EXIT_FAILURE);
119     }
120     curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
121     slog (LG_INFO, "uplink_connect(): connecting to first entry %s[%s]:%d.", curr_uplink->name, curr_uplink->host, curr_uplink->port);
122     }
123     else if (curr_uplink->node->next)
124     {
125     u = static_cast<uplink_t *> (curr_uplink->node->next->data);
126    
127     curr_uplink = u;
128     slog (LG_INFO, "uplink_connect(): trying alternate uplink %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
129     }
130     else
131     {
132     curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
133     slog (LG_INFO, "uplink_connect(): trying again first entry %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
134     }
135    
136     u = curr_uplink;
137    
138 pippijn 1.6 curr_uplink->conn = connection_t::open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush);
139 pippijn 1.1 if (curr_uplink->conn != NULL)
140     curr_uplink->conn->close_handler = uplink_close;
141     else
142     event_add_once ("reconn", reconn, NULL, me.recontime);
143     }
144    
145     /*
146     * uplink_close()
147     *
148     * inputs:
149     * connection pointer of current uplink
150     * triggered by callback close_handler
151     *
152     * outputs:
153     * none
154     *
155     * side effects:
156     * reconnection is scheduled
157     * uplink marked dead
158     * uplink deleted if it had been removed from configuration
159     */
160     static void
161     uplink_close (connection_t *cptr)
162     {
163     event_add_once ("reconn", reconn, NULL, me.recontime);
164    
165     me.connected = false;
166    
167     if (curr_uplink->flags & UPF_ILLEGAL)
168     {
169     slog (LG_INFO, "uplink_close(): %s was removed from configuration, deleting", curr_uplink->name);
170     uplink_delete (curr_uplink);
171     if (uplinks.head == NULL)
172     {
173     slog (LG_ERROR, "uplink_close(): last uplink deleted, exiting.");
174     exit (EXIT_FAILURE);
175     }
176     curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
177     }
178     curr_uplink->conn = NULL;
179    
180     slog (LG_DEBUG, "uplink_close(): ----------------------- clearing -----------------------");
181    
182     /* we have to kill everything.
183     * we do not clear users here because when you delete a server,
184     * it deletes its users
185     */
186     if (me.actual != NULL)
187     server_delete (me.actual);
188     me.actual = NULL;
189     /* remove all the channels left */
190 pippijn 1.5 foreach (channel_pair &cp, chanlist)
191     channel_delete (cp.second);
192 pippijn 1.1 /* this leaves me.me and all users on it (i.e. services) */
193    
194     slog (LG_DEBUG, "uplink_close(): ------------------------- done -------------------------");
195     }