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

# 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.5 2007-08-30 06:57:25 pippijn Exp $";
9
10 #include <boost/foreach.hpp>
11
12 #include "atheme.h"
13 #include "datastream.h"
14 #include "uplink.h"
15 #include "connection.h"
16
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 #if 0
26 uplink_heap = BlockHeapCreate (sizeof (uplink_t), 4);
27 #endif
28 }
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 sfree (u->name);
44 sfree (u->host);
45 sfree (u->pass);
46 sfree (u->vhost);
47 }
48 else
49 {
50 slog (LG_INFO, "Duplicate uplink %s.", name);
51 return NULL;
52 }
53 }
54 else
55 {
56 u = new uplink_t;
57 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 sfree (u->name);
81 sfree (u->host);
82 sfree (u->pass);
83 sfree (u->vhost);
84
85 node_del (n, &uplinks);
86 node_free (n);
87
88 delete u;
89 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 curr_uplink->conn = connection_t::open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush);
139 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 foreach (channel_pair &cp, chanlist)
191 channel_delete (cp.second);
192 /* this leaves me.me and all users on it (i.e. services) */
193
194 slog (LG_DEBUG, "uplink_close(): ------------------------- done -------------------------");
195 }