ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/uplink.C
Revision: 1.9
Committed: Sat Sep 22 14:27:30 2007 UTC (16 years, 7 months 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

# Content
1 /*
2 * uplink.C: Uplink management.
3 *
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 * Rights to this code are documented in doc/pod/license.pod.
10 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
11 */
12
13 static char const rcsid[] = "$Id: uplink.C,v 1.8 2007-09-16 18:54:45 pippijn Exp $";
14
15 #include <boost/foreach.hpp>
16
17 #include "atheme.h"
18 #include "servers.h"
19 #include "datastream.h"
20 #include "uplink.h"
21 #include "connection.h"
22
23 uplink_t::list_type uplinks;
24 uplink_t *curr_uplink;
25
26 static void uplink_close (connection_t *cptr);
27
28 void
29 init_uplinks (void)
30 {
31 #if 0
32 uplink_heap = BlockHeapCreate (sizeof (uplink_t), 4);
33 #endif
34 }
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 sfree (u->name);
49 sfree (u->host);
50 sfree (u->pass);
51 sfree (u->vhost);
52 }
53 else
54 {
55 slog (LG_INFO, "Duplicate uplink %s.", name);
56 return NULL;
57 }
58 }
59 else
60 {
61 u = new uplink_t;
62 uplinks.insert (u);
63 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 sfree (u->name);
82 sfree (u->host);
83 sfree (u->pass);
84 sfree (u->vhost);
85
86 uplinks.erase (u);
87
88 delete u;
89 cnt.uplink--;
90 }
91
92 uplink_t *
93 uplink_find (char *name)
94 {
95 foreach (uplink_t *u, uplinks)
96 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 if (uplinks.empty ())
110 {
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 curr_uplink = uplinks.front ();
115 slog (LG_INFO, "uplink_connect(): connecting to first entry %s[%s]:%d.", curr_uplink->name, curr_uplink->host, curr_uplink->port);
116 }
117 else if (curr_uplink != uplinks.back ())
118 {
119 u = uplinks[curr_uplink->index + 1];
120
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 curr_uplink = uplinks.front ();
127 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 curr_uplink->conn = connection_t::open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush);
133 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 void
140 uplink_cleanup ()
141 {
142 while (!uplinks.empty ())
143 uplink_delete (uplinks.back ());
144 }
145
146 /*
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 if (uplinks.empty ())
173 {
174 slog (LG_ERROR, "uplink_close(): last uplink deleted, exiting.");
175 exit (EXIT_FAILURE);
176 }
177 curr_uplink = uplinks.front ();
178 }
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 foreach (channel_pair &cp, chanlist)
192 channel_delete (cp.second);
193 /* this leaves me.me and all users on it (i.e. services) */
194
195 slog (LG_DEBUG, "uplink_close(): ------------------------- done -------------------------");
196 }