Allow increasing connection limit on linux (#3799)
With this you can now support more connections on linux, even if your system header is still set to a smaller value. Make sure to increase the limit of open file handles with ulimit or other resource related settings. You can change the compile time value of supported connections with ./configure --with-maxconn=value Windows default is still 4096.
This commit is contained in:
parent
4ec0c0109f
commit
8ae788b643
25
configure
vendored
25
configure
vendored
@ -1367,7 +1367,9 @@ Optional Packages:
|
|||||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||||
--with-maxconn[=ARG] optionally set the maximum connections the core can
|
--with-maxconn[=ARG] optionally set the maximum connections the core can
|
||||||
handle (default: 16384) NOT USED YET - EXPERIMENTAL
|
handle. By default the system header value will be used.
|
||||||
|
This will only be the compile time limit, make sure
|
||||||
|
you set the correct limit with ulimit on your OS.
|
||||||
--with-outputlogin[=ARG]
|
--with-outputlogin[=ARG]
|
||||||
Specify the login-serv output name (defaults to
|
Specify the login-serv output name (defaults to
|
||||||
login-server)
|
login-server)
|
||||||
@ -3469,22 +3471,11 @@ fi
|
|||||||
# Check whether --with-maxconn was given.
|
# Check whether --with-maxconn was given.
|
||||||
if test "${with_maxconn+set}" = set; then :
|
if test "${with_maxconn+set}" = set; then :
|
||||||
withval=$with_maxconn;
|
withval=$with_maxconn;
|
||||||
if test "$withval" == "no"; then
|
if ! test "$withval" -ge 0 -o "$withval" -lt 0 2>&- ; then
|
||||||
CPPFLAGS="$CPPFLAGS -DMAXCONN=16384"
|
as_fn_error $? "Invalid argument --with-maxconn=$withval ... stopping" "$LINENO" 5
|
||||||
else
|
else
|
||||||
|
CPPFLAGS="$CPPFLAGS -DMAXCONN=$withval"
|
||||||
if ! test "$withval" -ge 0 -o "$withval" -lt 0 2>&- ; then
|
fi
|
||||||
as_fn_error $? "Invalid argument --with-maxconn=$withval ... stopping" "$LINENO" 5
|
|
||||||
else
|
|
||||||
CPPFLAGS="$CPPFLAGS -DMAXCONN=$withval"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
CPPFLAGS="$CPPFLAGS -DMAXCONN=16384"
|
|
||||||
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
19
configure.in
19
configure.in
@ -295,29 +295,24 @@ AC_ARG_ENABLE(
|
|||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Optionally set the max number of network conenctions
|
# Optionally set the maximum number of network connections
|
||||||
# the core will be support
|
# the core will be able to handle
|
||||||
#
|
#
|
||||||
AC_ARG_WITH(
|
AC_ARG_WITH(
|
||||||
[maxconn],
|
[maxconn],
|
||||||
AC_HELP_STRING(
|
AC_HELP_STRING(
|
||||||
[--with-maxconn@<:@=ARG@:>@],
|
[--with-maxconn@<:@=ARG@:>@],
|
||||||
[optionally set the maximum connections the core can handle (default: 16384) NOT USED YET - EXPERIMENTAL]
|
[optionally set the maximum connections the core can handle. By default the system header value is used.]
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
if test "$withval" == "no"; then
|
if ! test "$withval" -ge 0 -o "$withval" -lt 0 2>&- ; then
|
||||||
CPPFLAGS="$CPPFLAGS -DMAXCONN=16384"
|
AC_MSG_ERROR([Invalid argument --with-maxconn=$withval ... stopping])
|
||||||
else
|
else
|
||||||
|
CPPFLAGS="$CPPFLAGS -DMAXCONN=$withval"
|
||||||
if ! test "$withval" -ge 0 -o "$withval" -lt 0 2>&- ; then
|
|
||||||
AC_MSG_ERROR([Invalid argument --with-maxconn=$withval ... stopping])
|
|
||||||
else
|
|
||||||
CPPFLAGS="$CPPFLAGS -DMAXCONN=$withval"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
CPPFLAGS="$CPPFLAGS -DMAXCONN=16384"
|
CPPFLAGS="$CPPFLAGS"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ typedef int socklen_t;
|
|||||||
|
|
||||||
// global array of sockets (emulating linux)
|
// global array of sockets (emulating linux)
|
||||||
// fd is the position in the array
|
// fd is the position in the array
|
||||||
static SOCKET sock_arr[FD_SETSIZE];
|
static SOCKET sock_arr[MAXCONN];
|
||||||
static int sock_arr_len = 0;
|
static int sock_arr_len = 0;
|
||||||
|
|
||||||
/// Returns the socket associated with the target fd.
|
/// Returns the socket associated with the target fd.
|
||||||
@ -98,7 +98,7 @@ int sock2fd(SOCKET s)
|
|||||||
/// Returns a new fd associated with the socket.
|
/// Returns a new fd associated with the socket.
|
||||||
/// If there are too many sockets it closes the socket, sets an error and
|
/// If there are too many sockets it closes the socket, sets an error and
|
||||||
// returns -1 instead.
|
// returns -1 instead.
|
||||||
/// Since fd 0 is reserved, it returns values in the range [1,FD_SETSIZE[.
|
/// Since fd 0 is reserved, it returns values in the range [1,MAXCONN[.
|
||||||
///
|
///
|
||||||
/// @param s Socket
|
/// @param s Socket
|
||||||
/// @return New fd or -1
|
/// @return New fd or -1
|
||||||
@ -220,7 +220,7 @@ char* sErr(int code)
|
|||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
#else
|
#else
|
||||||
// Epoll based Event Dispatcher
|
// Epoll based Event Dispatcher
|
||||||
static int epoll_maxevents = (FD_SETSIZE / 2);
|
static int epoll_maxevents = (MAXCONN / 2);
|
||||||
static int epfd = SOCKET_ERROR;
|
static int epfd = SOCKET_ERROR;
|
||||||
static struct epoll_event epevent;
|
static struct epoll_event epevent;
|
||||||
static struct epoll_event *epevents = nullptr;
|
static struct epoll_event *epevents = nullptr;
|
||||||
@ -258,12 +258,12 @@ static time_t socket_data_last_tick = 0;
|
|||||||
// The connection is closed if it goes over the limit.
|
// The connection is closed if it goes over the limit.
|
||||||
#define WFIFO_MAX (1*1024*1024)
|
#define WFIFO_MAX (1*1024*1024)
|
||||||
|
|
||||||
struct socket_data* session[FD_SETSIZE];
|
struct socket_data* session[MAXCONN];
|
||||||
|
|
||||||
#ifdef SEND_SHORTLIST
|
#ifdef SEND_SHORTLIST
|
||||||
int send_shortlist_array[FD_SETSIZE];// we only support FD_SETSIZE sockets, limit the array to that
|
int send_shortlist_array[MAXCONN];// we only support MAXCONN sockets, limit the array to that
|
||||||
size_t send_shortlist_count = 0;// how many fd's are in the shortlist
|
size_t send_shortlist_count = 0;// how many fd's are in the shortlist
|
||||||
uint32 send_shortlist_set[(FD_SETSIZE+31)/32];// to know if specific fd's are already in the shortlist
|
uint32 send_shortlist_set[(MAXCONN+31)/32];// to know if specific fd's are already in the shortlist
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseFunc func_parse);
|
static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseFunc func_parse);
|
||||||
@ -483,9 +483,9 @@ int connect_client(int listen_fd)
|
|||||||
sClose(fd);
|
sClose(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if( fd >= FD_SETSIZE )
|
if( fd >= MAXCONN )
|
||||||
{// socket number too big
|
{// socket number too big
|
||||||
ShowError("connect_client: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
|
ShowError("connect_client: New socket #%d is greater than can we handle! Increase the value of MAXCONN (currently %d) for your OS to fix this!\n", fd, MAXCONN);
|
||||||
sClose(fd);
|
sClose(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -542,9 +542,9 @@ int make_listen_bind(uint32 ip, uint16 port)
|
|||||||
sClose(fd);
|
sClose(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if( fd >= FD_SETSIZE )
|
if( fd >= MAXCONN )
|
||||||
{// socket number too big
|
{// socket number too big
|
||||||
ShowError("make_listen_bind: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
|
ShowError("make_listen_bind: New socket #%d is greater than can we handle! Increase the value of MAXCONN (currently %d) for your OS to fix this!\n", fd, MAXCONN);
|
||||||
sClose(fd);
|
sClose(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -608,9 +608,9 @@ int make_connection(uint32 ip, uint16 port, bool silent,int timeout) {
|
|||||||
sClose(fd);
|
sClose(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if( fd >= FD_SETSIZE )
|
if( fd >= MAXCONN )
|
||||||
{// socket number too big
|
{// socket number too big
|
||||||
ShowError("make_connection: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE);
|
ShowError("make_connection: New socket #%d is greater than can we handle! Increase the value of MAXCONN (currently %d) for your OS to fix this!\n", fd, MAXCONN);
|
||||||
sClose(fd);
|
sClose(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1417,7 +1417,7 @@ void socket_final(void)
|
|||||||
/// Closes a socket.
|
/// Closes a socket.
|
||||||
void do_close(int fd)
|
void do_close(int fd)
|
||||||
{
|
{
|
||||||
if( fd <= 0 ||fd >= FD_SETSIZE )
|
if( fd <= 0 ||fd >= MAXCONN )
|
||||||
return;// invalid
|
return;// invalid
|
||||||
|
|
||||||
flush_fifo(fd); // Try to send what's left (although it might not succeed since it's a nonblocking socket)
|
flush_fifo(fd); // Try to send what's left (although it might not succeed since it's a nonblocking socket)
|
||||||
@ -1526,7 +1526,7 @@ int socket_getips(uint32* ips, int max)
|
|||||||
void socket_init(void)
|
void socket_init(void)
|
||||||
{
|
{
|
||||||
const char *SOCKET_CONF_FILENAME = "conf/packet_athena.conf";
|
const char *SOCKET_CONF_FILENAME = "conf/packet_athena.conf";
|
||||||
unsigned int rlim_cur = FD_SETSIZE;
|
unsigned int rlim_cur = MAXCONN;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
{// Start up windows networking
|
{// Start up windows networking
|
||||||
@ -1546,14 +1546,14 @@ void socket_init(void)
|
|||||||
#elif defined(HAVE_SETRLIMIT) && !defined(CYGWIN)
|
#elif defined(HAVE_SETRLIMIT) && !defined(CYGWIN)
|
||||||
// NOTE: getrlimit and setrlimit have bogus behaviour in cygwin.
|
// NOTE: getrlimit and setrlimit have bogus behaviour in cygwin.
|
||||||
// "Number of fds is virtually unlimited in cygwin" (sys/param.h)
|
// "Number of fds is virtually unlimited in cygwin" (sys/param.h)
|
||||||
{// set socket limit to FD_SETSIZE
|
{// set socket limit to MAXCONN
|
||||||
struct rlimit rlp;
|
struct rlimit rlp;
|
||||||
if( 0 == getrlimit(RLIMIT_NOFILE, &rlp) )
|
if( 0 == getrlimit(RLIMIT_NOFILE, &rlp) )
|
||||||
{
|
{
|
||||||
rlp.rlim_cur = FD_SETSIZE;
|
rlp.rlim_cur = MAXCONN;
|
||||||
if( 0 != setrlimit(RLIMIT_NOFILE, &rlp) )
|
if( 0 != setrlimit(RLIMIT_NOFILE, &rlp) )
|
||||||
{// failed, try setting the maximum too (permission to change system limits is required)
|
{// failed, try setting the maximum too (permission to change system limits is required)
|
||||||
rlp.rlim_max = FD_SETSIZE;
|
rlp.rlim_max = MAXCONN;
|
||||||
if( 0 != setrlimit(RLIMIT_NOFILE, &rlp) )
|
if( 0 != setrlimit(RLIMIT_NOFILE, &rlp) )
|
||||||
{// failed
|
{// failed
|
||||||
const char *errmsg = error_msg();
|
const char *errmsg = error_msg();
|
||||||
@ -1566,7 +1566,7 @@ void socket_init(void)
|
|||||||
// report limit
|
// report limit
|
||||||
getrlimit(RLIMIT_NOFILE, &rlp);
|
getrlimit(RLIMIT_NOFILE, &rlp);
|
||||||
rlim_cur = rlp.rlim_cur;
|
rlim_cur = rlp.rlim_cur;
|
||||||
ShowWarning("socket_init: failed to set socket limit to %d, setting to maximum allowed (original limit=%d, current limit=%d, maximum allowed=%d, %s).\n", FD_SETSIZE, rlim_ori, (int)rlp.rlim_cur, (int)rlp.rlim_max, errmsg);
|
ShowWarning("socket_init: failed to set socket limit to %d, setting to maximum allowed (original limit=%d, current limit=%d, maximum allowed=%d, %s).\n", MAXCONN, rlim_ori, (int)rlp.rlim_cur, (int)rlp.rlim_max, errmsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1582,7 +1582,7 @@ void socket_init(void)
|
|||||||
ShowInfo( "Server uses '" CL_WHITE "select" CL_RESET "' as event dispatcher\n" );
|
ShowInfo( "Server uses '" CL_WHITE "select" CL_RESET "' as event dispatcher\n" );
|
||||||
#else
|
#else
|
||||||
// Epoll based Event Dispatcher
|
// Epoll based Event Dispatcher
|
||||||
epfd = epoll_create( FD_SETSIZE ); // 2.6.8 or newer ignores the expected socket amount argument
|
epfd = epoll_create( MAXCONN ); // 2.6.8 or newer ignores the expected socket amount argument
|
||||||
|
|
||||||
if( epfd == SOCKET_ERROR ){
|
if( epfd == SOCKET_ERROR ){
|
||||||
ShowError( "Failed to create epoll event dispatcher: %s\n", error_msg() );
|
ShowError( "Failed to create epoll event dispatcher: %s\n", error_msg() );
|
||||||
@ -1621,7 +1621,7 @@ void socket_init(void)
|
|||||||
|
|
||||||
bool session_isValid(int fd)
|
bool session_isValid(int fd)
|
||||||
{
|
{
|
||||||
return ( fd > 0 && fd < FD_SETSIZE && session[fd] != NULL );
|
return ( fd > 0 && fd < MAXCONN && session[fd] != NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool session_isActive(int fd)
|
bool session_isActive(int fd)
|
||||||
@ -1703,7 +1703,7 @@ void send_shortlist_do_sends()
|
|||||||
send_shortlist_array[i] = send_shortlist_array[send_shortlist_count];
|
send_shortlist_array[i] = send_shortlist_array[send_shortlist_count];
|
||||||
send_shortlist_array[send_shortlist_count] = 0;
|
send_shortlist_array[send_shortlist_count] = 0;
|
||||||
|
|
||||||
if( fd <= 0 || fd >= FD_SETSIZE )
|
if( fd <= 0 || fd >= MAXCONN )
|
||||||
{
|
{
|
||||||
ShowDebug("send_shortlist_do_sends: fd is out of range, corrupted memory? (fd=%d)\n", fd);
|
ShowDebug("send_shortlist_do_sends: fd is out of range, corrupted memory? (fd=%d)\n", fd);
|
||||||
continue;
|
continue;
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#ifndef SOCKET_HPP
|
#ifndef SOCKET_HPP
|
||||||
#define SOCKET_HPP
|
#define SOCKET_HPP
|
||||||
|
|
||||||
|
#include "../config/core.hpp"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "winapi.hpp"
|
#include "winapi.hpp"
|
||||||
typedef long in_addr_t;
|
typedef long in_addr_t;
|
||||||
@ -17,6 +19,10 @@
|
|||||||
#include "cbasetypes.hpp"
|
#include "cbasetypes.hpp"
|
||||||
#include "timer.hpp" // t_tick
|
#include "timer.hpp" // t_tick
|
||||||
|
|
||||||
|
#ifndef MAXCONN
|
||||||
|
#define MAXCONN FD_SETSIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FIFOSIZE_SERVERLINK 256*1024
|
#define FIFOSIZE_SERVERLINK 256*1024
|
||||||
|
|
||||||
// socket I/O macros
|
// socket I/O macros
|
||||||
@ -103,7 +109,7 @@ struct socket_data
|
|||||||
|
|
||||||
// Data prototype declaration
|
// Data prototype declaration
|
||||||
|
|
||||||
extern struct socket_data* session[FD_SETSIZE];
|
extern struct socket_data* session[MAXCONN];
|
||||||
|
|
||||||
extern int fd_max;
|
extern int fd_max;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user