ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_connect.c
Revision: 374
Committed: Sat Jan 14 17:57:18 2006 UTC (19 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 9360 byte(s)
Log Message:
- More m_connect cleanups, I also never liked the idea of temporarily modifying
  a connect item, so let's do this a bit different now.

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_connect.c: Connects to a remote IRC server.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "handlers.h"
27 #include "client.h"
28 #include "ircd.h"
29 #include "numeric.h"
30 #include "s_conf.h"
31 #include "s_serv.h"
32 #include "send.h"
33 #include "msg.h"
34 #include "parse.h"
35 #include "hash.h"
36 #include "modules.h"
37
38 static void mo_connect(struct Client *, struct Client *, int, char *[]);
39 static void ms_connect(struct Client *, struct Client *, int, char *[]);
40
41 struct Message connect_msgtab = {
42 "CONNECT", 0, 0, 2, 0, MFLG_SLOW, 0,
43 { m_unregistered, m_not_oper, ms_connect, m_ignore, mo_connect, m_ignore }
44 };
45
46 #ifndef STATIC_MODULES
47 void
48 _modinit(void)
49 {
50 mod_add_cmd(&connect_msgtab);
51 }
52
53 void
54 _moddeinit(void)
55 {
56 mod_del_cmd(&connect_msgtab);
57 }
58
59 const char *_version = "$Revision$";
60 #endif
61
62 /*! \brief CONNECT command handler (called for operators only)
63 *
64 * \param client_p Pointer to allocated Client struct with physical connection
65 * to this server, i.e. with an open socket connected.
66 * \param source_p Pointer to allocated Client struct from which the message
67 * originally comes from. This can be a local or remote client.
68 * \param parc Integer holding the number of supplied arguments.
69 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
70 * pointers.
71 * \note Valid arguments for this command are:
72 * - parv[0] = sender prefix
73 * - parv[1] = servername
74 * - parv[2] = port number
75 * - parv[3] = remote server
76 */
77 static void
78 mo_connect(struct Client *client_p, struct Client *source_p,
79 int parc, char *parv[])
80 {
81 int port = 0;
82 struct ConfItem *conf = NULL;
83 struct AccessItem *aconf = NULL;
84 struct Client *target_p = NULL;
85
86 /* always privileged with handlers */
87 if (MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3)
88 {
89 sendto_one(source_p, form_str(ERR_NOPRIVS),
90 me.name, source_p->name, "connect");
91 return;
92 }
93
94 if (hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3,
95 parc, parv) != HUNTED_ISME)
96 return;
97
98 if (*parv[1] == '\0')
99 {
100 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
101 me.name, source_p->name, "CONNECT");
102 return;
103 }
104
105 if ((target_p = find_server(parv[1])))
106 {
107 sendto_one(source_p,
108 ":%s NOTICE %s :Connect: Server %s already exists from %s.",
109 me.name, source_p->name, parv[1], target_p->from->name);
110 return;
111 }
112
113 /*
114 * Try to find the name, then host, if both fail notify ops and bail
115 */
116 if ((conf = find_matching_name_conf(SERVER_TYPE,
117 parv[1], NULL, NULL, 0)) != NULL)
118 aconf = &conf->conf.AccessItem;
119 else if ((conf = find_matching_name_conf(SERVER_TYPE,
120 NULL, NULL, parv[1], 0)) != NULL)
121 aconf = &conf->conf.AccessItem;
122
123 if (conf == NULL)
124 {
125 sendto_one(source_p,
126 ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf",
127 me.name, source_p->name, parv[1]);
128 return;
129 }
130
131 /*
132 * Get port number from user, if given. If not specified,
133 * use the default from configuration structure.
134 */
135 port = aconf->port;
136
137 if (parc > 2 && !EmptyString(parv[2]))
138 port = atoi(parv[2]);
139
140 if (port <= 0 || port > 0xFFFF)
141 {
142 sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal or missing port number",
143 me.name, source_p->name);
144 return;
145 }
146
147 if (find_servconn_in_progress(conf->name))
148 {
149 sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s "
150 "is already in progress.", me.name, source_p->name, conf->name);
151 return;
152 }
153
154 /*
155 * Notify all operators about remote connect requests
156 */
157 ilog(L_TRACE, "CONNECT From %s : %s %s",
158 source_p->name, parv[1], parv[2] ? parv[2] : "");
159
160 /*
161 * At this point we should be calling connect_server with a valid
162 * connect{} and a valid port in the connect{}
163 */
164 if (serv_connect(aconf, source_p, port))
165 {
166 if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
167 sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s[%s].%d",
168 me.name, source_p->name, aconf->host,
169 conf->name, port);
170 else
171 sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
172 me.name, source_p->name, conf->name, port);
173 }
174 else
175 {
176 sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
177 me.name, source_p->name, conf->name, port);
178 }
179
180 /*
181 * Client is either connecting with all the data it needs or has been
182 * destroyed
183 */
184 }
185
186 /*! \brief CONNECT command handler (called for remote clients only)
187 *
188 * \param client_p Pointer to allocated Client struct with physical connection
189 * to this server, i.e. with an open socket connected.
190 * \param source_p Pointer to allocated Client struct from which the message
191 * originally comes from. This can be a local or remote client.
192 * \param parc Integer holding the number of supplied arguments.
193 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
194 * pointers.
195 * \note Valid arguments for this command are:
196 * - parv[0] = sender prefix
197 * - parv[1] = servername
198 * - parv[2] = port number
199 * - parv[3] = remote server
200 */
201 static void
202 ms_connect(struct Client *client_p, struct Client *source_p,
203 int parc, char *parv[])
204 {
205 int port = 0;
206 struct ConfItem *conf = NULL;
207 struct AccessItem *aconf = NULL;
208 struct Client *target_p = NULL;
209
210 if (hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3,
211 parc, parv) != HUNTED_ISME)
212 return;
213
214 if (*parv[1] == '\0')
215 {
216 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
217 me.name, source_p->name, "CONNECT");
218 return;
219 }
220
221 if ((target_p = find_server(parv[1])))
222 {
223 sendto_one(source_p,
224 ":%s NOTICE %s :Connect: Server %s already exists from %s.",
225 me.name, source_p->name, parv[1], target_p->from->name);
226 return;
227 }
228
229 /*
230 * Try to find the name, then host, if both fail notify ops and bail
231 */
232 if ((conf = find_matching_name_conf(SERVER_TYPE,
233 parv[1], NULL, NULL, 0)) != NULL)
234 aconf = &conf->conf.AccessItem;
235 else if ((conf = find_matching_name_conf(SERVER_TYPE,
236 NULL, NULL, parv[1], 0)) != NULL)
237 aconf = &conf->conf.AccessItem;
238
239 if (aconf == NULL)
240 {
241 sendto_one(source_p,
242 ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf",
243 me.name, source_p->name, parv[1]);
244 return;
245 }
246
247 assert(aconf != NULL);
248
249 /*
250 * Get port number from user, if given. If not specified,
251 * use the default from configuration structure.
252 */
253 port = aconf->port;
254
255 if (parc > 2 && !EmptyString(parv[2]))
256 {
257 port = atoi(parv[2]);
258
259 /* if someone sends port 0, use the config port instead */
260 if (port == 0)
261 port = aconf->port;
262 }
263
264 if (port <= 0 || port > 0xFFFF)
265 {
266 sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal or missing port number",
267 me.name, source_p->name);
268 return;
269 }
270
271 if (find_servconn_in_progress(conf->name))
272 {
273 sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s "
274 "is already in progress.", me.name, source_p->name, conf->name);
275 return;
276 }
277
278 /*
279 * Notify all operators about remote connect requests
280 */
281 sendto_wallops_flags(UMODE_WALLOP, &me, "Remote CONNECT %s %d from %s",
282 parv[1], port, source_p->name);
283 sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS,
284 ":%s WALLOPS :Remote CONNECT %s %d from %s",
285 me.name, parv[1], port, source_p->name);
286
287 ilog(L_TRACE, "CONNECT From %s : %s %d",
288 source_p->name, parv[1], port);
289
290 /*
291 * At this point we should be calling connect_server with a valid
292 * connect{} and a valid port in the connect{}
293 */
294 if (serv_connect(aconf, source_p, port))
295 sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
296 me.name, source_p->name, conf->name, port);
297 else
298 sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
299 me.name, source_p->name, conf->name, port);
300
301 /*
302 * Client is either connecting with all the data it needs or has been
303 * destroyed
304 */
305 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision