summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2010-04-08 20:23:00 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2010-04-08 20:23:00 +0000
commit973ecb7058325931d14a9537e5e3e57595347a10 (patch)
tree43585f36085949a1b494374572fa4e3dc25b0960
parente1ff14e0c44d0a115372a821559b782c57c793f3 (diff)
Rewrote sockets. This adds support for IPv6 and makes Anope capable of reconnecting if it loses connection to the uplink.
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2862 5417fbe8-f217-4b02-8779-1006273d7864
-rw-r--r--Changes.conf4
-rw-r--r--TODO16
-rw-r--r--data/example.conf38
-rw-r--r--include/config.h6
-rw-r--r--include/configreader.h8
-rw-r--r--include/extern.h28
-rw-r--r--include/modules.h10
-rw-r--r--include/services.h155
-rw-r--r--include/sockets.h191
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/Makefile4
-rw-r--r--src/config.c39
-rw-r--r--src/core/cs_xop.c19
-rw-r--r--src/core/db_plain.cpp2
-rw-r--r--src/core/os_shutdown.c3
-rw-r--r--src/core/os_stats.c4
-rw-r--r--src/init.c55
-rw-r--r--src/log.c4
-rw-r--r--src/main.c178
-rw-r--r--src/messages.c3
-rw-r--r--src/process.c11
-rw-r--r--src/protocol/bahamut.c2
-rw-r--r--src/protocol/inspircd11.c2
-rw-r--r--src/protocol/unreal32.c5
-rw-r--r--src/send.c8
-rw-r--r--src/servers.c9
-rw-r--r--src/sockets.cpp459
-rw-r--r--src/sockutil.c718
-rw-r--r--src/windows.cpp85
29 files changed, 1011 insertions, 1059 deletions
diff --git a/Changes.conf b/Changes.conf
index 2c3d33ceb..9174eb41f 100644
--- a/Changes.conf
+++ b/Changes.conf
@@ -9,6 +9,9 @@ options:userlen added to configure maxiumum ident length
options:hostlen added to configure maximum hostname length
db_plain:database added to configure what database file to use
options:passlen added to specify the maximum length of passwords
+uplink:ipv6 added to enable IPv6 connectivity
+options:maxretries added to specify the number of reconnect attempts allowed
+options:retrywait added to specify how long to wait between reconnect attempts
** MODIFIED CONFIGURATION DIRECTIVES **
options:encryption added enc_sha256
@@ -26,6 +29,7 @@ operserv:newsdatabase deleted because of the new database system
operserv:exceptiondatabase deleted because of the new database system
hs_request:database deleted because of the new database system
os_ignore:database deleted because of the new database system
+serverinfo:localport deleted
Anope Version 1.9.1
-------------------
diff --git a/TODO b/TODO
index 222ba6a18..9505bc8de 100644
--- a/TODO
+++ b/TODO
@@ -14,11 +14,10 @@ Legend:
[+] New database format (text, not binary - works very well for merging and so on)
[x] generic database routines modules can use to create their own database
[?] IRCd capability support: don't rely on CAPAB, provide an interface to turn capabilities on specifically
-[ ] Socket subsystem needs some serious loving
- [ ] Multiple sockets
- [ ] Asynchronous, using select() (multiple engines? not really needed..)
- [ ] Callbacks, event style, see also inspircd
- [ ] Asynchronous DNS?
+[x] Socket subsystem needs some serious loving
+ [x] Multiple sockets
+ [x] Asynchronous, using select() (multiple engines? not really needed..)
+ [x] Callbacks, event style, see also inspircd
[x] generic way to check which modes a user has set (u->HasUmode(UMODE_OPER))
[?] way for one module to depend on another... not like 2 MOD_HEADs and it being unpredictable which is loaded first..
the MOD_HEAD MOD_TAIL allows for too few combinations (interface code of insp, hooks code of insp?)
@@ -34,13 +33,15 @@ Legend:
Future
------
+[ ] Asynchronous DNS
+[ ] CIDR Akills, session exceptions, etc
+[ ] Hashing system for storing just about everything needs to die
[ ] Move a (lot) of stuff to class members as a defined interface rather than copypasta everywhere (ns_set, ns_saset!)
[?] Remote identification (1.9.1? will this break stuff?)
[ ] Language charset stuff, including collation (1.9.1? phoenix?)
[ ] Add support for +k, +q, etc type umodes
[ ] fantasy: allow replies/notifications to fantasy commands to go to the channel via notice
[?] a way for a module to queue itself (or even another module) for unloading
-[ ] add overridden form of SendGlobops accepting BotInfo
[ ] Language system is disgusting, it must die.
[ ] Modules should also have a way to add strings programatically
[ ] Should be able to add many strings by dropping a file in a set location.
@@ -71,8 +72,7 @@ Future
[ ] Reason
[ ] Unique IDs on each AKILL/blah so that networks may use them as ticket IDs
[ ] HS ACTIVATE -ALL (rob sez this all needs reviewing)
-[ ] NS MARK, CS MARK. Allow multiple marks. Combine into OS MARK?
-[ ] Method to list suspended/forbidden nicks/channels?
+[?] NS MARK, CS MARK. Allow multiple marks. Combine into OS MARK? (AKA os_info)
[?] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers?
[?] More "friendly" date displays of some things like registration time ("November 7th 2006 (2 years, 0 months, 0 days ago)")
[?] OS INJECT
diff --git a/data/example.conf b/data/example.conf
index 3cc20ad31..c372ae17d 100644
--- a/data/example.conf
+++ b/data/example.conf
@@ -91,6 +91,11 @@ uplink
host = "localhost"
/*
+ * Enable if Services should connect using IPv6
+ */
+ ipv6 = no
+
+ /*
* The port to connect to.
* The IRCd *MUST* be configured to listen on this port, and to accept
* server connections.
@@ -132,17 +137,13 @@ serverinfo
/*
* The local address that Services will bind to before connecting to the remote
- * server. This may be useful for multihomed hosts. If neither of these are given,
- * Services will let the Operating System choose the local address. If only a
- * hostname is specified, Services will bind to that address but let the Operating
- * System choose the local port. These directives are optional, and may be overridden
- * with the -local command-line option when starting Services.
+ * server. This may be useful for multihomed hosts. If ommited, Services will let
+ * the Operating System choose the local address. This directive is optional.
*
- * If you don't know what this means or don't need to use it, just leave these
+ * If you don't know what this means or don't need to use it, just leave this
* directives commented out.
*/
#localhost = "nowhere."
- #localport = 0
/*
* This directive instructs Anope which IRCd Protocol to speak when connecting.
@@ -532,15 +533,26 @@ options
*/
#enablelogchannel = yes
- /*
- * Default modes for mode lock, these are set on newly registered channels.
- */
+ /*
+ * Default modes for mode lock, these are set on newly registered channels.
+ */
mlock = "+nrt"
- /*
- * Modes to set on service bots when they join channels, comment this out for no modes
- */
+ /*
+ * Modes to set on service bots when they join channels, comment this out for no modes
+ */
botmodes = "ao"
+
+ /*
+ * How many times services should attempt to reconnect to the uplink before giving up
+ * Comment this out to never give up.
+ */
+ maxretries = 10
+
+ /*
+ * How long to wait between connection retries, in seconds.
+ */
+ retrywait = 60
}
diff --git a/include/config.h b/include/config.h
index a43b17f3e..1aaf5a47c 100644
--- a/include/config.h
+++ b/include/config.h
@@ -25,9 +25,6 @@
/* Name of log file (in Services directory) */
#define LOG_FILENAME "services.log"
-/* Maximum amount of data from/to the network to buffer (bytes). */
-#define NET_BUFSIZE 65536
-
/******************* END OF USER-CONFIGURABLE SECTION ********************/
/* Size of input buffer (note: this is different from BUFSIZ)
@@ -35,6 +32,9 @@
* things will happen. */
#define BUFSIZE 1024
+/* Maximum amount of data from/to the network to buffer (bytes). */
+#define NET_BUFSIZE 65536
+
/**************************************************************************/
#endif /* CONFIG_H */
diff --git a/include/configreader.h b/include/configreader.h
index a461c1f15..c6dbbefb8 100644
--- a/include/configreader.h
+++ b/include/configreader.h
@@ -384,8 +384,6 @@ class ServerConfig
/* Host to connect to **/
char *LocalHost;
- /* Port */
- unsigned LocalPort;
/* List of uplink servers to try and connect to */
std::list<Uplink *> Uplinks;
@@ -475,7 +473,7 @@ class ServerConfig
bool ForceForbidReason;
/* Services should use privmsgs instead of notices */
bool UsePrivmsg;
- /* Services only respond to full PRIVMSG client@services.server.name messaegs */
+ /* Services only respond to full PRIVMSG client@services.server.name messages */
bool UseStrictPrivMsg;
/* Dump a core file if we crash */
bool DumpCore;
@@ -490,6 +488,10 @@ class ServerConfig
std::string MLock;
/* Default botmodes on channels, defaults to ao */
std::string BotModes;
+ /* How many times to try and reconnect to the uplink before giving up */
+ unsigned MaxRetries;
+ /* How long to wait between connection attempts */
+ int RetryWait;
/* Services can use email */
bool UseMail;
diff --git a/include/extern.h b/include/extern.h
index ccff00e58..983f61af5 100644
--- a/include/extern.h
+++ b/include/extern.h
@@ -244,14 +244,14 @@ E int protocoldebug;
E int is44;
E int quitting;
-E int delayed_quit;
+E int shutting_down;
E const char *quitmsg;
-E char inbuf[BUFSIZE];
-E int servsock;
E int save_data;
E int got_alarm;
E time_t start_time;
+E Socket *UplinkSock;
+
E void save_databases();
E void expire_all();
E void sighandler(int signum);
@@ -455,7 +455,7 @@ E int delete_ignore(const char *nick);
E int clear_ignores();
E int split_buf(char *buf, const char ***argv, int colon_special);
-E void process();
+E void process(const std::string &buf);
/**** send.c ****/
@@ -485,7 +485,7 @@ E void CapabParse(int ac, const char **av);
E int is_ulined(const char *server);
E int is_sync(Server *server);
-E Server *new_server(Server * uplink, const char *name, const char *desc, ServerFlag flag, const char *suid);
+E Server *new_server(Server * uplink, const char *name, const char *desc, ServerFlag flag, const std::string &suid);
E Server *findserver(Server *s, const char *name);
@@ -538,20 +538,10 @@ E void slist_pack(SList *slist);
E int slist_remove(SList *slist, void *item);
E int slist_setcapacity(SList *slist, int16 capacity);
-/**** sockutil.c ****/
-
-E int32 total_read, total_written;
-E int32 read_buffer_len();
-E int32 write_buffer_len();
-
-E int sgetc(ano_socket_t s);
-E char *sgets(char *buf, int len, ano_socket_t s);
-E char *sgets2(char *buf, int len, ano_socket_t s);
-E int sread(ano_socket_t s, char *buf, int len);
-E int sputs(char *str, ano_socket_t s);
-E int sockprintf(ano_socket_t s, const char *fmt, ...);
-E int conn(const char *host, int port, const char *lhost, int lport);
-E void disconn(ano_socket_t s);
+/**** sockets.cpp ****/
+E SocketEngine socketEngine;
+E int32 TotalRead;
+E int32 TotalWritten;
/**** users.c ****/
diff --git a/include/modules.h b/include/modules.h
index bf178d72d..88a605acd 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -671,10 +671,14 @@ class CoreExport Module
*/
virtual void OnPreServerConnect() { }
- /** Called when anope connects to its uplink
+ /** Called when Anope connects to its uplink
*/
virtual void OnServerConnect() { }
+ /** Called when Anope disconnects from its uplink, before it tries to reconnect
+ */
+ virtual void OnServerDisconnect() { }
+
/** Called before the database expire routines are called
* Note: Code that is in seperate expiry routines should just be done
* when we save the DB, theres no need to have both
@@ -1202,8 +1206,8 @@ enum Implementation
I_OnModuleLoad, I_OnModuleUnload,
/* Other */
- I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnPreCommandRun, I_OnPreCommand, I_OnPostCommand,
- I_OnPreDatabaseExpire, I_OnPreRestart, I_OnRestart, I_OnPreShutdown, I_OnShutdown, I_OnSignal,
+ I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnServerDisconnect, I_OnPreCommandRun, I_OnPreCommand,
+ I_OnPostCommand, I_OnPreDatabaseExpire, I_OnPreRestart, I_OnRestart, I_OnPreShutdown, I_OnShutdown, I_OnSignal,
I_OnServerQuit, I_OnTopicUpdated,
I_OnEncrypt, I_OnEncryptInPlace, I_OnEncryptCheckLen, I_OnDecrypt, I_OnCheckPassword,
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
diff --git a/include/services.h b/include/services.h
index 7e6783404..ea6b89364 100644
--- a/include/services.h
+++ b/include/services.h
@@ -19,28 +19,23 @@
#include "sysconf.h"
#include "config.h"
-#ifndef MAX_CMD_HASH
-#define MAX_CMD_HASH 1024
-#endif
-
/* Some SUN fixs */
#ifdef __sun
-/* Solaris specific code, types that do not exist in Solaris'
- * sys/types.h
- **/
-#undef u_int8_t
-#undef u_int16_t
-#undef u_int32_t
-#undef u_int_64_t
-#define u_int8_t uint8_t
-#define u_int16_t uint16_t
-#define u_int32_t uint32_t
-#define u_int64_t uint64_t
-
-#ifndef INADDR_NONE
-#define INADDR_NONE (-1)
-#endif
-
+ /* Solaris specific code, types that do not exist in Solaris'
+ * sys/types.h
+ **/
+# undef u_int8_t
+# undef u_int16_t
+# undef u_int32_t
+# undef u_int_64_t
+# define u_int8_t uint8_t
+# define u_int16_t uint16_t
+# define u_int32_t uint32_t
+# define u_int64_t uint64_t
+
+# ifndef INADDR_NONE
+# define INADDR_NONE (-1)
+# endif
#endif
@@ -49,63 +44,57 @@
#include <stdlib.h>
#include <string.h>
-/* Windows does not have: unistd.h, grp.h, netdb.h, netinet/in.h, sys/socket.h, sys/time.h
- * Windows requires: winsock.h
- * -- codemastr
- */
-
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
#include <signal.h>
#include <time.h>
#include <errno.h>
-
-#ifndef _WIN32
-#include <grp.h>
-#endif
-
#include <limits.h>
-#ifndef _WIN32
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#else
-#include <winsock.h>
-#include <windows.h>
-#endif
-
-#include <sys/stat.h> /* for umask() on some systems */
+#include <sys/stat.h> /* for umask() on some systems */
#include <sys/types.h>
-#ifdef HAVE_GETTIMEOFDAY
-#include <sys/time.h>
-#endif
-
-#ifdef _WIN32
-#include <sys/timeb.h>
-#include <direct.h>
-#include <io.h>
-#endif
-
#include <fcntl.h>
#ifndef _WIN32
-#ifdef HAVE_BACKTRACE
-#include <execinfo.h>
-#endif
-#endif
-
-#ifndef _WIN32
-#include <dirent.h>
+# include <unistd.h>
+# include <grp.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <sys/socket.h>
+# include <dirent.h>
+# ifdef HAVE_BACKTRACE
+# include <execinfo.h>
+# endif
+# define DllExport
+# define CoreExport
+# define MARK_DEPRECATED __attribute((deprecated))
+#else
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <windows.h>
+# include <sys/timeb.h>
+# include <direct.h>
+# include <io.h>
+# ifdef MODULE_COMPILE
+# define CoreExport __declspec(dllimport)
+# define DllExport __declspec(dllexport)
+# else
+# define CoreExport __declspec(dllexport)
+# define DllExport __declspec(dllimport)
+# endif
+/* VS2008 hates having this define before its own */
+# define vsnprintf _vsnprintf
+/* We have our own inet_pton and inet_ntop (Windows doesn't have its own) */
+# define inet_pton inet_pton_
+# define inet_ntop inet_ntop_
+# define MARK_DEPRECATED
+
+extern CoreExport int inet_pton(int af, const char *src, void *dst);
+extern CoreExport const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
-#ifdef _WIN32
-/* VS2008 hates having this define before its own */
-#define vsnprintf _vsnprintf
+#ifdef HAVE_GETTIMEOFDAY
+# include <sys/time.h>
#endif
#if HAVE_STRINGS_H
@@ -116,8 +105,6 @@
# include <sys/select.h>
#endif
-#include "sockets.h"
-
#ifndef va_copy
# ifdef __va_copy
# define VA_COPY(DEST,SRC) __va_copy((DEST),(SRC))
@@ -168,25 +155,6 @@ extern int strncasecmp(const char *, const char *, size_t);
# undef int32
#endif
-#ifndef _WIN32
- #define MARK_DEPRECATED __attribute((deprecated))
-#else
- #define MARK_DEPRECATED
-#endif
-
-#ifdef _WIN32
-# ifdef MODULE_COMPILE
-# define CoreExport __declspec(dllimport)
-# define DllExport __declspec(dllexport)
-# else
-# define CoreExport __declspec(dllexport)
-# define DllExport __declspec(dllimport)
-# endif
-#else
-# define DllExport
-# define CoreExport
-#endif
-
/** This definition is used as shorthand for the various classes
* and functions needed to make a module loadable by the OS.
* It defines the class factory and external init_module function.
@@ -230,7 +198,7 @@ extern int strncasecmp(const char *, const char *, size_t);
#include "defs.h"
#include "slist.h"
-/* pull in the various bits of STL to pull in */
+/* Pull in the various bits of STL */
#include <iostream>
#include <string>
#include <map>
@@ -239,6 +207,7 @@ extern int strncasecmp(const char *, const char *, size_t);
#include <vector>
#include <deque>
#include <bitset>
+#include <set>
/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
* When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or
@@ -302,6 +271,13 @@ class ModuleException : public CoreException
virtual ~ModuleException() throw() {}
};
+
+/*************************************************************************/
+
+#include "sockets.h"
+
+/*************************************************************************/
+
/** Class with the ability to keep flags on items, they should extend from this
* where T is an enum.
*/
@@ -1107,11 +1083,14 @@ struct Uplink {
char *host;
unsigned port;
char *password;
- Uplink(const char *_host, int _port, const char *_password)
+ bool ipv6;
+
+ Uplink(const char *_host, int _port, const char *_password, bool _ipv6)
{
host = sstrdup(_host);
port = _port;
password = sstrdup(_password);
+ ipv6 = _ipv6;
}
~Uplink()
{
diff --git a/include/sockets.h b/include/sockets.h
index c722fbb1e..3277c1b9f 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -15,34 +15,171 @@
#define SOCKETS_H
#ifdef _WIN32
-typedef SOCKET ano_socket_t;
-#define ano_sockread(fd, buf, len) recv(fd, buf, len, 0)
-#define ano_sockwrite(fd, buf, len) send(fd, buf, len, 0)
-#define ano_sockclose(fd) closesocket(fd)
-#define ano_sockgeterr() WSAGetLastError()
-#define ano_sockseterr(err) WSASetLastError(err)
-/* ano_sockstrerror in sockutil.c */
-extern char *ano_sockstrerror(int);
-/* ano_socksetnonb in sockutil.c */
-#define ano_sockerrnonb(err) (err == WSAEINPROGRESS || err == WSAEWOULDBLOCK)
-#define SOCKERR_EBADF WSAENOTSOCK
-#define SOCKERR_EINTR WSAEINTR
-#define SOCKERR_EINVAL WSAEINVAL
-#define SOCKERR_EINPROGRESS WSAEINPROGRESS
+#define CloseSocket closesocket
#else
-typedef int ano_socket_t;
-#define ano_sockread(fd, buf, len) read(fd, buf, len)
-#define ano_sockwrite(fd, buf, len) write(fd, buf, len)
-#define ano_sockclose(fd) close(fd)
-#define ano_sockgeterr() errno
-#define ano_sockseterr(err) errno = err
-#define ano_sockstrerror(err) strerror(err)
-#define ano_socksetnonb(fd) fcntl(fd, F_SETFL, O_NONBLOCK)
-#define ano_sockerrnonb(err) (err == EINPROGRESS)
-#define SOCKERR_EBADF EBADF
-#define SOCKERR_EINTR EINTR
-#define SOCKERR_EINVAL EINVAL
-#define SOCKERR_EINPROGRESS EINPROGRESS
+#define CloseSocket close
#endif
+class SocketException : public CoreException
+{
+ public:
+ /** Default constructor for socket exceptions
+ * @param message Error message
+ */
+ SocketException(const std::string &message) : CoreException(message) { }
+
+ /** Default destructor
+ * @throws Nothing
+ */
+ virtual ~SocketException() throw() { }
+};
+
+class CoreExport Socket
+{
+ private:
+ /** Read from the socket
+ * @param buf Buffer to read to
+ * @param sz How much to read
+ * @return Number of bytes recieved
+ */
+ virtual int RecvInternal(char *buf, size_t sz) const;
+
+ /** Write to the socket
+ * @param buf What to write
+ * @return Number of bytes sent, -1 on error
+ */
+ virtual int SendInternal(const std::string &buf) const;
+
+ protected:
+ /* Socket FD */
+ int Sock;
+ /* Host this socket is connected to */
+ std::string TargetHost;
+ /* Port we're connected to */
+ int Port;
+ /* IP this socket is bound to */
+ std::string BindHost;
+ /* Is this an IPv6 socket? */
+ bool IPv6;
+
+ /* Messages to be written to the socket */
+ std::string WriteBuffer;
+ /* Part of a message not totally yet recieved */
+ std::string extrabuf;
+ /* How much data was recieved from the socket */
+ size_t RecvLen;
+
+ public:
+ /** Default constructor
+ * @param nTargetHost Hostname to connect to
+ * @param nPort Port to connect to
+ * @param nBindHos Host to bind to when connecting
+ * @param nIPv6 true to use IPv6
+ */
+ Socket(const std::string &nTargetHost, int nPort, const std::string &nBindHost = "", bool nIPv6 = false);
+
+ /** Default destructor
+ */
+ virtual ~Socket();
+
+ /** Get the socket FD for this socket
+ * @return The fd
+ */
+ virtual int GetSock() const;
+
+ /** Check if this socket is IPv6
+ * @return true or false
+ */
+ bool IsIPv6() const;
+
+ /** Called when there is something to be read from thie socket
+ * @return true on success, false to kill this socket
+ */
+ virtual bool ProcessRead();
+
+ /** Called when this socket becomes writeable
+ * @return true on success, false to drop this socket
+ */
+ virtual bool ProcessWrite();
+
+ /** Called when there is an error on this socket
+ */
+ virtual void ProcessError();
+
+ /** Called with a message recieved from the socket
+ * @param buf The message
+ * @return true on success, false to kill this socket
+ */
+ virtual bool Read(const std::string &buf);
+
+ /** Write to the socket
+ * @param message The message to write
+ */
+ void Write(const char *message, ...);
+ void Write(std::string &message);
+
+ /** Get the length of the read buffer
+ * @return The length of the read buffer
+ */
+ size_t ReadBufferLen() const;
+
+ /** Get the length of the write buffer
+ * @return The length of the write buffer
+ */
+ size_t WriteBufferLen() const;
+};
+
+class CoreExport SocketEngine
+{
+ private:
+ /* List of sockets that need to be deleted */
+ std::set<Socket *> OldSockets;
+ /* FDs to read */
+ fd_set ReadFDs;
+ /* FDs that want writing */
+ fd_set WriteFDs;
+ /* Max FD */
+ int MaxFD;
+
+ /** Unmark a socket as writeable
+ * @param s The socket
+ */
+ void ClearWriteable(Socket *s);
+ public:
+ /* Set of sockets */
+ std::set<Socket *> Sockets;
+
+ /** Constructor
+ */
+ SocketEngine();
+
+ /** Destructor
+ */
+ virtual ~SocketEngine();
+
+ /** Add a socket to the socket engine
+ * @param s The socket
+ */
+ void AddSocket(Socket *s);
+
+ /** Delete a socket from the socket engine
+ * @param s The socket
+ */
+ void DelSocket(Socket *s);
+
+ /** Mark a socket as wanting to be written to
+ * @param s The socket
+ */
+ void MarkWriteable(Socket *s);
+
+ /** Called to iterate through each socket and check for activity
+ */
+ void Process();
+
+ /** Get the last socket error
+ * @return The error
+ */
+ const std::string GetError() const;
+};
+
#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a6343e8c3..4bad367b4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -64,9 +64,9 @@ endif(MSVC)
# Generate the Anope executable and set it's linker flags, also set it to export it's symbols even though it's not a module
add_executable(${PROGRAM_NAME} ${SRC_SRCS})
set_target_properties(${PROGRAM_NAME} PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${LDFLAGS}" ENABLE_EXPORTS ON)
-# On Windows, also link Anope to the wsock32 library, as well as set the version
+# On Windows, also link Anope to the wsock32 and Ws2_32 library, as well as set the version
if(WIN32)
- target_link_libraries(${PROGRAM_NAME} wsock32 ${WIN32_MEMORY})
+ target_link_libraries(${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY})
set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
endif(WIN32)
# Building the Anope executable requires the language files to be compiled first as well as the version.h header to be generated
diff --git a/src/Makefile b/src/Makefile
index e5a883d1b..949e7e8ec 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,7 @@
OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o commands.o compat.o \
config.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \
memory.o memoserv.o messages.o misc.o modules.o nickserv.o operserv.o \
- process.o protocol.o send.o servers.o sessions.o slist.o sockutil.o opertype.o users.o module.o modulemanager.o configreader.o \
+ process.o protocol.o send.o servers.o sessions.o slist.o sockets.o opertype.o users.o module.o modulemanager.o configreader.o \
wildcard.o nickcore.o nickalias.o timers.o modes.o regchannel.o
INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \
@@ -71,7 +71,7 @@ send.o: send.c $(INCLUDES)
servers.o: servers.c $(INCLUDES)
sessions.o: sessions.c $(INCLUDES)
slist.o: slist.c $(INCLUDES)
-sockutil.o: sockutil.c $(INCLUDES)
+sockets.o: sockets.cpp $(INCLUDES)
opertype.o: opertype.cpp $(INCLUDES)
users.o: users.c $(INCLUDES)
vsnprintf.o: vsnprintf.c $(INCLUDES)
diff --git a/src/config.c b/src/config.c
index 70505c8c6..f023d07c2 100644
--- a/src/config.c
+++ b/src/config.c
@@ -144,7 +144,7 @@ void ServerConfig::ValidateHostname(const char *p, const std::string &tag, const
if (!strcasecmp(p, "localhost"))
return;
- int num_dots = 0;
+ int num_dots = 0, num_seps = 0;
if (*p)
{
if (*p == '.')
@@ -157,9 +157,13 @@ void ServerConfig::ValidateHostname(const char *p, const std::string &tag, const
throw ConfigException(std::string("The value of <") + tag + ":" + val + "> is not a valid hostname");
case '.':
++num_dots;
+ break;
+ case ':':
+ ++num_seps;
+ break;
}
}
- if (!num_dots)
+ if (!num_dots && !num_seps)
throw ConfigException(std::string("The value of <") + tag + ":" + val + "> is not a valid hostname");
}
}
@@ -382,8 +386,9 @@ bool DoUplink(ServerConfig *conf, const char *, const char **, ValueList &values
if (!bail)
return true;
// Validation variables
- const char *host = values[0].GetString(), *password = values[2].GetString();
- int port = values[1].GetInteger();
+ const char *host = values[0].GetString(), *password = values[3].GetString();
+ int port = values[2].GetInteger();
+ bool ipv6 = values[1].GetBool();
ValueItem vi_host(host), vi_port(port), vi_password(password);
// Validate the host to make sure it is not empty
if (!ValidateNotEmpty(conf, "uplink", "host", vi_host))
@@ -395,7 +400,7 @@ bool DoUplink(ServerConfig *conf, const char *, const char **, ValueList &values
if (!ValidateNotEmpty(conf, "uplink", "password", vi_password))
throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
// If we get here, all the values are valid, we'll add it to the Uplinks list
- Config.Uplinks.push_back(new Uplink(host, port, password));
+ Config.Uplinks.push_back(new Uplink(host, port, password, ipv6));
return true;
}
@@ -597,7 +602,6 @@ int ServerConfig::Read(bool bail)
{"serverinfo", "name", "", new ValueContainerChar(&Config.ServerName), DT_HOSTNAME | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "description", "", new ValueContainerChar(&Config.ServerDesc), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "localhost", "", new ValueContainerChar(&Config.LocalHost), DT_HOSTNAME | DT_NORELOAD, NoValidation},
- {"serverinfo", "localport", "0", new ValueContainerUInt(&Config.LocalPort), DT_UINTEGER | DT_NORELOAD, ValidatePort},
{"serverinfo", "type", "", new ValueContainerChar(&Config.IRCDModule), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "id", "", new ValueContainerChar(&Config.Numeric), DT_NOSPACES | DT_NORELOAD, NoValidation},
{"serverinfo", "ident", "", new ValueContainerChar(&Config.ServiceUser), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
@@ -645,6 +649,8 @@ int ServerConfig::Read(bool bail)
{"options", "enablelogchannel", "no", new ValueContainerBool(&LogChan), DT_BOOLEAN, NoValidation},
{"options", "mlock", "+nrt", new ValueContainerString(&Config.MLock), DT_STRING, NoValidation},
{"options", "botmodes", "", new ValueContainerString(&Config.BotModes), DT_STRING, NoValidation},
+ {"options", "maxretries", "10", new ValueContainerUInt(&Config.MaxRetries), DT_UINTEGER, NoValidation},
+ {"options", "retrywait", "60", new ValueContainerInt(&Config.RetryWait), DT_INTEGER, ValidateNotZero},
{"nickserv", "nick", "NickServ", new ValueContainerChar(&Config.s_NickServ), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty