1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-10-04 01:42:24 +00:00

Compare commits

...

25 Commits

Author SHA1 Message Date
Alexander Barton
b00a08ef40 Free topic array on channel deletion.
The topic array in the CHANNEL structure must be free()'d before the
channel itself becomes deleted.

(backport of commit 18efc7469c of master branch)
2009-01-04 15:57:33 +01:00
Florian Westphal
aede22901c Fix handling of MaxConnections option
Config option claimed to be 'number of connections' but in reality this
was treated as 'largest file descriptor allowed'.

This also fixes another bug in New_connection, where the
ng_ipaddr_tostr_r error path was missing a return statement.
2008-08-31 18:43:42 +02:00
Alexander Barton
62b668a7b1 ngIRCd 0.12.1 2008-07-09 12:37:37 +02:00
Alexander Barton
ecddfb7010 Updated ChangeLog for 0.12.1. 2008-06-11 16:39:25 +02:00
Alexander Barton
fb46757c48 Allow mixed line terminations (CR+LF/CR/LF) in non-RFC-compliant mode
Up to now ngIRCd accepted CR+LF as well as a single CR or LF in "non RFC
compliant" mode (the default). But ngIRCd became confused when it received
data containing mixed line endings (e. g. "111\r222\n333\r\n").

This patch enables ngIRCd (in "non RFC compliant" mode) to detect CR+LF,
CR, and LF as equally good line termination sequences and to always end the
command after the first one detected.

Some clients (for exmaple Trilian) are that ... broken to send such mixed
line terminations ...

First patch proposed by Scott Perry <scperry@ucsd.edu>,
Thanks to Ali Shemiran <ashemira@ucsd.edu> for testing!

(manually cherry picked from commit a84f7dcee5)
2008-06-11 16:38:11 +02:00
Alexander Barton
b6b019dddc Updated NEWS and ChangeLog in preparation for ngIRCd 0.12.1. 2008-05-30 19:26:19 +02:00
Alexander Barton
ce3215acaf Don't allow stray \r or \n in command parameters
If ngircd receives an input line like "COMMAND arg\nIRRELEVANT\r\n",
"arg\nIRRELEVANT" is passed as an argument to COMMAND. This can lead
to output like:

:ngircd.test.server 322 nick #chan 1 :
topicwithprecedingnewline
:ngircd.test.server 322 nick #nxtchan 1 :
[..]

Worse, this allows clients to piggyback irc commands, e.g.
"TOPIC #a :test\n:fake!~a@nonexistant JOIN :#a\r\n", which
causes the client to receive a JOIN command during /LIST output.

Bug reported by Scott Perry, first patch by Florian Westphal.
(cherry picked from commit 8644cbf197)
2008-05-30 15:12:17 +02:00
Alexander Barton
edb59b8317 --configtest: return non-zero exit code if there are errors
(cherry picked from commit 6f7b669bec)
2008-05-30 15:12:07 +02:00
Alexander Barton
42207d160b Update ngIRCd manual pages
- Update timestamp,
- enhance some phrasing,
- and fix "Passive" ([Server]) formatting.
(cherry picked from commit aad49bd260)
2008-05-30 15:08:40 +02:00
Jari Aalto
a3dc42534b Add option aliases -V (for --version) and -h (for --help).
This patch adds -h and -V short options (to complement the usage).

It is based on a patch attached to Debian bug #466063, see
<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=466063>.

Idea by Jari Aalto <jari.aalto@cante.net>,
patch adapted by Alexander Barton <alex@barton.de>.
(cherry picked from commit 818a206a42)
2008-05-19 14:59:41 +02:00
Florian Westphal
bb81927ce4 Fix 'no-ipv6' compile error. 2008-05-19 14:59:35 +02:00
Florian Westphal
b2c0a89f45 make Listen parameter a comma-seperated list of addresses.
this also obsoletes ListenIPv4 and ListenIPv6 options.
If Listen is unset, it is treated as Listen="::,0.0.0.0".

Note: ListenIPv4 and ListenIPv6 options are still recognized,
but ngircd will print a warning if they are used in the config file.

Also, some plattforms require that ai_socktype
is set in the getaddrinfo() hints structure.
2008-05-19 14:27:04 +02:00
Alexander Barton
f44007f42f ngIRCd 0.12.0 2008-05-13 12:42:59 +02:00
Alexander Barton
1a56c77751 Updated NEWS and ChangeLog for ngIRCd 0.12.0. 2008-05-13 12:42:27 +02:00
Florian Westphal
78257374f0 If bind() fails, also print ip address and not just the port number. 2008-05-13 12:30:41 +02:00
Florian Westphal
fc93044909 Fix complie on FreeBSD 5.4 and AIX.
This is picked from commits

d9c26f3aeb
"ng_ipaddr.h must include netinet/in.h."

and
4e507881f3
"On AIX (for example) socklen_t is defined in sys/socket.h"
2008-05-10 21:53:39 +02:00
Ali Shemiran
2e0c62df91 Fix secret channel information leak
/who on a secret channel that the user is not a member of
now returns proper RPL_ENDOFWHO_MSG instead of nothing.

[picked from 12cd554af1709c44f35024d7d2fc368fb22f133d; without testcase]
2008-05-09 21:52:54 +02:00
Alexander Barton
c5ba599140 ngIRCd 0.12.0-pre2 2008-04-29 23:57:11 +02:00
Alexander Barton
afc67ff323 Merge branch 'master' into branch-0-12-x 2008-04-29 15:36:16 +02:00
Alexander Barton
6052d04c60 Merge branch 'master' into branch-0-12-x 2008-04-29 14:41:24 +02:00
Alexander Barton
32bf6d4de0 Merge branch 'master' into branch-0-12-x
Fixed bug 81:
When trying to part a channel ("PART #channel") the client is not member of
the daemon now correctly reports the numeric ERR_NOTONCHANNEL (442) insted
of ERR_NOSUCHCHANNEL (403).
2008-04-25 00:20:35 +02:00
Alexander Barton
b187fac244 Get rid of cvs-version.* and CVSDATE definition. 2008-04-20 23:10:22 +02:00
Alexander Barton
6e9389b86c Documentation: get rid of some more references to CVS, switch to GIT. 2008-04-20 22:48:05 +02:00
Alexander Barton
a8e0eb62e9 Don't include doc/CVS.txt in distribution archive, use doc/GIT.txt now! 2008-04-20 16:46:49 +02:00
Alexander Barton
4ea2932967 ngIRCd 0.12.0-pre1 2008-04-20 15:53:49 +02:00
17 changed files with 331 additions and 202 deletions

View File

@@ -10,8 +10,28 @@
-- ChangeLog -- -- ChangeLog --
ngIRCd 0.12.0-pre2 (2008-04-29) ngIRCd 0.12.1 (2008-07-09)
- Allow mixed line terminations (CR+LF/CR/LF) in non-RFC-compliant mode
- Don't allow stray \r or \n in command parameters
- --configtest: return non-zero exit code if there are errors
- Update ngIRCd manual pages
- Add option aliases -V (for --version) and -h (for --help).
- Fix 'no-ipv6' compile error.
- Make Listen parameter a comma-seperated list of addresses. This also
obsoletes ListenIPv4 and ListenIPv6 options. If Listen is unset, it
is treated as Listen="::,0.0.0.0".
Note: ListenIPv4 and ListenIPv6 options are still recognized,
but ngircd will print a warning if they are used in the config file.
ngIRCd 0.12.0 (2008-05-13)
- Fix Bug: 85: "WHO #SecretChannel" that user is not a member of now returns
proper RPL_ENDOFWHO_MSG instead of nothing. (Ali Shemiran)
- Fix complie on FreeBSD 5.4 and AIX.
- If bind() fails, also print ip address and not just the port number.
ngIRCd 0.12.0-pre2 (2008-04-29)
- IPv6: Add config options to disabe ipv4/ipv6 support. - IPv6: Add config options to disabe ipv4/ipv6 support.
- Don't include doc/CVS.txt in distribution archive, use doc/GIT.txt now! - Don't include doc/CVS.txt in distribution archive, use doc/GIT.txt now!
- Documentation: get rid of some more references to CVS, switch to GIT. - Documentation: get rid of some more references to CVS, switch to GIT.

12
NEWS
View File

@@ -10,8 +10,18 @@
-- NEWS -- -- NEWS --
ngIRCd 0.12.0-pre2 (2008-04-29) ngIRCd 0.12.1 (2008-07-09)
- Add option aliases -V (for --version) and -h (for --help).
- Make Listen parameter a comma-seperated list of addresses. This also
obsoletes ListenIPv4 and ListenIPv6 options. If Listen is unset, it
is treated as Listen="::,0.0.0.0".
Note: ListenIPv4 and ListenIPv6 options are still recognized,
but ngircd will print a warning if they are used in the config file.
ngIRCd 0.12.0 (2008-05-13)
ngIRCd 0.12.0-pre2 (2008-04-29)
- IPv6: Add config options to disabe ipv4/ipv6 support. - IPv6: Add config options to disabe ipv4/ipv6 support.
ngIRCd 0.12.0-pre1 (2008-04-20) ngIRCd 0.12.0-pre1 (2008-04-20)

View File

@@ -12,7 +12,7 @@
# -- Initialisation -- # -- Initialisation --
AC_PREREQ(2.50) AC_PREREQ(2.50)
AC_INIT(ngircd, HEAD) AC_INIT(ngircd, 0.12.1)
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c) AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AC_CANONICAL_TARGET AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6) AM_INIT_AUTOMAKE(1.6)

View File

@@ -1,3 +1,21 @@
ngircd (0.12.1-0ab1) unstable; urgency=low
* New "upstream" release ngIRCd 0.12.1.
-- Alexander Barton <alex@barton.de> Wed, 9 Jul 2008 11:27:00 +0200
ngircd (0.12.0-0ab1) unstable; urgency=low
* New "upstream" release ngIRCd 0.12.0.
-- Alexander Barton <alex@barton.de> Tue, 13 May 2008 12:30:31 +0200
ngircd (0.12.0-0ab0-pre2) unstable; urgency=low
* Second prerelease of upcoming new "upstrem" release 0.12.0-pre1.
-- Alexander Barton <alex@barton.de> Tue, 29 Apr 2008 23:06:14 +0200
ngircd (0.12.0-0ab0-pre1) unstable; urgency=low ngircd (0.12.0-0ab0-pre1) unstable; urgency=low
* Prereloease of upcoming new "upstrem" release 0.12.0-pre1. * Prereloease of upcoming new "upstrem" release 0.12.0-pre1.

View File

@@ -1,5 +1,5 @@
%define name ngircd %define name ngircd
%define version CVSHEAD %define version 0.12.1
%define release 1 %define release 1
%define prefix %{_prefix} %define prefix %{_prefix}

View File

@@ -40,9 +40,11 @@
# one port, separated with ",". (Default: 6667) # one port, separated with ",". (Default: 6667)
;Ports = 6667, 6668, 6669 ;Ports = 6667, 6668, 6669
# IP address on which the server should listen. (Default: empty, # comma seperated list of IP addresses on which the server should
# so the server listens on all IP addresses of the system) # listen. Default values are:
;Listen = 1.2.3.4 # "0.0.0.0" or (if compiled with IPv6 support) "::,0.0.0.0"
# so the server listens on all IP addresses of the system by default.
;Listen = 127.0.0.1,192.168.0.1
# Text file with the "message of the day" (MOTD). This message will # Text file with the "message of the day" (MOTD). This message will
# be shown to all users connecting to the server: # be shown to all users connecting to the server:
@@ -103,11 +105,6 @@
# Don't do any DNS lookups when a client connects to the server. # Don't do any DNS lookups when a client connects to the server.
;NoDNS = no ;NoDNS = no
# allow both ipv4 and ipv6 clients to connect by opening both
# ipv4 and ipv6 sockets
;ListenIPv6 = yes
;ListenIPv4 = yes
# try to connect to other irc servers using ipv4 and ipv6, if possible # try to connect to other irc servers using ipv4 and ipv6, if possible
;ConnectIPv6 = yes ;ConnectIPv6 = yes
;ConnectIPv4 = yes ;ConnectIPv4 = yes

View File

@@ -1,7 +1,7 @@
.\" .\"
.\" $Id: ngircd.8.tmpl,v 1.2 2007/11/15 01:03:29 fw Exp $ .\" $Id: ngircd.8.tmpl,v 1.2 2007/11/15 01:03:29 fw Exp $
.\" .\"
.TH ngircd 8 "August 2005" ngircd "ngIRCd Manual" .TH ngircd 8 "May 2008" ngircd "ngIRCd Manual"
.SH NAME .SH NAME
ngIRCd \- the next generation IRC daemon ngIRCd \- the next generation IRC daemon
.SH SYNOPSIS .SH SYNOPSIS
@@ -50,10 +50,10 @@ CONNECT later on as IRC Operator to link this ngIRCd to other servers.
\fB\-t\fR, \fB\-\-configtest\fR \fB\-t\fR, \fB\-\-configtest\fR
Read, validate and display the configuration; then exit. Read, validate and display the configuration; then exit.
.TP .TP
\fB\-\-version\fR \fB\-V\fR, \fB\-\-version\fR
Output version information and exit. Output version information and exit.
.TP .TP
\fB\-\-help\fR \fB\-h\fR, \fB\-\-help\fR
Display a brief help text and exit. Display a brief help text and exit.
.SH FILES .SH FILES
.I :ETCDIR:/ngircd.conf .I :ETCDIR:/ngircd.conf

View File

@@ -1,7 +1,7 @@
.\" .\"
.\" $Id: ngircd.conf.5.tmpl,v 1.7 2007/11/23 16:26:03 fw Exp $ .\" $Id: ngircd.conf.5.tmpl,v 1.7 2007/11/23 16:26:03 fw Exp $
.\" .\"
.TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual" .TH ngircd.conf 5 "May 2008" ngircd "ngIRCd Manual"
.SH NAME .SH NAME
ngircd.conf \- configuration file of ngIRCd ngircd.conf \- configuration file of ngIRCd
.SH SYNOPSIS .SH SYNOPSIS
@@ -26,19 +26,20 @@ Sections contain parameters of the form
.RE .RE
.PP .PP
Empty lines and any line beginning with a semicolon (';') or a hash ('#') Empty lines and any line beginning with a semicolon (';') or a hash ('#')
character is treated as a comment and will be ignored. character are treated as a comment and will be ignored. Leading and trailing
whitespaces are trimmed before any processing takes place.
.PP .PP
The file format is line-based - that means, each newline-terminated line The file format is line-based - that means, each non-empty newline-terminated
represents either a comment, a section name or a parameter. line represents either a comment, a section name, or a parameter.
.PP .PP
Section and parameter names are not case sensitive. Section and parameter names are not case sensitive.
.SH "SECTION OVERVIEW" .SH "SECTION OVERVIEW"
The file can contain blocks of four types: [Global], [Operator], [Server], The file can contain blocks of four types: [Global], [Operator], [Server],
and [Channel]. and [Channel].
.PP .PP
In the The main configuration of the server is stored in the
.I [Global] .I [Global]
section, there is the main configuration like the server name and the section, like the server name, administrative information and the
ports on which the server should be listening. IRC operators of this ports on which the server should be listening. IRC operators of this
server are defined in server are defined in
.I [Operator] .I [Operator]
@@ -57,7 +58,7 @@ section is used to define the server main configuration, like the server
name and the ports on which the server should be listening. name and the ports on which the server should be listening.
.TP .TP
\fBName\fR \fBName\fR
Server name in the IRC network Server name in the IRC network, must contain at least one dot (".").
.TP .TP
\fBInfo\fR \fBInfo\fR
Info text of the server. This will be shown by WHOIS and LINKS requests for Info text of the server. This will be shown by WHOIS and LINKS requests for
@@ -72,8 +73,10 @@ Ports on which the server should listen. There may be more than one port,
separated with ','. Default: 6667. separated with ','. Default: 6667.
.TP .TP
\fBListen\fR \fBListen\fR
The IP address on which the server should listen. Default is empty, so A comma seperated list of IP address on which the server should listen.
the server listens on all configured IP addresses and interfaces. If unset, the defaults value is "0.0.0.0", or, if ngircd was compiled
with IPv6 support, "::,0.0.0.0", so the server listens on all configured
IP addresses and interfaces by default.
.TP .TP
\fBMotdFile\fR \fBMotdFile\fR
Text file with the "message of the day" (MOTD). This message will be shown Text file with the "message of the day" (MOTD). This message will be shown
@@ -81,7 +84,8 @@ to all users connecting to the server.
.TP .TP
\fBMotdPhrase\fR \fBMotdPhrase\fR
A simple Phrase (<256 chars) if you don't want to use a MOTD file. A simple Phrase (<256 chars) if you don't want to use a MOTD file.
If it is set no MotdFile will be read at all. If it is set no MotdFile will be read at all which can be handy if the
daemon should run inside a chroot directory.
.TP .TP
\fBServerUID\fR \fBServerUID\fR
User ID under which the server should run; you can use the name of the user User ID under which the server should run; you can use the name of the user
@@ -158,15 +162,6 @@ If you configure ngircd to connect to other servers, ngircd may still
perform a DNS lookup if required. perform a DNS lookup if required.
Default: No. Default: No.
.TP .TP
\fBListenIPv4\fR
Set this to no if you do not want ngircd to accept clients using the standard internet protocol, ipv4.
This allows use of ngircd in ipv6-only setups.
Default: Yes.
.TP
\fBListenIPv6\fR
Set this to no if you do not want ngircd to accept clients using the new internet protocol, ipv6.
Default: Yes.
.TP
\fBConnectIPv4\fR \fBConnectIPv4\fR
Set this to no if you do not want ngircd to connect to other irc servers using ipv4. Set this to no if you do not want ngircd to connect to other irc servers using ipv4.
This allows use of ngircd in ipv6-only setups. This allows use of ngircd in ipv6-only setups.
@@ -212,31 +207,34 @@ Example: nick!ident@*.example.com
Other servers are configured in Other servers are configured in
.I [Server] .I [Server]
sections. If you configure a port for the connection, then this ngIRCd sections. If you configure a port for the connection, then this ngIRCd
tries to connect to to the other server on the given port; if not, it waits tries to connect to to the other server on the given port (active);
for the other server to connect. if not, it waits for the other server to connect (passive).
.PP .PP
The ngIRCd allows "server groups": You can assign an "ID" to every server ngIRCd supports "server groups": You can assign an "ID" to every server
with which you want this ngIRCd to link. If a server of a group won't with which you want this ngIRCd to link, and the daemon ensures that at
answer, the ngIRCd tries to connect to the next server in the given group. any given time only one direct link exists to servers with the same ID.
But ngIRCd never tries to connect to two servers with the same group ID. So if a server of a group won't answer, ngIRCd tries to connect to the next
server in the given group (="with the same ID"), but never tries to connect
to more than one server of this group simultaneously.
.PP .PP
There may be more than one There may be more than one
.I [Server] .I [Server]
block. block.
.TP .TP
\fBName\fR \fBName\fR
IRC name of the server IRC name of the remote server.
.TP .TP
\fBHost\fR \fBHost\fR
Internet host name of the peer Internet host name (or IP address) of the peer.
.TP .TP
\fBBind\fR \fBBind\fR
IP address to use as source IP for the outgoing connection. Default ist IP address to use as source IP for the outgoing connection. Default ist
to let the operating system decide. to let the operating system decide.
.TP .TP
\fBPort\fR \fBPort\fR
Port of the server to which the ngIRCd should connect. If you assign no port Port of the remote server to which ngIRCd should connect (active).
the ngIRCd waits for incoming connections. If no port is assigned to a configured server, the daemon only waits for
incoming connections (passive).
.TP .TP
\fBMyPassword\fR \fBMyPassword\fR
Own password for this connection. This password has to be configured as Own password for this connection. This password has to be configured as
@@ -248,6 +246,7 @@ Foreign password for this connection. This password has to be configured as
.TP .TP
\fBGroup\fR \fBGroup\fR
Group of this server (optional). Group of this server (optional).
.TP
\fBPassive\fR \fBPassive\fR
Disable automatic connection even if port value is specified. Default: false. Disable automatic connection even if port value is specified. Default: false.
You can use the IRC Operator command CONNECT later on to create the link. You can use the IRC Operator command CONNECT later on to create the link.
@@ -265,19 +264,19 @@ There may be more than one
block. block.
.TP .TP
\fBName\fR \fBName\fR
Name of the channel Name of the channel, including channel prefix ("#").
.TP .TP
\fBTopic\fR \fBTopic\fR
Topic for this channel Topic for this channel.
.TP .TP
\fBModes\fR \fBModes\fR
Initial channel modes. Initial channel modes.
.TP .TP
\fBKey\fR \fBKey\fR
Sets initial channel key (only relevant if mode k is set) Sets initial channel key (only relevant if mode k is set).
.TP .TP
\fBMaxUsers\fR \fBMaxUsers\fR
Set maximum user limit for this channel (only relevant if mode l is set) Set maximum user limit for this channel (only relevant if mode l is set).
.SH HINTS .SH HINTS
It's wise to use "ngircd --configtest" to validate the configuration file It's wise to use "ngircd --configtest" to validate the configuration file
after changing it. See after changing it. See

View File

@@ -14,9 +14,6 @@
#include <netdb.h> #include <netdb.h>
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#include <sys/socket.h>
#include <netinet/in.h>
#include "ng_ipaddr.h" #include "ng_ipaddr.h"
@@ -27,18 +24,19 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
int ret; int ret;
char portstr[64]; char portstr[64];
struct addrinfo *res0; struct addrinfo *res0;
struct addrinfo hints = { struct addrinfo hints;
#ifndef WANT_IPV6 /* only accept v4 addresses */
.ai_family = AF_INET,
#endif
.ai_flags = AI_NUMERICHOST
};
if (ip_str == NULL) assert(ip_str);
hints.ai_flags |= AI_PASSIVE;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
/* some getaddrinfo implementations require that ai_socktype is set. */
hints.ai_socktype = SOCK_STREAM;
/* silly, but ngircd stores UINT16 in server config, not string */ /* silly, but ngircd stores UINT16 in server config, not string */
snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port); snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port);
ret = getaddrinfo(ip_str, portstr, &hints, &res0); ret = getaddrinfo(ip_str, portstr, &hints, &res0);
assert(ret == 0); assert(ret == 0);
if (ret != 0) if (ret != 0)
@@ -52,8 +50,7 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
freeaddrinfo(res0); freeaddrinfo(res0);
return ret == 0; return ret == 0;
#else /* HAVE_GETADDRINFO */ #else /* HAVE_GETADDRINFO */
if (ip_str == NULL) assert(ip_str);
ip_str = "0.0.0.0";
addr->sin4.sin_family = AF_INET; addr->sin4.sin_family = AF_INET;
# ifdef HAVE_INET_ATON # ifdef HAVE_INET_ATON
if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0) if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)

View File

@@ -8,6 +8,9 @@
#define NG_IPADDR_HDR #define NG_IPADDR_HDR
#include "portab.h" #include "portab.h"
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef HAVE_ARPA_INET_H #ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h> # include <arpa/inet.h>
#else #else
@@ -81,7 +84,6 @@ ng_ipaddr_getport(const ng_ipaddr_t *a)
* init a ng_ipaddr_t object. * init a ng_ipaddr_t object.
* @param addr: pointer to ng_ipaddr_t to initialize. * @param addr: pointer to ng_ipaddr_t to initialize.
* @param ip_str: ip address in dotted-decimal (ipv4) or hexadecimal (ipv6) notation * @param ip_str: ip address in dotted-decimal (ipv4) or hexadecimal (ipv6) notation
* if ip_str is NULL it is treated as 0.0.0.0/[::]
* @param port: transport layer port number to use. * @param port: transport layer port number to use.
*/ */
GLOBAL bool ng_ipaddr_init PARAMS((ng_ipaddr_t *addr, const char *ip_str, UINT16 port)); GLOBAL bool ng_ipaddr_init PARAMS((ng_ipaddr_t *addr, const char *ip_str, UINT16 port));

View File

@@ -1027,9 +1027,9 @@ Delete_Channel( CHANNEL *Chan )
Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name ); Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name );
/* Invite- und Ban-Lists aufraeumen */ array_free(&chan->topic);
Lists_Free( &chan->list_bans ); Lists_Free(&chan->list_bans);
Lists_Free( &chan->list_invites ); Lists_Free(&chan->list_invites);
/* Neu verketten und freigeben */ /* Neu verketten und freigeben */
if( last_chan ) last_chan->next = chan->next; if( last_chan ) last_chan->next = chan->next;

View File

@@ -56,9 +56,21 @@ static CONF_SERVER New_Server;
static int New_Server_Idx; static int New_Server_Idx;
#ifdef WANT_IPV6
/*
* these options appeared in ngircd 0.12; they are here
* for backwards compatibility. They should be removed
* in the future. Instead of setting these options,
* the "Listen" option should be set accordingly.
*/
static bool Conf_ListenIPv6;
static bool Conf_ListenIPv4;
#endif
static void Set_Defaults PARAMS(( bool InitServers )); static void Set_Defaults PARAMS(( bool InitServers ));
static bool Read_Config PARAMS(( bool ngircd_starting )); static bool Read_Config PARAMS(( bool ngircd_starting ));
static void Validate_Config PARAMS(( bool TestOnly, bool Rehash )); static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg )); static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg ));
static void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg )); static void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg ));
@@ -170,11 +182,14 @@ Conf_Test( void )
struct group *grp; struct group *grp;
unsigned int i; unsigned int i;
char *topic; char *topic;
bool config_valid;
Use_Log = false; Use_Log = false;
Read_Config( true ); if (! Read_Config(true))
Validate_Config(true, false); return 1;
config_valid = Validate_Config(true, false);
/* If stdin and stdout ("you can read our nice message and we can /* If stdin and stdout ("you can read our nice message and we can
* read in your keypress") are valid tty's, wait for a key: */ * read in your keypress") are valid tty's, wait for a key: */
@@ -199,8 +214,7 @@ Conf_Test( void )
fputs(" Ports = ", stdout); fputs(" Ports = ", stdout);
ports_puts(&Conf_ListenPorts); ports_puts(&Conf_ListenPorts);
printf(" Listen = %s\n", Conf_ListenAddress);
printf( " Listen = %s\n", Conf_ListenAddress );
pwd = getpwuid( Conf_UID ); pwd = getpwuid( Conf_UID );
if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name ); if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
else printf( " ServerUID = %ld\n", (long)Conf_UID ); else printf( " ServerUID = %ld\n", (long)Conf_UID );
@@ -216,8 +230,11 @@ Conf_Test( void )
printf( " NoDNS = %s\n", yesno_to_str(Conf_NoDNS)); printf( " NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
#ifdef WANT_IPV6 #ifdef WANT_IPV6
printf(" ListenIPv6 = %s\n", yesno_to_str(Conf_ListenIPv6)); /* both are deprecated, only mention them if their default value changed. */
printf(" ListenIPv4 = %s\n", yesno_to_str(Conf_ListenIPv4)); if (!Conf_ListenIPv6)
puts(" ListenIPv6 = no");
if (!Conf_ListenIPv4)
puts(" ListenIPv4 = no");
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6)); printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4)); printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
#endif #endif
@@ -265,7 +282,7 @@ Conf_Test( void )
printf( " Topic = %s\n\n", topic ? topic : ""); printf( " Topic = %s\n\n", topic ? topic : "");
} }
return 0; return (config_valid ? 0 : 1);
} /* Conf_Test */ } /* Conf_Test */
@@ -448,8 +465,8 @@ Set_Defaults( bool InitServers )
strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile )); strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile ));
strcpy( Conf_ListenAddress, "" ); free(Conf_ListenAddress);
Conf_ListenAddress = NULL;
Conf_UID = Conf_GID = 0; Conf_UID = Conf_GID = 0;
Conf_PingTimeout = 120; Conf_PingTimeout = 120;
@@ -466,10 +483,11 @@ Set_Defaults( bool InitServers )
Conf_OperServerMode = false; Conf_OperServerMode = false;
Conf_ConnectIPv4 = true; Conf_ConnectIPv4 = true;
Conf_ListenIPv4 = true;
Conf_ConnectIPv6 = true; Conf_ConnectIPv6 = true;
#ifdef WANT_IPV6
Conf_ListenIPv4 = true;
Conf_ListenIPv6 = true; Conf_ListenIPv6 = true;
#endif
Conf_MaxConnections = 0; Conf_MaxConnections = 0;
Conf_MaxConnectionsIP = 5; Conf_MaxConnectionsIP = 5;
Conf_MaxJoins = 10; Conf_MaxJoins = 10;
@@ -650,6 +668,23 @@ Read_Config( bool ngircd_starting )
exit( 1 ); exit( 1 );
} }
} }
if (!Conf_ListenAddress) {
/* no Listen addresses configured, use default */
#ifdef WANT_IPV6
/* Conf_ListenIPv6/4 should no longer be used */
if (Conf_ListenIPv6 && Conf_ListenIPv4)
Conf_ListenAddress = strdup_warn("::,0.0.0.0");
else if (Conf_ListenIPv6)
Conf_ListenAddress = strdup_warn("::");
else
#endif
Conf_ListenAddress = strdup_warn("0.0.0.0");
}
if (!Conf_ListenAddress) {
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
exit(1);
}
return true; return true;
} /* Read_Config */ } /* Read_Config */
@@ -840,17 +875,25 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
} }
#ifdef WANT_IPV6 #ifdef WANT_IPV6
/* the default setting for all the WANT_IPV6 special options is 'true' */ /* the default setting for all the WANT_IPV6 special options is 'true' */
if( strcasecmp( Var, "ListenIPv6" ) == 0 ) { if (strcasecmp(Var, "ListenIPv6") == 0) { /* DEPRECATED, option appeared in 0.12.0 */
/* listen on ipv6 sockets, if available? */ /*
* listen on ipv6 sockets, if available?
* Deprecated use "Listen = 0.0.0.0" (or, rather, do not list "::")
*/
Conf_ListenIPv6 = Check_ArgIsTrue( Arg ); Conf_ListenIPv6 = Check_ArgIsTrue( Arg );
Config_Error(LOG_WARNING, "%s, line %d: %s=%s is deprecated, %sinclude '::' in \"Listen =\" option instead",
NGIRCd_ConfFile, Line, Var, yesno_to_str(Conf_ListenIPv6), Conf_ListenIPv6 ? " ":"do not ");
return; return;
} }
if( strcasecmp( Var, "ListenIPv4" ) == 0 ) { if (strcasecmp(Var, "ListenIPv4") == 0) { /* DEPRECATED, option appeared in 0.12.0 */
/* /*
* listen on ipv4 sockets, if available? * listen on ipv4 sockets, if available?
* this allows "ipv6-only" setups. * this allows "ipv6-only" setups
* Deprecated use "Listen = ::" (or, rather, do not list "0.0.0.0")
*/ */
Conf_ListenIPv4 = Check_ArgIsTrue( Arg ); Conf_ListenIPv4 = Check_ArgIsTrue( Arg );
Config_Error(LOG_WARNING, "%s, line %d: %s=%s is deprecated, %sinclude '0.0.0.0' in \"Listen =\" option instead",
NGIRCd_ConfFile, Line, Var, yesno_to_str(Conf_ListenIPv4), Conf_ListenIPv4 ? " ":"do not ");
return; return;
} }
if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) { if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
@@ -911,14 +954,24 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
if( strcasecmp( Var, "Listen" ) == 0 ) { if( strcasecmp( Var, "Listen" ) == 0 ) {
/* IP-Address to bind sockets */ /* IP-Address to bind sockets */
len = strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress )); if (Conf_ListenAddress) {
if (len >= sizeof( Conf_ListenAddress )) Config_Error(LOG_ERR, "Multiple Listen= options, ignoring: %s", Arg);
Config_Error_TooLong( Line, Var ); return;
}
Conf_ListenAddress = strdup_warn(Arg);
/*
* if allocation fails, we're in trouble:
* we cannot ignore the error -- otherwise ngircd
* would listen on all interfaces.
*/
if (!Conf_ListenAddress) {
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
exit(1);
}
return; return;
} }
Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var);
NGIRCd_ConfFile, Line, Var );
} /* Handle_GLOBAL */ } /* Handle_GLOBAL */
@@ -1114,7 +1167,7 @@ Handle_CHANNEL( int Line, char *Var, char *Arg )
} /* Handle_CHANNEL */ } /* Handle_CHANNEL */
static void static bool
Validate_Config(bool Configtest, bool Rehash) Validate_Config(bool Configtest, bool Rehash)
{ {
/* Validate configuration settings. */ /* Validate configuration settings. */
@@ -1122,6 +1175,7 @@ Validate_Config(bool Configtest, bool Rehash)
#ifdef DEBUG #ifdef DEBUG
int i, servers, servers_once; int i, servers, servers_once;
#endif #endif
bool config_valid = true;
char *ptr; char *ptr;
/* Validate configured server name, see RFC 2812 section 2.3.1 */ /* Validate configured server name, see RFC 2812 section 2.3.1 */
@@ -1140,6 +1194,7 @@ Validate_Config(bool Configtest, bool Rehash)
if (!Conf_ServerName[0]) { if (!Conf_ServerName[0]) {
/* No server name configured! */ /* No server name configured! */
config_valid = false;
Config_Error(LOG_ALERT, Config_Error(LOG_ALERT,
"No (valid) server name configured in \"%s\" (section 'Global': 'Name')!", "No (valid) server name configured in \"%s\" (section 'Global': 'Name')!",
NGIRCd_ConfFile); NGIRCd_ConfFile);
@@ -1153,6 +1208,7 @@ Validate_Config(bool Configtest, bool Rehash)
if (Conf_ServerName[0] && !strchr(Conf_ServerName, '.')) { if (Conf_ServerName[0] && !strchr(Conf_ServerName, '.')) {
/* No dot in server name! */ /* No dot in server name! */
config_valid = false;
Config_Error(LOG_ALERT, Config_Error(LOG_ALERT,
"Invalid server name configured in \"%s\" (section 'Global': 'Name'): Dot missing!", "Invalid server name configured in \"%s\" (section 'Global': 'Name'): Dot missing!",
NGIRCd_ConfFile); NGIRCd_ConfFile);
@@ -1167,6 +1223,7 @@ Validate_Config(bool Configtest, bool Rehash)
#ifdef STRICT_RFC #ifdef STRICT_RFC
if (!Conf_ServerAdminMail[0]) { if (!Conf_ServerAdminMail[0]) {
/* No administrative contact configured! */ /* No administrative contact configured! */
config_valid = false;
Config_Error(LOG_ALERT, Config_Error(LOG_ALERT,
"No administrator email address configured in \"%s\" ('AdminEMail')!", "No administrator email address configured in \"%s\" ('AdminEMail')!",
NGIRCd_ConfFile); NGIRCd_ConfFile);
@@ -1186,16 +1243,6 @@ Validate_Config(bool Configtest, bool Rehash)
"No administrative information configured but required by RFC!"); "No administrative information configured but required by RFC!");
} }
#ifdef WANT_IPV6
if (!Conf_ListenIPv4 && !Conf_ListenIPv6)
Config_Error(LOG_ALERT,
"Both \"ListenIPv4\" and \"ListenIPv6\" are set to 'no'; no network protocol available!");
if (!Conf_ConnectIPv4 && !Conf_ConnectIPv6)
Config_Error(LOG_ALERT,
"Both \"ConnectIPv4\" and \"ConnectIPv6\" are set to 'no'; ngircd will fail to connect to other irc servers");
#endif
#ifdef DEBUG #ifdef DEBUG
servers = servers_once = 0; servers = servers_once = 0;
for (i = 0; i < MAX_SERVERS; i++) { for (i = 0; i < MAX_SERVERS; i++) {
@@ -1209,6 +1256,8 @@ Validate_Config(bool Configtest, bool Rehash)
"Configuration: Operators=%d, Servers=%d[%d], Channels=%d", "Configuration: Operators=%d, Servers=%d[%d], Channels=%d",
Conf_Oper_Count, servers, servers_once, Conf_Channel_Count); Conf_Oper_Count, servers, servers_once, Conf_Channel_Count);
#endif #endif
return config_valid;
} /* Validate_Config */ } /* Validate_Config */

View File

@@ -86,7 +86,7 @@ GLOBAL char Conf_MotdPhrase[LINE_LEN];
GLOBAL array Conf_ListenPorts; GLOBAL array Conf_ListenPorts;
/* Address to which the socket should be bound or empty (=all) */ /* Address to which the socket should be bound or empty (=all) */
GLOBAL char Conf_ListenAddress[16]; GLOBAL char *Conf_ListenAddress;
/* User and group ID the server should run with */ /* User and group ID the server should run with */
GLOBAL uid_t Conf_UID; GLOBAL uid_t Conf_UID;
@@ -124,12 +124,6 @@ GLOBAL bool Conf_OperCanMode;
/* Disable all DNS functions? */ /* Disable all DNS functions? */
GLOBAL bool Conf_NoDNS; GLOBAL bool Conf_NoDNS;
/* listen for incoming ipv6 connections if OS supports it (default: yes)? */
GLOBAL bool Conf_ListenIPv6;
/* listen for incoming ipv4 connections if OS supports it (default: yes)? */
GLOBAL bool Conf_ListenIPv4;
/* /*
* try to connect to remote systems using the ipv6 protocol, * try to connect to remote systems using the ipv6 protocol,
* if they have an ipv6 address? (default yes) * if they have an ipv6 address? (default yes)

View File

@@ -88,10 +88,11 @@ static void Init_Conn_Struct PARAMS(( CONN_ID Idx ));
static bool Init_Socket PARAMS(( int Sock )); static bool Init_Socket PARAMS(( int Sock ));
static void New_Server PARAMS(( int Server, ng_ipaddr_t *dest )); static void New_Server PARAMS(( int Server, ng_ipaddr_t *dest ));
static void Simple_Message PARAMS(( int Sock, const char *Msg )); static void Simple_Message PARAMS(( int Sock, const char *Msg ));
static int NewListener PARAMS(( int af, const UINT16 Port )); static int NewListener PARAMS(( const char *listen_addr, UINT16 Port ));
static array My_Listeners; static array My_Listeners;
static array My_ConnArray; static array My_ConnArray;
static size_t NumConnections;
#ifdef TCPWRAP #ifdef TCPWRAP
int allow_severity = LOG_INFO; int allow_severity = LOG_INFO;
@@ -108,7 +109,8 @@ static void
cb_listen(int sock, short irrelevant) cb_listen(int sock, short irrelevant)
{ {
(void) irrelevant; (void) irrelevant;
New_Connection( sock ); if (New_Connection( sock ) >= 0)
NumConnections++;
} }
@@ -214,12 +216,10 @@ Conn_Init( void )
/* Speicher fuer Verbindungs-Pool anfordern */ /* Speicher fuer Verbindungs-Pool anfordern */
Pool_Size = CONNECTION_POOL; Pool_Size = CONNECTION_POOL;
if( Conf_MaxConnections > 0 ) if ((Conf_MaxConnections > 0) &&
{ (Pool_Size > Conf_MaxConnections))
/* konfiguriertes Limit beachten */ Pool_Size = Conf_MaxConnections;
if( Pool_Size > Conf_MaxConnections ) Pool_Size = Conf_MaxConnections;
}
if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Pool_Size)) { if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Pool_Size)) {
Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" ); Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" );
exit( 1 ); exit( 1 );
@@ -272,7 +272,7 @@ Conn_Exit( void )
static unsigned int static unsigned int
ports_initlisteners(array *a, int af, void (*func)(int,short)) ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
{ {
unsigned int created = 0; unsigned int created = 0;
size_t len; size_t len;
@@ -281,15 +281,15 @@ ports_initlisteners(array *a, int af, void (*func)(int,short))
len = array_length(a, sizeof (UINT16)); len = array_length(a, sizeof (UINT16));
port = array_start(a); port = array_start(a);
while(len--) { while (len--) {
fd = NewListener(af, *port); fd = NewListener(listen_addr, *port);
if (fd < 0) { if (fd < 0) {
port++; port++;
continue; continue;
} }
if (!io_event_create( fd, IO_WANTREAD, func )) { if (!io_event_create( fd, IO_WANTREAD, func )) {
Log( LOG_ERR, "io_event_create(): Could not add listening fd %d (port %u): %s!", Log( LOG_ERR, "io_event_create(): Could not add listening fd %d (port %u): %s!",
fd, (unsigned int) *port, strerror(errno)); fd, (unsigned int) *port, strerror(errno));
close(fd); close(fd);
port++; port++;
continue; continue;
@@ -297,7 +297,6 @@ ports_initlisteners(array *a, int af, void (*func)(int,short))
created++; created++;
port++; port++;
} }
return created; return created;
} }
@@ -306,21 +305,39 @@ GLOBAL unsigned int
Conn_InitListeners( void ) Conn_InitListeners( void )
{ {
/* Initialize ports on which the server should accept connections */ /* Initialize ports on which the server should accept connections */
unsigned int created = 0; unsigned int created = 0;
char *copy, *listen_addr;
if (!io_library_init(CONNECTION_POOL)) { if (!io_library_init(CONNECTION_POOL)) {
Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno)); Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno));
return -1; return -1;
} }
#ifdef WANT_IPV6 assert(Conf_ListenAddress);
if (Conf_ListenIPv6)
created = ports_initlisteners(&Conf_ListenPorts, AF_INET6, cb_listen);
#endif
if (Conf_ListenIPv4)
created += ports_initlisteners(&Conf_ListenPorts, AF_INET, cb_listen);
/* can't use Conf_ListenAddress directly, see below */
copy = strdup(Conf_ListenAddress);
if (!copy) {
Log(LOG_CRIT, "Cannot copy %s: %s", Conf_ListenAddress, strerror(errno));
return 0;
}
listen_addr = strtok(copy, ",");
while (listen_addr) {
ngt_TrimStr(listen_addr);
if (*listen_addr)
created += ports_initlisteners(&Conf_ListenPorts, listen_addr, cb_listen);
listen_addr = strtok(NULL, ",");
}
/*
* can't free() Conf_ListenAddress here. On /REHASH, if the config file
* cannot be re-loaded, we'd end up with a NULL Conf_ListenAddress.
* Instead, free() takes place in conf.c, before the config file
* is being parsed.
*/
free(copy);
return created; return created;
} /* Conn_InitListeners */ } /* Conn_InitListeners */
@@ -350,25 +367,15 @@ Conn_ExitListeners( void )
static bool static bool
InitSinaddrListenAddr(int af, ng_ipaddr_t *addr, UINT16 Port) InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port)
{ {
bool ret; bool ret;
const char *listen_addrstr = NULL;
#ifdef WANT_IPV6
if (af == AF_INET)
listen_addrstr = "0.0.0.0";
#else
(void)af;
#endif
if (Conf_ListenAddress[0]) /* overrides V4/V6 atm */
listen_addrstr = Conf_ListenAddress;
ret = ng_ipaddr_init(addr, listen_addrstr, Port); ret = ng_ipaddr_init(addr, listen_addrstr, Port);
if (!ret) { if (!ret) {
if (!listen_addrstr) assert(listen_addrstr);
listen_addrstr = ""; Log(LOG_CRIT, "Can't bind to [%s]:%u: can't convert ip address \"%s\"",
Log(LOG_CRIT, "Can't bind to %s:%u: can't convert ip address \"%s\"", listen_addrstr, Port, listen_addrstr);
listen_addrstr, Port, listen_addrstr);
} }
return ret; return ret;
} }
@@ -394,32 +401,33 @@ set_v6_only(int af, int sock)
/* return new listening port file descriptor or -1 on failure */ /* return new listening port file descriptor or -1 on failure */
static int static int
NewListener(int af, const UINT16 Port) NewListener(const char *listen_addr, UINT16 Port)
{ {
/* Create new listening socket on specified port */ /* Create new listening socket on specified port */
ng_ipaddr_t addr; ng_ipaddr_t addr;
int sock; int sock, af;
#ifdef ZEROCONF #ifdef ZEROCONF
char name[CLIENT_ID_LEN], *info; char name[CLIENT_ID_LEN], *info;
#endif #endif
if (!InitSinaddrListenAddr(af, &addr, Port)) if (!InitSinaddrListenAddr(&addr, listen_addr, Port))
return -1; return -1;
sock = socket(ng_ipaddr_af(&addr), SOCK_STREAM, 0); af = ng_ipaddr_af(&addr);
sock = socket(af, SOCK_STREAM, 0);
if( sock < 0 ) { if( sock < 0 ) {
Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno )); Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af, strerror(errno));
return -1; return -1;
} }
af = ng_ipaddr_af(&addr);
set_v6_only(af, sock); set_v6_only(af, sock);
if( ! Init_Socket( sock )) return -1; if (!Init_Socket(sock))
return -1;
if (bind(sock, (struct sockaddr *)&addr, ng_ipaddr_salen(&addr)) != 0) { if (bind(sock, (struct sockaddr *)&addr, ng_ipaddr_salen(&addr)) != 0) {
Log( LOG_CRIT, "Can't bind socket (port %d) : %s!", Port, strerror( errno )); Log(LOG_CRIT, "Can't bind socket to address %s:%d - %s",
close( sock ); ng_ipaddr_tostr(&addr), Port, strerror(errno));
close(sock);
return -1; return -1;
} }
@@ -436,12 +444,7 @@ NewListener(int af, const UINT16 Port)
return -1; return -1;
} }
#ifdef WANT_IPV6 Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock);
if (af == AF_INET6)
Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock);
else
#endif
Log(LOG_INFO, "Now listening on %s:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock);
#ifdef ZEROCONF #ifdef ZEROCONF
/* Get best server description text */ /* Get best server description text */
@@ -876,7 +879,10 @@ Conn_Close( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient )
/* Clean up connection structure (=free it) */ /* Clean up connection structure (=free it) */
Init_Conn_Struct( Idx ); Init_Conn_Struct( Idx );
LogDebug("Shutdown of connection %d completed.", Idx ); assert(NumConnections > 0);
if (NumConnections)
NumConnections--;
LogDebug("Shutdown of connection %d completed", Idx );
} /* Conn_Close */ } /* Conn_Close */
@@ -999,7 +1005,7 @@ New_Connection( int Sock )
#endif #endif
ng_ipaddr_t new_addr; ng_ipaddr_t new_addr;
char ip_str[NG_INET_ADDRSTRLEN]; char ip_str[NG_INET_ADDRSTRLEN];
int new_sock, new_sock_len, new_Pool_Size; int new_sock, new_sock_len;
CLIENT *c; CLIENT *c;
long cnt; long cnt;
@@ -1018,6 +1024,7 @@ New_Connection( int Sock )
Log(LOG_CRIT, "fd %d: Can't convert IP address!", new_sock); Log(LOG_CRIT, "fd %d: Can't convert IP address!", new_sock);
Simple_Message(new_sock, "ERROR :Internal Server Error"); Simple_Message(new_sock, "ERROR :Internal Server Error");
close(new_sock); close(new_sock);
return -1;
} }
#ifdef TCPWRAP #ifdef TCPWRAP
@@ -1046,18 +1053,16 @@ New_Connection( int Sock )
return -1; return -1;
} }
if( new_sock >= Pool_Size ) { if ((Conf_MaxConnections > 0) &&
new_Pool_Size = new_sock + 1; (NumConnections >= (size_t) Conf_MaxConnections))
/* No free Connection Structures, check if we may accept further connections */ {
if ((( Conf_MaxConnections > 0) && Pool_Size >= Conf_MaxConnections) || Log( LOG_ALERT, "Can't accept connection: limit (%d) reached!", Conf_MaxConnections);
(new_Pool_Size < Pool_Size)) Simple_Message( new_sock, "ERROR :Connection limit reached" );
{ close( new_sock );
Log( LOG_ALERT, "Can't accept connection: limit (%d) reached!", Pool_Size ); return -1;
Simple_Message( new_sock, "ERROR :Connection limit reached" ); }
close( new_sock );
return -1;
}
if( new_sock >= Pool_Size ) {
if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), if (!array_alloc(&My_ConnArray, sizeof(CONNECTION),
(size_t)new_sock)) { (size_t)new_sock)) {
Log( LOG_EMERG, "Can't allocate memory! [New_Connection]" ); Log( LOG_EMERG, "Can't allocate memory! [New_Connection]" );
@@ -1070,7 +1075,7 @@ New_Connection( int Sock )
/* Adjust pointer to new block */ /* Adjust pointer to new block */
My_Connections = array_start(&My_ConnArray); My_Connections = array_start(&My_ConnArray);
while (Pool_Size < new_Pool_Size) while (Pool_Size <= new_sock)
Init_Conn_Struct(Pool_Size++); Init_Conn_Struct(Pool_Size++);
} }
@@ -1224,7 +1229,7 @@ Handle_Buffer( CONN_ID Idx )
/* Handle Data in Connections Read-Buffer. /* Handle Data in Connections Read-Buffer.
* Return true if a reuqest was handled, false otherwise (also returned on errors). */ * Return true if a reuqest was handled, false otherwise (also returned on errors). */
#ifndef STRICT_RFC #ifndef STRICT_RFC
char *ptr1, *ptr2; char *ptr1, *ptr2, *first_eol;
#endif #endif
char *ptr; char *ptr;
size_t len, delta; size_t len, delta;
@@ -1252,19 +1257,32 @@ Handle_Buffer( CONN_ID Idx )
return false; return false;
/* A Complete Request end with CR+LF, see RFC 2812. */ /* A Complete Request end with CR+LF, see RFC 2812. */
delta = 2;
ptr = strstr( array_start(&My_Connections[Idx].rbuf), "\r\n" ); ptr = strstr( array_start(&My_Connections[Idx].rbuf), "\r\n" );
if( ptr ) delta = 2; /* complete request */
#ifndef STRICT_RFC #ifndef STRICT_RFC
else { /* Check for non-RFC-compliant request (only CR or LF)?
/* Check for non-RFC-compliant request (only CR or LF)? Unfortunately, * Unfortunately, there are quite a few clients out there
* there are quite a few clients that do this (incl. "mIRC" :-( */ * that do this -- e. g. mIRC, BitchX, and Trillian :-( */
ptr1 = strchr( array_start(&My_Connections[Idx].rbuf), '\r' ); ptr1 = strchr(array_start(&My_Connections[Idx].rbuf), '\r');
ptr2 = strchr( array_start(&My_Connections[Idx].rbuf), '\n' ); ptr2 = strchr(array_start(&My_Connections[Idx].rbuf), '\n');
if (ptr) {
/* Check if there is a single CR or LF _before_ the
* corerct CR+LF line terminator: */
first_eol = ptr1 < ptr2 ? ptr1 : ptr2;
if (first_eol < ptr) {
/* Single CR or LF before CR+LF found */
ptr = first_eol;
delta = 1;
}
} else if (ptr1 || ptr2) {
/* No CR+LF terminated command found, but single
* CR or LF found ... */
if (ptr1 && ptr2)
ptr = ptr1 < ptr2 ? ptr1 : ptr2;
else
ptr = ptr1 ? ptr1 : ptr2;
delta = 1; delta = 1;
if( ptr1 && ptr2 ) ptr = ptr1 > ptr2 ? ptr2 : ptr1;
else if( ptr1 ) ptr = ptr1;
else if( ptr2 ) ptr = ptr2;
} }
#endif #endif
@@ -1439,7 +1457,7 @@ New_Server( int Server , ng_ipaddr_t *dest)
af_dest = ng_ipaddr_af(dest); af_dest = ng_ipaddr_af(dest);
new_sock = socket(af_dest, SOCK_STREAM, 0); new_sock = socket(af_dest, SOCK_STREAM, 0);
if (new_sock < 0) { if (new_sock < 0) {
Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno )); Log( LOG_CRIT, "Can't create socket (af %d) : %s!", af_dest, strerror( errno ));
return; return;
} }

View File

@@ -718,7 +718,7 @@ IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
/* Secret channel? */ /* Secret channel? */
if (!is_member && strchr(Channel_Modes(Chan), 's')) if (!is_member && strchr(Channel_Modes(Chan), 's'))
return CONNECTED; return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), Channel_Name(Chan));
cl2chan = Channel_FirstMember(Chan); cl2chan = Channel_FirstMember(Chan);
for (; cl2chan ; cl2chan = Channel_NextMember(Chan, cl2chan)) { for (; cl2chan ; cl2chan = Channel_NextMember(Chan, cl2chan)) {

View File

@@ -166,14 +166,12 @@ main( int argc, const char *argv[] )
{ {
ok = false; ok = false;
#ifdef DEBUG #ifdef DEBUG
if( argv[i][n] == 'd' ) if (argv[i][n] == 'd') {
{
NGIRCd_Debug = true; NGIRCd_Debug = true;
ok = true; ok = true;
} }
#endif #endif
if( argv[i][n] == 'f' ) if (argv[i][n] == 'f') {
{
if(( ! argv[i][n + 1] ) && ( i + 1 < argc )) if(( ! argv[i][n + 1] ) && ( i + 1 < argc ))
{ {
/* Ok, next character is a blank */ /* Ok, next character is a blank */
@@ -185,31 +183,38 @@ main( int argc, const char *argv[] )
ok = true; ok = true;
} }
} }
if( argv[i][n] == 'n' )
{ if (argv[i][n] == 'h') {
Show_Version();
puts(""); Show_Help(); puts("");
exit(1);
}
if (argv[i][n] == 'n') {
NGIRCd_NoDaemon = true; NGIRCd_NoDaemon = true;
ok = true; ok = true;
} }
if( argv[i][n] == 'p' ) if (argv[i][n] == 'p') {
{
NGIRCd_Passive = true; NGIRCd_Passive = true;
ok = true; ok = true;
} }
#ifdef SNIFFER #ifdef SNIFFER
if( argv[i][n] == 's' ) if (argv[i][n] == 's') {
{
NGIRCd_Sniffer = true; NGIRCd_Sniffer = true;
ok = true; ok = true;
} }
#endif #endif
if( argv[i][n] == 't' ) if (argv[i][n] == 't') {
{
configtest = true; configtest = true;
ok = true; ok = true;
} }
if( ! ok ) if (argv[i][n] == 'V') {
{ Show_Version();
exit(1);
}
if (! ok) {
printf( "%s: invalid option \"-%c\"!\n", PACKAGE_NAME, argv[i][n] ); printf( "%s: invalid option \"-%c\"!\n", PACKAGE_NAME, argv[i][n] );
printf( "Try \"%s --help\" for more information.\n", PACKAGE_NAME ); printf( "Try \"%s --help\" for more information.\n", PACKAGE_NAME );
exit( 1 ); exit( 1 );
@@ -577,8 +582,8 @@ Show_Help( void )
puts( " -s, --sniffer enable network sniffer and display all IRC traffic" ); puts( " -s, --sniffer enable network sniffer and display all IRC traffic" );
#endif #endif
puts( " -t, --configtest read, validate and display configuration; then exit" ); puts( " -t, --configtest read, validate and display configuration; then exit" );
puts( " --version output version information and exit" ); puts( " -V, --version output version information and exit" );
puts( " --help display this help and exit" ); puts( " -h, --help display this help and exit" );
} /* Show_Help */ } /* Show_Help */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -9,11 +9,8 @@
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
*/ */
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: parse.c,v 1.72 2008/02/17 13:26:42 alex Exp $";
/** /**
* @file * @file
* IRC command parser and validator. * IRC command parser and validator.
@@ -338,12 +335,35 @@ Validate_Command( UNUSED CONN_ID Idx, UNUSED REQUEST *Req, bool *Closed )
static bool static bool
Validate_Args( UNUSED CONN_ID Idx, UNUSED REQUEST *Req, bool *Closed ) Validate_Args(CONN_ID Idx, REQUEST *Req, bool *Closed)
{ {
#ifdef STRICT_RFC
int i;
#endif
assert( Idx >= 0 ); assert( Idx >= 0 );
assert( Req != NULL ); assert( Req != NULL );
*Closed = false; *Closed = false;
#ifdef STRICT_RFC
/* CR and LF are never allowed in command parameters.
* But since we do accept lines terminated only with CR or LF in
* "non-RFC-compliant mode" (besides the correct CR+LF combination),
* this check can only trigger in "strict RFC" mode; therefore we
* optimize it away otherwise ... */
for (i = 0; i < Req->argc; i++) {
if (strchr(Req->argv[i], '\r') || strchr(Req->argv[i], '\n')) {
Log(LOG_ERR,
"Invalid character(s) in parameter (connection %d, command %s)!?",
Idx, Req->command);
if (!Conn_WriteStr(Idx,
"ERROR :Invalid character(s) in parameter!"))
*Closed = true;
return false;
}
}
#endif
return true; return true;
} /* Validate_Args */ } /* Validate_Args */