ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/uplink.C
Revision: 1.4
Committed: Tue Aug 28 17:08:12 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.3: +14 -19 lines
Log Message:
- changed name
- updated the example config to the new system
- added more documentation
- enhanced documentation generators
- added a link to the pdf to the website
- added an RSS feed generator
- transitioned hooks to c++ callbacks
- did various merges with upstream along the way
- added const where appropriate
- removed the old block allocator
- fixed most memory leaks
- transitioned some dictionaries to std::map
- transitioned some lists to std::vector
- made some free functions members where appropriate
- renamed string to dynstr and added a static string ststr
- use NOW instead of time (NULL) if possible
- completely reworked database backends, crypto handlers and protocol handlers
  to use an object factory
- removed the old module system. ermyth does not do any dynamic loading anymore
- fixed most of the build system
- reworked how protocol commands work

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.3 2007-07-21 13:23:22 pippijn Exp $";
9
10 #include "atheme.h"
11 #include "datastream.h"
12 #include "uplink.h"
13
14 list_t uplinks;
15 uplink_t *curr_uplink;
16
17 static void uplink_close (connection_t *cptr);
18
19 void
20 init_uplinks (void)
21 {
22 #if 0
23 uplink_heap = BlockHeapCreate (sizeof (uplink_t), 4);
24 #endif
25 }
26
27 uplink_t *
28 uplink_add (char *name, char *host, char *password, char *vhost, int port)
29 {
30 uplink_t *u;
31 node_t *n;
32
33 slog (LG_DEBUG, "uplink_add(): %s -> %s:%d", me.name, name, port);
34
35 if ((u = uplink_find (name)))
36 {
37 if (u->flags & UPF_ILLEGAL)
38 {
39 u->flags &= ~UPF_ILLEGAL;
40 sfree (u->name);
41 sfree (u->host);
42 sfree (u->pass);
43 sfree (u->vhost);
44 }
45 else
46 {
47 slog (LG_INFO, "Duplicate uplink %s.", name);
48 return NULL;
49 }
50 }
51 else
52 {
53 u = new uplink_t;
54 n = node_create ();
55 u->node = n;
56 node_add (u, n, &uplinks);
57 cnt.uplink++;
58 }
59
60 u->name = sstrdup (name);
61 u->host = sstrdup (host);
62 u->pass = sstrdup (password);
63 if (vhost)
64 u->vhost = sstrdup (vhost);
65 else
66 u->vhost = sstrdup ("0.0.0.0");
67 u->port = port;
68
69 return u;
70 }
71
72 void
73 uplink_delete (uplink_t *u)
74 {
75 node_t *n = node_find (u, &uplinks);
76
77 sfree (u->name);
78 sfree (u->host);
79 sfree (u->pass);
80 sfree (u->vhost);
81
82 node_del (n, &uplinks);
83 node_free (n);
84
85 delete u;
86 cnt.uplink--;
87 }
88
89 uplink_t *
90 uplink_find (char *name)
91 {
92 node_t *n;
93
94 LIST_FOREACH (n, uplinks.head)
95 {
96 uplink_t *u = static_cast<uplink_t *> (n->data);
97
98 if (!strcasecmp (u->name, name))
99 return u;
100 }
101
102 return NULL;
103 }
104
105 void
106 uplink_connect (void)
107 {
108 uplink_t *u;
109
110 if (curr_uplink == NULL)
111 {
112 if (uplinks.head == NULL)
113 {
114 slog (LG_ERROR, "uplink_connect(): no uplinks configured, exiting. Make sure to have at least one uplink{} block in your configuration file.");
115 exit (EXIT_FAILURE);
116 }
117 curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
118 slog (LG_INFO, "uplink_connect(): connecting to first entry %s[%s]:%d.", curr_uplink->name, curr_uplink->host, curr_uplink->port);
119 }
120 else if (curr_uplink->node->next)
121 {
122 u = static_cast<uplink_t *> (curr_uplink->node->next->data);
123
124 curr_uplink = u;
125 slog (LG_INFO, "uplink_connect(): trying alternate uplink %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
126 }
127 else
128 {
129 curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
130 slog (LG_INFO, "uplink_connect(): trying again first entry %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
131 }
132
133 u = curr_uplink;
134
135 curr_uplink->conn = connection_open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush);
136 if (curr_uplink->conn != NULL)
137 curr_uplink->conn->close_handler = uplink_close;
138 else
139 event_add_once ("reconn", reconn, NULL, me.recontime);
140 }
141
142 /*
143 * uplink_close()
144 *
145 * inputs:
146 * connection pointer of current uplink
147 * triggered by callback close_handler
148 *
149 * outputs:
150 * none
151 *
152 * side effects:
153 * reconnection is scheduled
154 * uplink marked dead
155 * uplink deleted if it had been removed from configuration
156 */
157 static void
158 uplink_close (connection_t *cptr)
159 {
160 channel_t *c;
161 dictionary_iteration_state_t state;
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 DICTIONARY_FOREACH (c, channel_t, &state, chanlist)
191 {
192 channel_delete (c);
193 }
194 /* this leaves me.me and all users on it (i.e. services) */
195
196 slog (LG_DEBUG, "uplink_close(): ------------------------- done -------------------------");
197 }