ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_connect.c
Revision: 3300
Committed: Sat Apr 12 18:26:22 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 8818 byte(s)
Log Message:
- doxygen

File Contents

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

Properties

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