ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/uplink.C
Revision: 1.8
Committed: Sun Sep 16 18:54:45 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.7: +7 -2 lines
Log Message:
#defines to enum

File Contents

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