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

# User Rev Content
1 pippijn 1.1 /*
2     * uplink.C: Uplink management.
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
5 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 pippijn 1.1 */
7    
8 pippijn 1.4 static char const rcsid[] = "$Id: uplink.C,v 1.3 2007-07-21 13:23:22 pippijn Exp $";
9 pippijn 1.1
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 pippijn 1.4 #if 0
23 pippijn 1.1 uplink_heap = BlockHeapCreate (sizeof (uplink_t), 4);
24 pippijn 1.4 #endif
25 pippijn 1.1 }
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 pippijn 1.4 sfree (u->name);
41     sfree (u->host);
42     sfree (u->pass);
43     sfree (u->vhost);
44 pippijn 1.1 }
45     else
46     {
47     slog (LG_INFO, "Duplicate uplink %s.", name);
48     return NULL;
49     }
50     }
51     else
52     {
53 pippijn 1.4 u = new uplink_t;
54 pippijn 1.1 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 pippijn 1.4 sfree (u->name);
78     sfree (u->host);
79     sfree (u->pass);
80     sfree (u->vhost);
81 pippijn 1.1
82     node_del (n, &uplinks);
83     node_free (n);
84    
85 pippijn 1.4 delete u;
86 pippijn 1.1 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     }