ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/uplink.C
Revision: 1.9
Committed: Sat Sep 22 14:27:30 2007 UTC (19 years ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +19 -24 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

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.9 static char const rcsid[] = "$Id: uplink.C,v 1.8 2007-09-16 18:54:45 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 pippijn 1.9 uplink_t::list_type uplinks;
24 pippijn 1.1 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    
41     slog (LG_DEBUG, "uplink_add(): %s -> %s:%d", me.name, name, port);
42    
43     if ((u = uplink_find (name)))
44     {
45     if (u->flags & UPF_ILLEGAL)
46     {
47     u->flags &= ~UPF_ILLEGAL;
48 pippijn 1.4 sfree (u->name);
49     sfree (u->host);
50     sfree (u->pass);
51     sfree (u->vhost);
52 pippijn 1.1 }
53     else
54     {
55     slog (LG_INFO, "Duplicate uplink %s.", name);
56     return NULL;
57     }
58     }
59     else
60     {
61 pippijn 1.4 u = new uplink_t;
62 pippijn 1.9 uplinks.insert (u);
63 pippijn 1.1 cnt.uplink++;
64     }
65    
66     u->name = sstrdup (name);
67     u->host = sstrdup (host);
68     u->pass = sstrdup (password);
69     if (vhost)
70     u->vhost = sstrdup (vhost);
71     else
72     u->vhost = sstrdup ("0.0.0.0");
73     u->port = port;
74    
75     return u;
76     }
77    
78     void
79     uplink_delete (uplink_t *u)
80     {
81 pippijn 1.4 sfree (u->name);
82     sfree (u->host);
83     sfree (u->pass);
84     sfree (u->vhost);
85 pippijn 1.1
86 pippijn 1.9 uplinks.erase (u);
87 pippijn 1.1
88 pippijn 1.4 delete u;
89 pippijn 1.1 cnt.uplink--;
90     }
91    
92     uplink_t *
93     uplink_find (char *name)
94     {
95 pippijn 1.9 foreach (uplink_t *u, uplinks)
96 pippijn 1.1 if (!strcasecmp (u->name, name))
97     return u;
98    
99     return NULL;
100     }
101    
102     void
103     uplink_connect (void)
104     {
105     uplink_t *u;
106    
107     if (curr_uplink == NULL)
108     {
109 pippijn 1.9 if (uplinks.empty ())
110 pippijn 1.1 {
111     slog (LG_ERROR, "uplink_connect(): no uplinks configured, exiting. Make sure to have at least one uplink{} block in your configuration file.");
112     exit (EXIT_FAILURE);
113     }
114 pippijn 1.9 curr_uplink = uplinks.front ();
115 pippijn 1.1 slog (LG_INFO, "uplink_connect(): connecting to first entry %s[%s]:%d.", curr_uplink->name, curr_uplink->host, curr_uplink->port);
116     }
117 pippijn 1.9 else if (curr_uplink != uplinks.back ())
118 pippijn 1.1 {
119 pippijn 1.9 u = uplinks[curr_uplink->index + 1];
120 pippijn 1.1
121     curr_uplink = u;
122     slog (LG_INFO, "uplink_connect(): trying alternate uplink %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
123     }
124     else
125     {
126 pippijn 1.9 curr_uplink = uplinks.front ();
127 pippijn 1.1 slog (LG_INFO, "uplink_connect(): trying again first entry %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
128     }
129    
130     u = curr_uplink;
131    
132 pippijn 1.6 curr_uplink->conn = connection_t::open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush);
133 pippijn 1.1 if (curr_uplink->conn != NULL)
134     curr_uplink->conn->close_handler = uplink_close;
135     else
136     event_add_once ("reconn", reconn, NULL, me.recontime);
137     }
138    
139 pippijn 1.9 void
140     uplink_cleanup ()
141     {
142     while (!uplinks.empty ())
143     uplink_delete (uplinks.back ());
144     }
145    
146 pippijn 1.1 /*
147     * uplink_close()
148     *
149     * inputs:
150     * connection pointer of current uplink
151     * triggered by callback close_handler
152     *
153     * outputs:
154     * none
155     *
156     * side effects:
157     * reconnection is scheduled
158     * uplink marked dead
159     * uplink deleted if it had been removed from configuration
160     */
161     static void
162     uplink_close (connection_t *cptr)
163     {
164     event_add_once ("reconn", reconn, NULL, me.recontime);
165    
166     me.connected = false;
167    
168     if (curr_uplink->flags & UPF_ILLEGAL)
169     {
170     slog (LG_INFO, "uplink_close(): %s was removed from configuration, deleting", curr_uplink->name);
171     uplink_delete (curr_uplink);
172 pippijn 1.9 if (uplinks.empty ())
173 pippijn 1.1 {
174     slog (LG_ERROR, "uplink_close(): last uplink deleted, exiting.");
175     exit (EXIT_FAILURE);
176     }
177 pippijn 1.9 curr_uplink = uplinks.front ();
178 pippijn 1.1 }
179     curr_uplink->conn = NULL;
180    
181     slog (LG_DEBUG, "uplink_close(): ----------------------- clearing -----------------------");
182    
183     /* we have to kill everything.
184     * we do not clear users here because when you delete a server,
185     * it deletes its users
186     */
187     if (me.actual != NULL)
188     server_delete (me.actual);
189     me.actual = NULL;
190     /* remove all the channels left */
191 pippijn 1.5 foreach (channel_pair &cp, chanlist)
192     channel_delete (cp.second);
193 pippijn 1.1 /* this leaves me.me and all users on it (i.e. services) */
194    
195     slog (LG_DEBUG, "uplink_close(): ------------------------- done -------------------------");
196     }