ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/uplink.C
Revision: 1.5
Committed: Thu Aug 30 06:57:25 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.4: +5 -8 lines
Log Message:
- chanlist to std::map

File Contents

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