summaryrefslogtreecommitdiff
path: root/include/socketengine.h
blob: bbd34a30288b2403ba5a5c7700c59fabd7296c80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*       +------------------------------------+
 *       | Inspire Internet Relay Chat Daemon |
 *       +------------------------------------+
 *
 *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
 *                       E-mail:
 *                <brain@chatspike.net>
 *                <Craig@chatspike.net>
 *
 * Written by Craig Edwards, Craig McLure, and others.
 * This program is free but copyrighted software; see
 *            the file COPYING for details.
 *
 * ---------------------------------------------------
*/

#ifndef __SOCKETENGINE__
#define __SOCKETENGINE__

#include <vector>
#include <string>
#include <map>
#include "inspircd_config.h"
#include "globals.h"
#include "inspircd.h"
#ifdef USE_EPOLL
#include <sys/epoll.h>
#define EP_DELAY 5
#endif
#ifdef USE_KQUEUE
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#endif

/**
 * Each of these values represents a socket
 * type in our reference table (the reference
 * table itself is only accessible to
 * socketengine.cpp)
 */
const char X_EMPTY_SLOT		= 0;
const char X_LISTEN             = 1;
const char X_ESTAB_CLIENT       = 2;
const char X_ESTAB_MODULE       = 3;
const char X_ESTAB_DNS          = 4;

/**
 * To indicate that a socket is readable, we
 * mask its top bit with this X_READBIT value.
 * The socket engine can handle two types of
 * socket, readable and writeable (error sockets
 * are dealt with when read() and write() return
 * negative or zero values).
 */
const char X_READBIT            = 0x80;

/**
 * The actual socketengine class presents the
 * same interface on all operating systems, but
 * its private members and internal behaviour
 * should be treated as blackboxed, and vary
 * from system to system and upon the config
 * settings chosen by the server admin. The current
 * version supports select, epoll and kqueue.
 */
class SocketEngine : public Extensible
{

	int EngineHandle;			/* Handle to the socket engine if needed */
	int CurrentSetSize;			/* Current number of descriptors in the engine */
#ifdef USE_SELECT
	std::map<int,int> fds;			/* List of file descriptors being monitored */
	fd_set wfdset, rfdset;			/* Readable and writeable sets for select() */
#endif
#ifdef USE_KQUEUE
	struct kevent ke_list[MAX_DESCRIPTORS];	/* Up to 64k sockets for kqueue */
	struct timespec ts;			/* kqueue delay value */
#endif
#ifdef USE_EPOLL
	struct epoll_event events[MAX_DESCRIPTORS];	/* Up to 64k sockets for epoll */
#endif

public:

	/** Constructor
	 * The constructor transparently initializes
	 * the socket engine which the ircd is using.
	 * Please note that if there is a catastrophic
	 * failure (for example, you try and enable
	 * epoll on a 2.4 linux kernel) then this
	 * function may bail back to the shell.
	 */
	SocketEngine();

	/** Destructor
	 * The destructor transparently tidies up
	 * any resources used by the socket engine.
	 */
	~SocketEngine();

	/** Add a file descriptor to the engine
	 * Use AddFd to add a file descriptor to the
	 * engine and have the socket engine monitor
	 * it. You must provide a type (see the consts
	 * in socketengine.h) and a boolean flag to
	 * indicate wether to watch this fd for read
	 * or write events (there is currently no
	 * need for support of both).
	 */
	bool AddFd(int fd, bool readable, char type);

	/** Returns the type value for this file descriptor
	 * This function masks off the X_READBIT value
	 * so that the type of the socket can be obtained.
	 * The core uses this to decide where to dispatch
	 * the event to. Please note that some engines
	 * such as select() have an upper limit of 1024
	 * descriptors which may be active at any one time,
	 * where others such as kqueue have no practical
	 * limits at all.
	 */
	char GetType(int fd);

	/** Returns the maximum number of file descriptors
	 * you may store in the socket engine at any one time.
	 */
	int GetMaxFds();

	/** Returns the number of file descriptor slots
	 * which are available for storing fds.
	 */
	int GetRemainingFds();

	/** Delete a file descriptor from the engine
	 * This function call deletes a file descriptor
	 * from the engine, returning true if it succeeded
	 * and false if it failed.
	 */
	bool DelFd(int fd);

	/** Returns true if a socket exists in the socket
	 * engine's list.
	 */
	bool HasFd(int fd);

	/** Waits for an event.
	 * Please note that this doesnt wait long, only
	 * a couple of milliseconds. It returns a list
	 * of active file descriptors in the vector
	 * fdlist which the core may then act upon.
	 */
	int Wait(int* fdlist);

	/** Returns the socket engines name
	 * This returns the name of the engine for use
	 * in /VERSION responses.
	 */
	std::string GetName();
};

#endif