… | |
… | |
8 | * Portions of this file were derived from sources bearing the following license: |
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. |
9 | * Rights to this code are documented in doc/pod/license.pod. |
10 | * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) |
10 | * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) |
11 | */ |
11 | */ |
12 | |
12 | |
13 | static char const rcsid[] = "$Id: uplink.C,v 1.8 2007/09/16 18:54:45 pippijn Exp $"; |
13 | static char const rcsid[] = "$Id: uplink.C,v 1.9 2007/09/22 14:27:30 pippijn Exp $"; |
14 | |
14 | |
15 | #include <boost/foreach.hpp> |
15 | #include <boost/foreach.hpp> |
16 | |
16 | |
17 | #include "atheme.h" |
17 | #include "atheme.h" |
18 | #include "servers.h" |
18 | #include "servers.h" |
19 | #include "datastream.h" |
19 | #include "datastream.h" |
20 | #include "uplink.h" |
20 | #include "uplink.h" |
21 | #include "connection.h" |
21 | #include "connection.h" |
22 | |
22 | |
23 | list_t uplinks; |
23 | uplink_t::list_type uplinks; |
24 | uplink_t *curr_uplink; |
24 | uplink_t *curr_uplink; |
25 | |
25 | |
26 | static void uplink_close (connection_t *cptr); |
26 | static void uplink_close (connection_t *cptr); |
27 | |
27 | |
28 | void |
28 | void |
… | |
… | |
35 | |
35 | |
36 | uplink_t * |
36 | uplink_t * |
37 | uplink_add (char *name, char *host, char *password, char *vhost, int port) |
37 | uplink_add (char *name, char *host, char *password, char *vhost, int port) |
38 | { |
38 | { |
39 | uplink_t *u; |
39 | uplink_t *u; |
40 | node_t *n; |
|
|
41 | |
40 | |
42 | slog (LG_DEBUG, "uplink_add(): %s -> %s:%d", me.name, name, port); |
41 | slog (LG_DEBUG, "uplink_add(): %s -> %s:%d", me.name, name, port); |
43 | |
42 | |
44 | if ((u = uplink_find (name))) |
43 | if ((u = uplink_find (name))) |
45 | { |
44 | { |
… | |
… | |
58 | } |
57 | } |
59 | } |
58 | } |
60 | else |
59 | else |
61 | { |
60 | { |
62 | u = new uplink_t; |
61 | u = new uplink_t; |
63 | n = node_create (); |
62 | uplinks.insert (u); |
64 | u->node = n; |
|
|
65 | node_add (u, n, &uplinks); |
|
|
66 | cnt.uplink++; |
63 | cnt.uplink++; |
67 | } |
64 | } |
68 | |
65 | |
69 | u->name = sstrdup (name); |
66 | u->name = sstrdup (name); |
70 | u->host = sstrdup (host); |
67 | u->host = sstrdup (host); |
… | |
… | |
79 | } |
76 | } |
80 | |
77 | |
81 | void |
78 | void |
82 | uplink_delete (uplink_t *u) |
79 | uplink_delete (uplink_t *u) |
83 | { |
80 | { |
84 | node_t *n = node_find (u, &uplinks); |
|
|
85 | |
|
|
86 | sfree (u->name); |
81 | sfree (u->name); |
87 | sfree (u->host); |
82 | sfree (u->host); |
88 | sfree (u->pass); |
83 | sfree (u->pass); |
89 | sfree (u->vhost); |
84 | sfree (u->vhost); |
90 | |
85 | |
91 | node_del (n, &uplinks); |
86 | uplinks.erase (u); |
92 | node_free (n); |
|
|
93 | |
87 | |
94 | delete u; |
88 | delete u; |
95 | cnt.uplink--; |
89 | cnt.uplink--; |
96 | } |
90 | } |
97 | |
91 | |
98 | uplink_t * |
92 | uplink_t * |
99 | uplink_find (char *name) |
93 | uplink_find (char *name) |
100 | { |
94 | { |
101 | node_t *n; |
95 | foreach (uplink_t *u, uplinks) |
102 | |
|
|
103 | LIST_FOREACH (n, uplinks.head) |
|
|
104 | { |
|
|
105 | uplink_t *u = static_cast<uplink_t *> (n->data); |
|
|
106 | |
|
|
107 | if (!strcasecmp (u->name, name)) |
96 | if (!strcasecmp (u->name, name)) |
108 | return u; |
97 | return u; |
109 | } |
|
|
110 | |
98 | |
111 | return NULL; |
99 | return NULL; |
112 | } |
100 | } |
113 | |
101 | |
114 | void |
102 | void |
… | |
… | |
116 | { |
104 | { |
117 | uplink_t *u; |
105 | uplink_t *u; |
118 | |
106 | |
119 | if (curr_uplink == NULL) |
107 | if (curr_uplink == NULL) |
120 | { |
108 | { |
121 | if (uplinks.head == NULL) |
109 | if (uplinks.empty ()) |
122 | { |
110 | { |
123 | slog (LG_ERROR, "uplink_connect(): no uplinks configured, exiting. Make sure to have at least one uplink{} block in your configuration file."); |
111 | slog (LG_ERROR, "uplink_connect(): no uplinks configured, exiting. Make sure to have at least one uplink{} block in your configuration file."); |
124 | exit (EXIT_FAILURE); |
112 | exit (EXIT_FAILURE); |
125 | } |
113 | } |
126 | curr_uplink = static_cast<uplink_t *> (uplinks.head->data); |
114 | curr_uplink = uplinks.front (); |
127 | slog (LG_INFO, "uplink_connect(): connecting to first entry %s[%s]:%d.", curr_uplink->name, curr_uplink->host, curr_uplink->port); |
115 | slog (LG_INFO, "uplink_connect(): connecting to first entry %s[%s]:%d.", curr_uplink->name, curr_uplink->host, curr_uplink->port); |
128 | } |
116 | } |
129 | else if (curr_uplink->node->next) |
117 | else if (curr_uplink != uplinks.back ()) |
130 | { |
118 | { |
131 | u = static_cast<uplink_t *> (curr_uplink->node->next->data); |
119 | u = uplinks[curr_uplink->index + 1]; |
132 | |
120 | |
133 | curr_uplink = u; |
121 | curr_uplink = u; |
134 | slog (LG_INFO, "uplink_connect(): trying alternate uplink %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port); |
122 | slog (LG_INFO, "uplink_connect(): trying alternate uplink %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port); |
135 | } |
123 | } |
136 | else |
124 | else |
137 | { |
125 | { |
138 | curr_uplink = static_cast<uplink_t *> (uplinks.head->data); |
126 | curr_uplink = uplinks.front (); |
139 | slog (LG_INFO, "uplink_connect(): trying again first entry %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port); |
127 | slog (LG_INFO, "uplink_connect(): trying again first entry %s[%s]:%d", curr_uplink->name, curr_uplink->host, curr_uplink->port); |
140 | } |
128 | } |
141 | |
129 | |
142 | u = curr_uplink; |
130 | u = curr_uplink; |
143 | |
131 | |
144 | curr_uplink->conn = connection_t::open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush); |
132 | curr_uplink->conn = connection_t::open_tcp (u->host, u->vhost, u->port, recvq_put, sendq_flush); |
145 | if (curr_uplink->conn != NULL) |
133 | if (curr_uplink->conn != NULL) |
146 | curr_uplink->conn->close_handler = uplink_close; |
134 | curr_uplink->conn->close_handler = uplink_close; |
147 | else |
135 | else |
148 | event_add_once ("reconn", reconn, NULL, me.recontime); |
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 ()); |
149 | } |
144 | } |
150 | |
145 | |
151 | /* |
146 | /* |
152 | * uplink_close() |
147 | * uplink_close() |
153 | * |
148 | * |
… | |
… | |
172 | |
167 | |
173 | if (curr_uplink->flags & UPF_ILLEGAL) |
168 | if (curr_uplink->flags & UPF_ILLEGAL) |
174 | { |
169 | { |
175 | slog (LG_INFO, "uplink_close(): %s was removed from configuration, deleting", curr_uplink->name); |
170 | slog (LG_INFO, "uplink_close(): %s was removed from configuration, deleting", curr_uplink->name); |
176 | uplink_delete (curr_uplink); |
171 | uplink_delete (curr_uplink); |
177 | if (uplinks.head == NULL) |
172 | if (uplinks.empty ()) |
178 | { |
173 | { |
179 | slog (LG_ERROR, "uplink_close(): last uplink deleted, exiting."); |
174 | slog (LG_ERROR, "uplink_close(): last uplink deleted, exiting."); |
180 | exit (EXIT_FAILURE); |
175 | exit (EXIT_FAILURE); |
181 | } |
176 | } |
182 | curr_uplink = static_cast<uplink_t *> (uplinks.head->data); |
177 | curr_uplink = uplinks.front (); |
183 | } |
178 | } |
184 | curr_uplink->conn = NULL; |
179 | curr_uplink->conn = NULL; |
185 | |
180 | |
186 | slog (LG_DEBUG, "uplink_close(): ----------------------- clearing -----------------------"); |
181 | slog (LG_DEBUG, "uplink_close(): ----------------------- clearing -----------------------"); |
187 | |
182 | |