Skip to content

Commit

Permalink
added REUSEPORT and namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
ColumPaget committed Oct 9, 2020
1 parent 40a5fa9 commit eda1403
Show file tree
Hide file tree
Showing 16 changed files with 108 additions and 1,799 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
CC = gcc
CFLAGS = -g -O2
CPPFLAGS =
LIBS = -lcrypt -lcrypto -lssl -lpam -lcap -lc -lc -lz libUseful/libUseful.a
LIBS = -lcrypt -lcrypto -lssl -lpam -lcap -lz libUseful/libUseful.a
INSTALL=/bin/install -c
prefix=/usr/local
exec_prefix=${prefix}
bindir=${exec_prefix}/sbin
sysconfdir=${prefix}/etc
FLAGS=$(CFLAGS) $(CPPFLAGS) -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -D_FILE_OFFSET_BITS=64 -DHAVE_LIBZ=1 -DHAVE_LIBC=1 -DHAVE_LIBC=1 -DHAVE_LIBCAP=1 -DUSE_LINUX_CAPABILITIES=1 -DHAVE_LIBPAM=1 -DHAVE_LIBSSL=1 -DHAVE_LIBCRYPTO=1 -DHAVE_LIBCRYPT=1 -DHAVE_SHADOW_H=1
FLAGS=$(CFLAGS) $(CPPFLAGS) -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -D_FILE_OFFSET_BITS=64 -DHAVE_LIBZ=1 -DHAVE_LIBCAP=1 -DUSE_LINUX_CAPABILITIES=1 -DHAVE_LIBPAM=1 -DHAVE_LIBSSL=1 -DHAVE_LIBCRYPTO=1 -DHAVE_LIBCRYPT=1 -DHAVE_SHADOW_H=1
OBJ=auth_access_token.o Authenticate.o auth_client_certificate.o auth_alaya_native.o auth_unix.o auth_pam.o MimeType.o DavProps.o Settings.o common.o server.o cgi.o FileProperties.o tar.o directory_listing.o FileDetailsPage.o VPath.o ChrootHelper.o UserAdminScreen.o Events.o ID3.o upload.o proxy.o websocket.o icecast.o xssi.o libUseful/libUseful.a
EXE=alaya

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ SanitizeAllowTags=<tag list> List of HTML tags allowed to be used in 'POST' to
UserAgentSettings=UserAgentString,Settings Settings to be applied when a particular user agent string is seen.
FileCacheTime=<seconds> Amount of time to recommend the browser caches documents for.
HttpKeepAlive=<yes|no> Use http keep-alive
ReusePort=<yes|no> Bind server socket with SO_REUSEPORT allowing multiple server processes to bind to the same port (on by default).
UseNamespaces=<yes|no> Use linux namespaces to isolate the connection-handler processes (on by default).
MaxMemory=<max bytes> Maximum amount of memory per alaya process. A suffix can be used to express the size as, for instance, 1G, 2M, 900k
MaxStack=<max bytes> Maximum Stack Size. A suffix can be used to express the size as, for instance, 1G, 2M, 900k
PackFormats=<list> List of 'pack formats' to offer in the 'download as packed' item on the directory page.
Expand Down
18 changes: 14 additions & 4 deletions Settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,11 @@ void ParseConfigItem(const char *ConfigLine)
{
const char *ConfTokens[]={"include","Chroot","Chhome","AllowUsers","DenyUsers","Port","LogFile","AuthPath","BindAddress","LogPasswords","HttpMethods","AuthMethods","DefaultUser","DefaultGroup","Path","FileType","LogVerbose","AuthRealm","Compression","DirListType","DisplayNameLen","MaxLogSize","ScriptHandler","ScriptHashFile","WebsocketHandler","LookupClientName","SanitizeAllowTags","CustomHeader","UserAgentSettings",
"SSLKey","SSLCert","SSLCiphers","SSLDHParams","SSLClientCertificate","SSLVerifyPath", "SSLVersion",
"Event","FileCacheTime","HttpKeepAlive","AccessTokenKey","Timezone","MaxMemory","MaxStack","ActivityTimeout","PackFormats","Admin","AllowProxy", "DenyProxy", NULL};
"Event","FileCacheTime","HttpKeepAlive","AccessTokenKey","Timezone","MaxMemory","MaxStack","ActivityTimeout","PackFormats","Admin","AllowProxy", "DenyProxy", "UseNamespaces", "ReusePort",
NULL};
typedef enum {CT_INCLUDE,CT_CHROOT, CT_CHHOME, CT_ALLOWUSERS,CT_DENYUSERS,CT_PORT, CT_LOGFILE,CT_AUTHFILE,CT_BINDADDRESS,CT_LOGPASSWORDS,CT_HTTPMETHODS, CT_AUTHMETHODS,CT_DEFAULTUSER, CT_DEFAULTGROUP, CT_PATH, CT_FILETYPE, CT_LOG_VERBOSE, CT_AUTH_REALM, CT_COMPRESSION, CT_DIRTYPE, CT_DISPLAYNAMELEN, CT_MAXLOGSIZE, CT_SCRIPTHANDLER, CT_SCRIPTHASHFILE, CT_WEBSOCKETHANDLER, CT_LOOKUPCLIENT, CT_SANITIZEALLOW, CT_CUSTOMHEADER, CT_USERAGENTSETTINGS,
CT_SSLKEY, CT_SSLCERT, CT_SSLCIPHERS, CT_SSLDHPARAMS, CT_CLIENT_CERTIFICATION, CT_SSLVERIFY_PATH, CT_SSL_VERSION,
CT_EVENT, CT_FILE_CACHE_TIME, CT_SESSION_KEEPALIVE, CT_ACCESS_TOKEN_KEY, CT_TIMEZONE, CT_MAX_MEM, CT_MAX_STACK, CT_ACTIVITY_TIMEOUT, CT_ARCHIVE_FORMATS, CT_ADMIN, CT_ALLOWPROXY, CT_DENYPROXY} TConfigTokens;
CT_EVENT, CT_FILE_CACHE_TIME, CT_SESSION_KEEPALIVE, CT_ACCESS_TOKEN_KEY, CT_TIMEZONE, CT_MAX_MEM, CT_MAX_STACK, CT_ACTIVITY_TIMEOUT, CT_ARCHIVE_FORMATS, CT_ADMIN, CT_ALLOWPROXY, CT_DENYPROXY, CT_USE_NAMESPACES, CT_REUSE_PORT} TConfigTokens;

char *Token=NULL;
const char *ptr;
Expand Down Expand Up @@ -220,7 +221,7 @@ switch(TokType)
break;

case CT_LOGPASSWORDS:
// Settings.Flags |= FLAG_LOGPASSWORDS;
//Settings.Flags |= FLAG_LOGPASSWORDS;
break;

case CT_DISPLAYNAMELEN:
Expand Down Expand Up @@ -423,6 +424,15 @@ switch(TokType)
SettingsParseProxyConf(FALSE, ptr);
break;

case CT_USE_NAMESPACES:
if (strtobool(ptr)) Settings.Flags |= FLAG_USE_UNSHARE;
else Settings.Flags &= ~FLAG_USE_UNSHARE;
break;

case CT_REUSE_PORT:
if (strtobool(ptr)) Settings.Flags |= FLAG_USE_REUSEPORT;
else Settings.Flags &= ~FLAG_USE_REUSEPORT;
break;
}

Destroy(Token);
Expand Down Expand Up @@ -780,7 +790,7 @@ Settings.LogPath=CopyStr(Settings.LogPath,"SYSLOG");
Settings.ConfigPath=CopyStr(Settings.ConfigPath,"/etc/alaya.conf");
Settings.DefaultDir=CopyStr(Settings.DefaultDir,"./");
Settings.BindAddress=CopyStr(Settings.BindAddress,"");
Settings.Flags |= FLAG_KEEPALIVES;
Settings.Flags |= FLAG_KEEPALIVES | FLAG_USE_REUSEPORT | FLAG_USE_UNSHARE;
Settings.DirListFlags=DIR_SHOWFILES | DIR_FANCY;
Settings.AuthFlags=FLAG_AUTH_REQUIRED | FLAG_AUTH_COOKIE;
Settings.AuthPath=CopyStr(Settings.AuthPath,"/etc/alaya.auth:~/.alaya/alaya.auth");
Expand Down
2 changes: 2 additions & 0 deletions Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#define FLAG_PFS_GENERATE 64
#define FLAG_COMPRESS 256
#define FLAG_PARTIAL_COMPRESS 512
#define FLAG_USE_UNSHARE 1024
#define FLAG_USE_REUSEPORT 2048
#define FLAG_CHECK_SCRIPTS 4096
#define FLAG_LOGOUT_AVAILABLE 8192
#define FLAG_LOOKUP_CLIENT 16384
Expand Down
2 changes: 1 addition & 1 deletion common.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "Authenticate.h"

TSettings Settings;
char *Version="3.2";
char *Version="4.0";

void SetTimezoneEnv()
{
Expand Down
12 changes: 6 additions & 6 deletions config.status
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ $config_files
Report bugs to the package provider."

ac_cs_config="'--enable-ssl' '--enable-unshare'"
ac_cs_config="'--enable-ssl' '--enable-simd'"
ac_cs_version="\
config.status
configured by ./configure, generated by GNU Autoconf 2.69,
Expand All @@ -427,7 +427,7 @@ Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

ac_pwd='/home/metacosm89/Alaya'
ac_pwd='/home/colum/work/alaya'
srcdir='.'
INSTALL='/bin/install -c'
test -n "$AWK" || AWK=awk
Expand Down Expand Up @@ -496,7 +496,7 @@ if $ac_cs_silent; then
fi

if $ac_cs_recheck; then
set X /bin/sh './configure' '--enable-ssl' '--enable-unshare' $ac_configure_extra_args --no-create --no-recursion
set X /bin/sh './configure' '--enable-ssl' '--enable-simd' $ac_configure_extra_args --no-create --no-recursion
shift
$as_echo "running CONFIG_SHELL=/bin/sh $*" >&6
CONFIG_SHELL='/bin/sh'
Expand Down Expand Up @@ -603,13 +603,13 @@ S["CC"]="gcc"
S["target_alias"]=""
S["host_alias"]=""
S["build_alias"]=""
S["LIBS"]="-lcrypt -lcrypto -lssl -lpam -lcap -lc -lc -lz "
S["LIBS"]="-lcrypt -lcrypto -lssl -lpam -lcap -lz "
S["ECHO_T"]=""
S["ECHO_N"]="-n"
S["ECHO_C"]=""
S["DEFS"]="-DPACKAGE_NAME=\\\"\\\" -DPACKAGE_TARNAME=\\\"\\\" -DPACKAGE_VERSION=\\\"\\\" -DPACKAGE_STRING=\\\"\\\" -DPACKAGE_BUGREPORT=\\\"\\\" -DPACKAGE_URL=\\\"\\\" -DSTDC_HEADERS=1"\
" -D_FILE_OFFSET_BITS=64 -DHAVE_LIBZ=1 -DHAVE_LIBC=1 -DHAVE_LIBC=1 -DUSE_UNSHARE=1 -DUSE_PRCTL=1 -DHAVE_LIBCAP=1 -DUSE_LINUX_CAPABILITIES=1 -DHAVE_LI"\
"BPAM=1 -DHAVE_LIBSSL=1 -DHAVE_LIBCRYPTO=1 -DHAVE_LIBCRYPT=1 -DHAVE_SHADOW_H=1"
" -D_FILE_OFFSET_BITS=64 -DHAVE_LIBZ=1 -DHAVE_LIBCAP=1 -DUSE_LINUX_CAPABILITIES=1 -DHAVE_LIBPAM=1 -DHAVE_LIBSSL=1 -DHAVE_LIBCRYPTO=1 -DHAVE_LIBCRYPT="\
"1 -DHAVE_SHADOW_H=1"
S["mandir"]="${datarootdir}/man"
S["localedir"]="${datarootdir}/locale"
S["libdir"]="${exec_prefix}/lib"
Expand Down
2 changes: 1 addition & 1 deletion libUseful/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CC = gcc
VERSION = 4.43
VERSION = 4.44
CFLAGS = -g -O2
LDFLAGS=
LIBS = -lssl -lcrypto -lc -lc -lc -lc -lc -lc -lc -lc
Expand Down
2 changes: 1 addition & 1 deletion libUseful/Makefile.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CC = @CC@
VERSION = 4.43
VERSION = 4.44
CFLAGS = @CFLAGS@ @SIMD_CFLAGS@
LDFLAGS=@LDFLAGS@
LIBS = @LIBS@
Expand Down
2 changes: 1 addition & 1 deletion libUseful/OpenSSL.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ int DoSSLClientNegotiation(STREAM *S, int Flags)
ptr=GetToken(ptr,":",&Token,0);
SSL_set_tlsext_host_name(ssl, Token);
#endif

SSL_CTX_set_timeout (ctx, 1);
result=SSL_connect(ssl);
while (result==-1)
{
Expand Down
62 changes: 47 additions & 15 deletions libUseful/Socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include "UnixSocket.h"

#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <ctype.h>
Expand Down Expand Up @@ -143,9 +146,12 @@ int IsSockConnected(int sock)

int SockSetOpt(int sock, int Opt, const char *Name, int OnOrOff)
{
int val=OnOrOff;
int val=OnOrOff, level;

if (strncmp(Name, "TCP_", 4)==0) level=IPPROTO_TCP;
else level=SOL_SOCKET;

if (setsockopt(sock, SOL_SOCKET, Opt, &val,sizeof(int)) != 0)
if (setsockopt(sock, level, Opt, &val, sizeof(int)) != 0)
{
RaiseError(ERRFLAG_ERRNO, "Failed to setsockopt '%s'",Name);
return(FALSE);
Expand Down Expand Up @@ -173,33 +179,54 @@ void SockSetOptions(int sock, int SetFlags, int UnsetFlags)
if (SetFlags & SOCK_PEERCREDS) SockSetOpt(sock, SO_PASSCRED, "SOCK_PEERCREDS", 1);
#endif

#ifdef TCP_NODELAY
if (SetFlags & SOCK_TCP_NODELAY) SockSetOpt(sock, TCP_NODELAY, "TCP_NODELAY", 1);
#endif

#ifdef TCP_FASTOPEN
if (SetFlags & SOCK_TCP_FASTOPEN) SockSetOpt(sock, TCP_FASTOPEN, "TCP_FASTOPEN", 1);
#endif


#ifdef SO_KEEPALIVE
//Default is KEEPALIVE ON
//SOCK_NOKEEPALIVE unsets the default, so looks opposite to all the others
SockSetOpt(sock, SO_KEEPALIVE, "SO_KEEPALIVE", 1);
#endif

if (SetFlags & CONNECT_NONBLOCK) fcntl(sock,F_SETFL,O_NONBLOCK);

if (SetFlags & CONNECT_NONBLOCK) fcntl(sock,F_SETFL,O_NONBLOCK);


#ifdef SO_BROADCAST
if (UnsetFlags & SOCK_BROADCAST) SockSetOpt(sock, SO_BROADCAST, "", 0);
if (UnsetFlags & SOCK_BROADCAST) SockSetOpt(sock, SO_BROADCAST, "SOCK_BROADCAST", 0);
#endif

#ifdef SO_DONTROUTE
if (UnsetFlags & SOCK_DONTROUTE) SockSetOpt(sock, SO_DONTROUTE, "", 1);
if (UnsetFlags & SOCK_DONTROUTE) SockSetOpt(sock, SO_DONTROUTE, "SOCK_DONTROUTE", 0);
#endif

#ifdef SO_REUSEPORT
if (UnsetFlags & SOCK_REUSEPORT) SockSetOpt(sock, SO_REUSEPORT, "", 1);
if (UnsetFlags & SOCK_REUSEPORT) SockSetOpt(sock, SO_REUSEPORT, "SOCK_REUSEPORT", 0);
#endif

#ifdef SO_PASSCRED
if (UnsetFlags & SOCK_PEERCREDS) SockSetOpt(sock, SO_PASSCRED, "", 1);
if (UnsetFlags & SOCK_PEERCREDS) SockSetOpt(sock, SO_PASSCRED, "SOCK_PASSCRED", 0);
#endif

#ifdef TCP_NODELAY
if (UnsetFlags & SOCK_TCP_NODELAY) SockSetOpt(sock, TCP_NODELAY, "TCP_NODELAY", 0);
#endif

#ifdef TCP_FASTOPEN
if (UnsetFlags & SOCK_TCP_FASTOPEN) SockSetOpt(sock, TCP_FASTOPEN, "TCP_FASTOPEN", 0);
#endif

#ifdef SO_KEEPALIVE
//SOCK_NOKEEPALIVE unsets the default, so looks opposite to all the others
if (SetFlags & SOCK_NOKEEPALIVE) SockSetOpt(sock, SO_KEEPALIVE, "SOCK_NOKEEPALIVE", 0);
#endif

}


Expand Down Expand Up @@ -314,7 +341,7 @@ int BindSock(int Type, const char *Address, int Port, int Flags)
#endif

#ifdef SO_REUSEPORT
if (Flags & BIND_REUSEPORT) setsockopt(fd, IPPROTO_IP, SO_REUSEPORT, &result, sizeof(result));
if (Flags & BIND_REUSEPORT) setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &result, sizeof(result));
#endif

result=bind(fd, sa, salen);
Expand Down Expand Up @@ -712,7 +739,7 @@ STREAM *STREAMFromSock(int sock, int Type, const char *Peer, const char *DestIP,
}


int ServerParseConfig(const char *Config)
int SocketParseConfig(const char *Config)
{
const char *ptr;
int Flags=0;
Expand All @@ -721,10 +748,14 @@ for (ptr=Config; *ptr !='\0'; ptr++)
{
switch (*ptr)
{
case 'E': Flags |= CONNECT_ERROR; break;
case 'k': Flags |= SOCK_NOKEEPALIVE; break;
case 'A': Flags |= SOCK_TLS_AUTO; break;
case 'B': Flags |= SOCK_BROADCAST; break;
case 'F': Flags |= SOCK_TCP_FASTOPEN; break;
case 'R': Flags |= SOCK_DONTROUTE; break;
case 'P': Flags |= SOCK_REUSEPORT; break;
case 'N': Flags |= SOCK_TCP_NODELAY; break;
}
}

Expand All @@ -741,7 +772,7 @@ STREAM *STREAMServerNew(const char *URL, const char *Config)
ParseURL(URL, &Proto, &Host, &Token,NULL, NULL,NULL,NULL);
if (StrValid(Token)) Port=atoi(Token);

Flags=ServerParseConfig(Config);
Flags=SocketParseConfig(Config);

switch (*Proto)
{
Expand Down Expand Up @@ -1242,15 +1273,16 @@ int STREAMConnect(STREAM *S, const char *URL, const char *Config)
const char *ptr;
int Flags=0;

ptr=GetToken(Config, "\\S", &Value, 0);
Flags=SocketParseConfig(Value);

ptr=LibUsefulGetValue("TCP:Keepalives");
if ( StrValid(ptr) && (! strtobool(ptr)) ) Flags |= SOCK_NOKEEPALIVE;

ptr=GetNameValuePair(Config," ","=",&Name,&Value);
ptr=GetNameValuePair(ptr," ","=",&Name,&Value);
while (ptr)
{
if (strcmp("Name","E")==0) Flags |= CONNECT_ERROR;
else if (strcmp("Name","k")==0) Flags |= SOCK_NOKEEPALIVE;
else if (strcasecmp("Name","keepalive")==0)
if (strcasecmp("Name","keepalive")==0)
{
if (StrLen(Value) && (strncasecmp(Value, "n",1)==0)) Flags |= SOCK_NOKEEPALIVE;
}
Expand All @@ -1270,7 +1302,7 @@ int STREAMConnect(STREAM *S, const char *URL, const char *Config)
result=STREAMProcessConnectHops(S, Value);
}
else if (strchr(URL, '|')) result=STREAMProcessConnectHops(S, URL);
else result=STREAMDirectConnect(S, URL, 0);
else result=STREAMDirectConnect(S, URL, Flags);


DestroyString(Name);
Expand Down
6 changes: 5 additions & 1 deletion libUseful/Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Copyright (c) 2015 Colum Paget <[email protected]>
#define SOCK_PEERCREDS 512 //used with UNIX sockets to get remote user ID
#define CONNECT_ERROR 1024 //report errors even if Error:IgnoreIP is set
#define SOCK_TLS_AUTO 2048
#define SOCK_TCP_NODELAY 4096
#define SOCK_TCP_FASTOPEN 8192

#define SOCK_CONNECTED 1
#define SOCK_CONNECTING -1
Expand Down Expand Up @@ -111,12 +113,14 @@ int IPServerAccept(int ServerSock,char **Addr);

//STREAMServerInit and STREAMServerNew create server sockets for tcp:// udp:// unix:// unixdgram:// and tproxy:// protocols
//STREAMServerNew takes a Config argument that is a string containing characters as follows:
// k - disable tcp keepalives
// A - Autodetect SSL
// B - BROADCAST set udp socket to be a broadcast socket
// F - Tcp FASTOPEN
// N - Tcp NODELAY - disable Nagel's algorithm and send data straight away
// R - Don't route. All addresses are treated as local
// P - REUSE_PORT allows multiple processes to listen on the same port


STREAM *STREAMServerInit(const char *URL);
STREAM *STREAMServerNew(const char *URL, const char *Config);

Expand Down
8 changes: 1 addition & 7 deletions libUseful/SpawnPrograms.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,25 +118,19 @@ pid_t xforkio(int StdIn, int StdOut, int StdErr)
if (StdIn !=0)
{
if (StdIn == -1) fd_remap_path(0, "/dev/null", O_RDONLY);
else
{
fd_remap(0, StdIn);
close(StdIn); //must close or we will have it open twice, and it won't close when the peer closes it
}
else fd_remap(0, StdIn);
}

if (StdOut !=1)
{
if (StdOut == -1) fd_remap_path(1, "/dev/null", O_WRONLY);
else fd_remap(1, StdOut);
close(StdOut); //must close or we will have it open twice, and it won't close when the peer closes it
}

if (StdErr !=2)
{
if (StdErr == -1) fd_remap_path(2, "/dev/null", O_WRONLY);
else fd_remap(2, StdErr);
close(StdErr); //must close or we will have it open twice, and it won't close when the peer closes it
}
}

Expand Down
Loading

0 comments on commit eda1403

Please sign in to comment.