ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/uplink.C
Revision: 1.7
Committed: Sun Sep 9 20:05:53 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.6: +2 -1 lines
Log Message:
- changed configurations to the c++ stdlib
- more #defines to enum
- removed getopt.h and link.h from the system as they were unused
- reworked logstreams
- added an itoa with old syntax
- made klines objects
- moved some global variables into appropriate classes
- fixed boost.foreach's compiler workaround #if's
- allow other files to add exceptions with ADD_EXCEPTION
- changed mynick_t to c++ object
- moved servers.h out of atheme.h
- corrected PING from inspircd 1.2

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.6 2007-08-30 19:56:26 pippijn Exp $";
9
10 #include <boost/foreach.hpp>
11
12 #include "atheme.h"
13 #include "servers.h"
14 #include "datastream.h"
15 #include "uplink.h"
16 #include "connection.h"
17
18 list_t uplinks;
19 uplink_t *curr_uplink;
20
21 static void uplink_close (connection_t *cptr);
22
23 void
24 init_uplinks (void)
25 {
26 #if 0
27 uplink_heap = BlockHeapCreate (sizeof (uplink_t), 4);
28 #endif
29 }
30
31 uplink_t *
32 uplink_add (char *name, char *host, char *password, char *vhost, int port)
33 {
34 uplink_t *u;
35 node_t *n;
36
37 slog (LG_DEBUG, "uplink_add(): %s -> %s:%d", me.name, name, port);
38
39 if ((u = uplink_find (name)))
40 {
41 if (u->flags & UPF_ILLEGAL)
42 {
43 u->flags &= ~UPF_ILLEGAL;
44 sfree (u->name);
45 sfree (u->host);
46 sfree (u->pass);
47 sfree (u->vhost);
48 }
49 else
50 {
51 slog (LG_INFO, "Duplicate uplink %s.", name);
52 return NULL;
53 }
54 }
55 else
56 {
57 u = new uplink_t;
58 n = node_create ();
59 u->node = n;
60 node_add (u, n, &uplinks);
61 cnt.uplink++;
62 }
63
64 u->name = sstrdup (name);
65 u->host = sstrdup (host);
66 u->pass = sstrdup (password);
67 if (vhost)
68 u->vhost = sstrdup (vhost);
69 else
70 u->vhost = sstrdup ("0.0.0.0");
71 u->port = port;
72
73 return u;
74 }
75
76 void
77 uplink_delete (uplink_t *u)
78 {
79 node_t *n = node_find (u, &uplinks);
80
81 sfree (u->name);
82 sfree (u->host);
83 sfree (u->pass);
84 sfree (u->vhost);
85
86 node_del (n, &uplinks);
87 node_free (n);
88
89 delete u;
90 cnt.uplink--;
91 }
92
93 uplink_t *
94 uplink_find (char *name)
95 {
96 node_t *n;
97
98 LIST_FOREACH (n, uplinks.head)
99 {
100 uplink_t *u = static_cast<uplink_t *> (n->data);
101
102 if (!strcasecmp (u->name, name))
103 return u;
104 }
105
106 return NULL;
107 }
108
109 void
110 uplink_connect (void)
111 {
112 uplink_t *u;
113
114 if (curr_uplink == NULL)
115 {
116 if (uplinks.head == NULL)
117 {
118 slog (LG_ERROR, "uplink_connect(): no uplinks configured, exiting. Make sure to have at least one uplink{} block in your configuration file.");
119 exit (EXIT_FAILURE);
120 }
121 curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
122 slog (LG_INFO, "uplink_connect(): connecting to first entry %s[%s]:%d.", curr_uplink->name, curr_uplink->host, curr_uplink->port);
123 }
124 else if (curr_uplink->node->next)
125 {
126 u = static_cast<uplink_t *> (curr_uplink->node->next->data);
127
128 curr_uplink = u;
129 slog (LG_INFO, "uplink_connect(): trying alternate uplink %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
130 }
131 else
132 {
133 curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
134 slog (LG_INFO, "uplink_connect(): trying again first entry %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port);
135 }
136
137 u = curr_uplink;
138
139 curr_uplink->conn = connection_t::open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush);
140 if (curr_uplink->conn != NULL)
141 curr_uplink->conn->close_handler = uplink_close;
142 else
143 event_add_once ("reconn", reconn, NULL, me.recontime);
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.head == NULL)
173 {
174 slog (LG_ERROR, "uplink_close(): last uplink deleted, exiting.");
175 exit (EXIT_FAILURE);
176 }
177 curr_uplink = static_cast<uplink_t *> (uplinks.head->data);
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 }