Version 0.51

- added configfile parser, added configfile support to subsystems
- plugins: replaced con/destructor with dlsym() peeking
This commit is contained in:
Olaf Rempel 2006-02-02 16:41:56 +01:00
parent 5d10585d29
commit 0d0650008f
27 changed files with 533 additions and 334 deletions

View File

@ -1,3 +1,7 @@
* Sun 27 Mar 2005 Olaf Rempel <razzor@kopf-tisch.de> 0.51
- added configfile parser, added configfile support to subsystems
- plugins: replaced con/destructor with dlsym() peeking
* Sat 26 Mar 2005 Olaf Rempel <razzor@kopf-tisch.de> 0.50 * Sat 26 Mar 2005 Olaf Rempel <razzor@kopf-tisch.de> 0.50
- added autoconf/automake/libtool support - added autoconf/automake/libtool support
- plugins: replaced _init() / _fini() with ((constructor)) / ((destructor)) - plugins: replaced _init() / _fini() with ((constructor)) / ((destructor))

View File

@ -2,4 +2,4 @@ AUTOMAKE_OPTIONS = foreign no-dependencies
SUBDIRS = src plugins tools SUBDIRS = src plugins tools
EXTRA_DIST = autogen.sh TODO EXTRA_DIST = TODO autogen.sh hlswmaster.conf

View File

@ -174,7 +174,7 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@ target_alias = @target_alias@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
SUBDIRS = src plugins tools SUBDIRS = src plugins tools
EXTRA_DIST = autogen.sh TODO EXTRA_DIST = TODO autogen.sh hlswmaster.conf
all: config.h all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive $(MAKE) $(AM_MAKEFLAGS) all-recursive

9
TODO
View File

@ -1,8 +1,7 @@
- eigene daemon() funktion rauswerfen und dann libc daemon() benutzen - daemonize & userwechsel
- configfile parser bauen & benutzen - signalhandler fuer config reread
- logging ausbauen - signalhandler listen-flush + neuscannen
- plugins im dev und auf live system finden - auf mehreren/allen interfaces gleichzeitig scannen
- auf mehreren interfaces gleichzeitig scannen
- threads ueberwachen - threads ueberwachen
- threadpool fuer client-thread? - threadpool fuer client-thread?
- ratelimit fuer scanner - ratelimit fuer scanner

20
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for hlswmaster 0.50. # Generated by GNU Autoconf 2.59 for hlswmaster 0.51.
# #
# Report bugs to <Olaf Rempel <razzor@kopf-tisch.de>>. # Report bugs to <Olaf Rempel <razzor@kopf-tisch.de>>.
# #
@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='hlswmaster' PACKAGE_NAME='hlswmaster'
PACKAGE_TARNAME='hlswmaster' PACKAGE_TARNAME='hlswmaster'
PACKAGE_VERSION='0.50' PACKAGE_VERSION='0.51'
PACKAGE_STRING='hlswmaster 0.50' PACKAGE_STRING='hlswmaster 0.51'
PACKAGE_BUGREPORT='Olaf Rempel <razzor@kopf-tisch.de>' PACKAGE_BUGREPORT='Olaf Rempel <razzor@kopf-tisch.de>'
# Factoring default headers for most tests. # Factoring default headers for most tests.
@ -953,7 +953,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures hlswmaster 0.50 to adapt to many kinds of systems. \`configure' configures hlswmaster 0.51 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1019,7 +1019,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of hlswmaster 0.50:";; short | recursive ) echo "Configuration of hlswmaster 0.51:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1160,7 +1160,7 @@ fi
test -n "$ac_init_help" && exit 0 test -n "$ac_init_help" && exit 0
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
hlswmaster configure 0.50 hlswmaster configure 0.51
generated by GNU Autoconf 2.59 generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc. Copyright (C) 2003 Free Software Foundation, Inc.
@ -1174,7 +1174,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by hlswmaster $as_me 0.50, which was It was created by hlswmaster $as_me 0.51, which was
generated by GNU Autoconf 2.59. Invocation command line was generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@ $ $0 $@
@ -1818,7 +1818,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE=hlswmaster PACKAGE=hlswmaster
VERSION=0.50 VERSION=0.51
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -21419,7 +21419,7 @@ _ASBOX
} >&5 } >&5
cat >&5 <<_CSEOF cat >&5 <<_CSEOF
This file was extended by hlswmaster $as_me 0.50, which was This file was extended by hlswmaster $as_me 0.51, which was
generated by GNU Autoconf 2.59. Invocation command line was generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -21482,7 +21482,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\ ac_cs_version="\\
hlswmaster config.status 0.50 hlswmaster config.status 0.51
configured by $0, generated by GNU Autoconf 2.59, configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"

View File

@ -1,8 +1,8 @@
dnl projekname, version, bugsto dnl projekname, version, bugsto
AC_INIT(hlswmaster, 0.50, [Olaf Rempel <razzor@kopf-tisch.de>]) AC_INIT(hlswmaster, 0.51, [Olaf Rempel <razzor@kopf-tisch.de>])
dnl same for automake dnl same for automake
AM_INIT_AUTOMAKE(hlswmaster, 0.50) AM_INIT_AUTOMAKE(hlswmaster, 0.51)
dnl do not rebuild configure dnl do not rebuild configure
AM_MAINTAINER_MODE AM_MAINTAINER_MODE

33
hlswmaster.conf Normal file
View File

@ -0,0 +1,33 @@
[global]
# broadcast scan source IP & PORT (udp)
scan_ip 0.0.0.0
scan_port 7130
# broadcast scan every X seconds
scan_interval 30
# serverlist rebuild every X seconds
serverlist_interval 5
# server timeout after X seconds
serverlist_timeout 120
# master answers with this source IP
master_ip 0.0.0.0
# load these plugins
plugin plugins/.libs/hlswproxy.so
plugin plugins/.libs/q3engine.so
plugin plugins/.libs/quake2.so
plugin plugins/.libs/gamespy1.so
plugin plugins/.libs/gamespy2.so
plugin plugins/.libs/doom3.so
plugin plugins/.libs/ut.so
# logging
# logfile hlswmaster.log
[hlswproxy]
scan_ip 10.10.0.1
scan_ip 10.10.0.2

24
include/configfile.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef _CONFIG_H
#define _CONFIG_H
#include "list.h"
struct conf_section {
struct list_head list;
char name[32];
struct list_head tupel;
};
struct conf_tupel {
struct list_head list;
char *option;
char *parameter;
};
int config_parse(char *config);
struct conf_section * config_get_section(char *name);
char * config_get_parameter(struct conf_section *section, char *option);
char * config_get_string(char *section, char *option, char *def);
int config_get_int(char *section, char *option, int def);
#endif /* _CONFIG_H */

View File

@ -3,6 +3,7 @@
#include "list.h" #include "list.h"
#include "netpkt.h" #include "netpkt.h"
#include "configfile.h"
struct game_server { struct game_server {
struct list_head list; struct list_head list;
@ -15,34 +16,30 @@ struct game_server {
} __attribute__ ((packed)); } __attribute__ ((packed));
/* daemon.c */
void daemonize(char *pw_name);
/* logging.c */ /* logging.c */
void log_open(char *logfile); int log_open();
void log_close();
void log_print(const char *fmt, ... ); void log_print(const char *fmt, ... );
/* plugin.c */ /* plugin.c */
int plugin_load(char *name); int plugin_load(char *name);
int plugin_unload(char *name); int plugin_load_all();
int plugins_scan(void); int plugin_unload_all();
int plugins_scan();
int plugins_parse(struct net_pkt *pkt); int plugins_parse(struct net_pkt *pkt);
int plugins_gc(unsigned long timeout); int plugins_gc(unsigned long timeout);
/* scanner.c */ /* scanner.c */
void pkt_queue(struct net_pkt *pkt); void pkt_queue(struct net_pkt *pkt);
int scan_init(void); int scan_init();
void scan_exit(void); void scan_transmit();
void scan_transmit(void); void scan_receive();
void scan_receive(void);
/* serverlist.c */ /* serverlist.c */
void server_collector(void); void server_collector();
/* client.c */ /* client.c */
int client_pkt_add(struct game_server *server); int client_pkt_add(struct game_server *server);
int client_pkt_commit(void); int client_pkt_commit();
void client_handler(void); void client_handler();
#endif /* _HLSWMASTER_H */ #endif /* _HLSWMASTER_H */

View File

@ -2,6 +2,7 @@
#define _PLUGIN_H #define _PLUGIN_H
#include "netpkt.h" #include "netpkt.h"
#include "configfile.h"
#include "list.h" #include "list.h"
extern int server_add(u_int16_t gameid, u_int32_t ip, u_int16_t port1, u_int16_t port2); extern int server_add(u_int16_t gameid, u_int32_t ip, u_int16_t port1, u_int16_t port2);
@ -26,19 +27,16 @@ extern unsigned short pkt_getport(struct net_pkt *pkt);
extern int pkt_atoi(struct net_pkt *pkt, void *p); extern int pkt_atoi(struct net_pkt *pkt, void *p);
struct hlswmaster_plugin { struct hlswmaster_plugin {
/* must be first */
struct list_head list; struct list_head list;
char name[32]; char name[32];
void *dlref;
int (*init)(struct list_head *config);
int (*init)(struct conf_section *config);
int (*fini)(void); int (*fini)(void);
int (*scan)(void); int (*scan)(void);
int (*parse)(struct net_pkt *pkt); int (*parse)(struct net_pkt *pkt);
int (*gc)(int timeout); int (*gc)(int timeout);
}; };
extern void register_plugin(struct hlswmaster_plugin *me);
extern void unregister_plugin(struct hlswmaster_plugin *me);
#endif /* _PLUGIN_H */ #endif /* _PLUGIN_H */

View File

@ -20,7 +20,7 @@
#include <string.h> #include <string.h>
#include "plugin.h" #include "plugin.h"
struct scan_ports port_arr[] = { static struct scan_ports port_arr[] = {
{ 27666, 27673, 38 }, /* Doom 3 */ { 27666, 27673, 38 }, /* Doom 3 */
{ 0,0,0 } { 0,0,0 }
}; };
@ -28,12 +28,12 @@ struct scan_ports port_arr[] = {
static char scanmsg[] = "\xff\xffgetInfo"; static char scanmsg[] = "\xff\xffgetInfo";
static char replymsg[] = "\xff\xffinfoResponse"; static char replymsg[] = "\xff\xffinfoResponse";
int scan(void) { static int scan(void) {
pkt_send_portarr(NULL, port_arr, scanmsg, strlen(scanmsg)); pkt_send_portarr(NULL, port_arr, scanmsg, strlen(scanmsg));
return 1; return 1;
} }
int parse(struct net_pkt *pkt) { static int parse(struct net_pkt *pkt) {
int gameid; int gameid;
if (pkt_memcmp(pkt, 0, replymsg, strlen(replymsg))) if (pkt_memcmp(pkt, 0, replymsg, strlen(replymsg)))
@ -46,16 +46,8 @@ int parse(struct net_pkt *pkt) {
return 1; return 1;
} }
static struct hlswmaster_plugin plugin = { struct hlswmaster_plugin plugin = {
.name = "doom3", .name = "doom3",
.scan = &scan, .scan = &scan,
.parse = &parse, .parse = &parse,
}; };
void __attribute__ ((constructor)) init(void) {
register_plugin(&plugin);
}
void __attribute__ ((destructor)) fini(void) {
unregister_plugin(&plugin);
}

View File

@ -20,7 +20,7 @@
#include <string.h> #include <string.h>
#include "plugin.h" #include "plugin.h"
struct scan_ports port_arr[] = { static struct scan_ports port_arr[] = {
{ 22000, 22010, 16 }, /* Battlefield 1942 */ { 22000, 22010, 16 }, /* Battlefield 1942 */
{ 0, 0, 0 } { 0, 0, 0 }
}; };
@ -29,12 +29,12 @@ static char scanmsg[] = "\\info\\";
static char bf1942_reply[] = "\\gameId\\BF1942\\"; static char bf1942_reply[] = "\\gameId\\BF1942\\";
static char hostport_search[] = "\\hostport\\"; static char hostport_search[] = "\\hostport\\";
int scan(void) { static int scan(void) {
pkt_send_portarr(NULL, port_arr, scanmsg, strlen(scanmsg)); pkt_send_portarr(NULL, port_arr, scanmsg, strlen(scanmsg));
return 1; return 1;
} }
int parse(struct net_pkt *pkt) { static int parse(struct net_pkt *pkt) {
int gameid, port; int gameid, port;
void *p; void *p;
@ -62,16 +62,8 @@ int parse(struct net_pkt *pkt) {
return 1; return 1;
} }
static struct hlswmaster_plugin plugin = { struct hlswmaster_plugin plugin = {
.name = "gamespy1", .name = "gamespy1",
.scan = &scan, .scan = &scan,
.parse = &parse, .parse = &parse,
}; };
void __attribute__ ((constructor)) init(void) {
register_plugin(&plugin);
}
void __attribute__ ((destructor)) fini(void) {
unregister_plugin(&plugin);
}

View File

@ -20,7 +20,7 @@
#include <string.h> #include <string.h>
#include "plugin.h" #include "plugin.h"
struct scan_ports port_arr[] = { static struct scan_ports port_arr[] = {
{ 2302, 2302, 30 }, /* halo */ { 2302, 2302, 30 }, /* halo */
{ 0,0,0 } { 0,0,0 }
}; };
@ -28,12 +28,12 @@ struct scan_ports port_arr[] = {
static char scanmsg[] = { 0xFE, 0xFD, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00 }; static char scanmsg[] = { 0xFE, 0xFD, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00 };
static char replymsg[] = { 0x00, 0xDE, 0xAD, 0xBE, 0xEF }; static char replymsg[] = { 0x00, 0xDE, 0xAD, 0xBE, 0xEF };
int scan(void) { static int scan(void) {
pkt_send_portarr(NULL, port_arr, scanmsg, sizeof(scanmsg)); pkt_send_portarr(NULL, port_arr, scanmsg, sizeof(scanmsg));
return 1; return 1;
} }
int parse(struct net_pkt *pkt) { static int parse(struct net_pkt *pkt) {
int gameid; int gameid;
if (!(gameid = pkt_check_portarr(pkt, port_arr))) if (!(gameid = pkt_check_portarr(pkt, port_arr)))
@ -46,16 +46,8 @@ int parse(struct net_pkt *pkt) {
return 1; return 1;
} }
static struct hlswmaster_plugin plugin = { struct hlswmaster_plugin plugin = {
.name = "gamespy2", .name = "gamespy2",
.scan = &scan, .scan = &scan,
.parse = &parse, .parse = &parse,
}; };
void __attribute__ ((constructor)) init(void) {
register_plugin(&plugin);
}
void __attribute__ ((destructor)) fini(void) {
unregister_plugin(&plugin);
}

View File

@ -23,19 +23,19 @@
static char scanmsg[] = "\xff\xff\xff\xffHLSWLANSEARCH"; static char scanmsg[] = "\xff\xff\xff\xffHLSWLANSEARCH";
struct _entry { static struct _entry {
u_int16_t gameid; u_int16_t gameid;
u_int32_t ip; u_int32_t ip;
u_int16_t port1; u_int16_t port1;
u_int16_t port2; u_int16_t port2;
} __attribute__ ((packed)); } __attribute__ ((packed));
int scan(void) { static int scan(void) {
pkt_send(NULL, 7140, scanmsg, sizeof(scanmsg)); pkt_send(NULL, 7140, scanmsg, sizeof(scanmsg));
return 1; return 1;
} }
int parse(struct net_pkt *pkt) { static int parse(struct net_pkt *pkt) {
struct _entry *server; struct _entry *server;
if (pkt_getport(pkt) != 7140) if (pkt_getport(pkt) != 7140)
return 0; return 0;
@ -49,16 +49,21 @@ int parse(struct net_pkt *pkt) {
return 1; return 1;
} }
static struct hlswmaster_plugin plugin = { static int init(struct conf_section *section) {
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel, list)
if (!strcmp(tupel->option, "scan_ip"))
log_print("hlswproxy: will scan %s", tupel->parameter);
}
static int fini() {
}
struct hlswmaster_plugin plugin = {
.name = "hlswproxy", .name = "hlswproxy",
.scan = &scan, .scan = &scan,
.parse = &parse, .parse = &parse,
.init = &init,
.fini = &fini,
}; };
void __attribute__ ((constructor)) init(void) {
register_plugin(&plugin);
}
void __attribute__ ((destructor)) fini(void) {
unregister_plugin(&plugin);
}

View File

@ -20,7 +20,7 @@
#include <string.h> #include <string.h>
#include "plugin.h" #include "plugin.h"
struct scan_ports port_arr[] = { static struct scan_ports port_arr[] = {
{ 27960, 27969, 6 }, /* Quake3(6), Elite Force(7), Enemy Territory(25) */ { 27960, 27969, 6 }, /* Quake3(6), Elite Force(7), Enemy Territory(25) */
{ 28960, 28963, 31 }, /* Call of Duty(31), Call of Duty: United Offensive (42) */ { 28960, 28963, 31 }, /* Call of Duty(31), Call of Duty: United Offensive (42) */
{ 0,0,0 } { 0,0,0 }
@ -35,12 +35,12 @@ static char et_reply[] = "\\version\\ET ";
static char cod_reply[] = "\\gamename\\Call of Duty\\"; static char cod_reply[] = "\\gamename\\Call of Duty\\";
static char coduo_reply[] = "\\gamename\\CoD:United Offensive\\"; static char coduo_reply[] = "\\gamename\\CoD:United Offensive\\";
int scan(void) { static int scan(void) {
pkt_send_portarr(NULL, port_arr, scanmsg, strlen(scanmsg)); pkt_send_portarr(NULL, port_arr, scanmsg, strlen(scanmsg));
return 1; return 1;
} }
int parse(struct net_pkt *pkt) { static int parse(struct net_pkt *pkt) {
int gameid; int gameid;
if (!(gameid = pkt_check_portarr(pkt, port_arr))) if (!(gameid = pkt_check_portarr(pkt, port_arr)))
@ -82,16 +82,8 @@ int parse(struct net_pkt *pkt) {
return 1; return 1;
} }
static struct hlswmaster_plugin plugin = { struct hlswmaster_plugin plugin = {
.name = "q3engine", .name = "q3engine",
.scan = &scan, .scan = &scan,
.parse = &parse, .parse = &parse,
}; };
void __attribute__ ((constructor)) init(void) {
register_plugin(&plugin);
}
void __attribute__ ((destructor)) fini(void) {
unregister_plugin(&plugin);
}

View File

@ -22,13 +22,12 @@
static char scanmsg[] = "\xff\xff\xff\xffinfo 34"; static char scanmsg[] = "\xff\xff\xff\xffinfo 34";
int scan(void) { static int scan(void) {
pkt_send(NULL, 27910, scanmsg, strlen(scanmsg)); pkt_send(NULL, 27910, scanmsg, strlen(scanmsg));
return 1; return 1;
} }
/* TODO: src port checken */ static int parse(struct net_pkt *pkt) {
int parse(struct net_pkt *pkt) {
if (pkt_getport(pkt) != 27910) if (pkt_getport(pkt) != 27910)
return 0; return 0;
@ -39,16 +38,8 @@ int parse(struct net_pkt *pkt) {
return 1; return 1;
} }
static struct hlswmaster_plugin plugin = { struct hlswmaster_plugin plugin = {
.name = "quake2", .name = "quake2",
.scan = &scan, .scan = &scan,
.parse = &parse, .parse = &parse,
}; };
void __attribute__ ((constructor)) init(void) {
register_plugin(&plugin);
}
void __attribute__ ((destructor)) fini(void) {
unregister_plugin(&plugin);
}

View File

@ -20,7 +20,7 @@
#include <string.h> #include <string.h>
#include "plugin.h" #include "plugin.h"
struct scan_ports port_arr[] = { static struct scan_ports port_arr[] = {
{ 8777, 8786, 5 }, /* Unreal Tournament (5), Ravenshield (-) */ { 8777, 8786, 5 }, /* Unreal Tournament (5), Ravenshield (-) */
{ 0,0,0 } { 0,0,0 }
}; };
@ -29,12 +29,12 @@ static char scanmsg[] = "REPORTQUERY";
static char ut_reply[] = "ut "; static char ut_reply[] = "ut ";
static char rvs_reply[] = "rvnshld 0"; static char rvs_reply[] = "rvnshld 0";
int scan(void) { static int scan(void) {
pkt_send_portarr(NULL, port_arr, scanmsg, strlen(scanmsg)); pkt_send_portarr(NULL, port_arr, scanmsg, strlen(scanmsg));
return 1; return 1;
} }
int parse(struct net_pkt *pkt) { static int parse(struct net_pkt *pkt) {
int gameid, port; int gameid, port;
void *p; void *p;
@ -61,16 +61,8 @@ int parse(struct net_pkt *pkt) {
return 1; return 1;
} }
static struct hlswmaster_plugin plugin = { struct hlswmaster_plugin plugin = {
.name = "ut", .name = "ut",
.scan = &scan, .scan = &scan,
.parse = &parse, .parse = &parse,
}; };
void __attribute__ ((constructor)) init(void) {
register_plugin(&plugin);
}
void __attribute__ ((destructor)) fini(void) {
unregister_plugin(&plugin);
}

View File

@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies
INCLUDES = -I../include INCLUDES = -I../include
bin_PROGRAMS = hlswmaster bin_PROGRAMS = hlswmaster
hlswmaster_SOURCES = client.c daemon.c logging.c main.c plugin.c plugin_helper.c scanner.c serverlist.c \ hlswmaster_SOURCES = client.c config.c logging.c main.c plugin.c plugin_helper.c scanner.c serverlist.c \
../include/hlswmaster.h ../include/list.h ../include/netpkt.h ../include/plugin.h ../include/configfile.h ../include/hlswmaster.h ../include/list.h ../include/netpkt.h ../include/plugin.h
hlswmaster_LDADD = -ldl -lpthread hlswmaster_LDADD = -ldl -lpthread
hlswmaster_LDFLAGS = -rdynamic hlswmaster_LDFLAGS = -rdynamic

View File

@ -51,7 +51,7 @@ CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(bindir)" am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS) PROGRAMS = $(bin_PROGRAMS)
am_hlswmaster_OBJECTS = client.$(OBJEXT) daemon.$(OBJEXT) \ am_hlswmaster_OBJECTS = client.$(OBJEXT) config.$(OBJEXT) \
logging.$(OBJEXT) main.$(OBJEXT) plugin.$(OBJEXT) \ logging.$(OBJEXT) main.$(OBJEXT) plugin.$(OBJEXT) \
plugin_helper.$(OBJEXT) scanner.$(OBJEXT) serverlist.$(OBJEXT) plugin_helper.$(OBJEXT) scanner.$(OBJEXT) serverlist.$(OBJEXT)
hlswmaster_OBJECTS = $(am_hlswmaster_OBJECTS) hlswmaster_OBJECTS = $(am_hlswmaster_OBJECTS)
@ -173,8 +173,8 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@ target_alias = @target_alias@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
INCLUDES = -I../include INCLUDES = -I../include
hlswmaster_SOURCES = client.c daemon.c logging.c main.c plugin.c plugin_helper.c scanner.c serverlist.c \ hlswmaster_SOURCES = client.c config.c logging.c main.c plugin.c plugin_helper.c scanner.c serverlist.c \
../include/hlswmaster.h ../include/list.h ../include/netpkt.h ../include/plugin.h ../include/configfile.h ../include/hlswmaster.h ../include/list.h ../include/netpkt.h ../include/plugin.h
hlswmaster_LDADD = -ldl -lpthread hlswmaster_LDADD = -ldl -lpthread
hlswmaster_LDFLAGS = -rdynamic hlswmaster_LDFLAGS = -rdynamic

View File

@ -28,6 +28,7 @@
#include <pthread.h> #include <pthread.h>
#include "hlswmaster.h" #include "hlswmaster.h"
#include "configfile.h"
#include "plugin.h" #include "plugin.h"
#include "list.h" #include "list.h"
@ -70,19 +71,19 @@ static inline int cpkt_not_full(const struct client_pkt *a, void *b) {
* @return struct client_pkt * or NULL on error * @return struct client_pkt * or NULL on error
*/ */
static struct client_pkt * client_pkt_add_real(struct list_head *list) { static struct client_pkt * client_pkt_add_real(struct list_head *list) {
struct client_pkt *new; struct client_pkt *pkt;
if (!(new = malloc(sizeof(struct client_pkt) + MAX_PKT_LEN))) pkt = malloc(sizeof(struct client_pkt) + MAX_PKT_LEN);
return NULL; if (pkt) {
INIT_LIST_HEAD(&pkt->list);
INIT_LIST_HEAD(&new->list);
/* kopier den hlsw header in das client paket */
/* kopier den hlsw header in das client paket */ memcpy(pkt->buf, HLSW_HEADER, HLSW_HEADER_LEN);
memcpy(new->buf, HLSW_HEADER, HLSW_HEADER_LEN); pkt->size = HLSW_HEADER_LEN;
new->size = HLSW_HEADER_LEN;
list_add_tail(&pkt->list, list);
list_add_tail(&new->list, list); }
return new; return pkt;
} }
/** /**
@ -118,6 +119,10 @@ int client_pkt_add(struct game_server *server) {
int client_pkt_commit() { int client_pkt_commit() {
struct list_head old_list, *pkt, *tmp; struct list_head old_list, *pkt, *tmp;
/* wenn die liste leer ist, HLSW-header verschicken */
if (list_empty(&client_pkt_prepare))
client_pkt_add_real(&client_pkt_prepare);
pthread_mutex_lock(&pkt_list_lock); pthread_mutex_lock(&pkt_list_lock);
/* old_list wird head der real list */ /* old_list wird head der real list */
@ -141,23 +146,24 @@ int client_pkt_commit() {
/** /**
* client_handler() * client_handler()
* empfaengt und beantwortet die HLSW Anfragen * empfaengt und beantwortet die HLSW Anfragen
*
* TODO: src-ip configurierbar machen (config file?)
*/ */
void client_handler(void) { void client_handler(void) {
struct client_pkt *pkt; struct client_pkt *pkt;
struct sockaddr_in dst; struct sockaddr_in dst;
int sock, i; int sock, i;
unsigned char buf[32]; unsigned char buf[32], *ip;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
log_print("client_handler(): socket()"); log_print("client_handler(): socket()");
return; return;
} }
ip = config_get_string("global", "master_ip", "0.0.0.0");
log_print("starting client_handler thread");
dst.sin_family = AF_INET; dst.sin_family = AF_INET;
dst.sin_port = htons(7140); dst.sin_port = htons(7140);
inet_aton("0.0.0.0", &dst.sin_addr); inet_aton(ip, &dst.sin_addr);
if (bind(sock, (struct sockaddr *)&dst, sizeof(dst)) < 0) { if (bind(sock, (struct sockaddr *)&dst, sizeof(dst)) < 0) {
log_print("client_handler(): bind()"); log_print("client_handler(): bind()");

208
src/config.c Normal file
View File

@ -0,0 +1,208 @@
/***************************************************************************
* Copyright (C) 03/2005 by Olaf Rempel *
* razzor@kopf-tisch.de *
* *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "hlswmaster.h"
#include "configfile.h"
#include "list.h"
//#define DEBUG 1
/* liste der geladenen plugins */
LIST_HEAD(config_list);
static struct conf_section * config_add_section(char *name) {
struct conf_section *section;
if (!name)
return NULL;
section = malloc(sizeof(struct conf_section));
if (section) {
INIT_LIST_HEAD(&section->list);
INIT_LIST_HEAD(&section->tupel);
strncpy(section->name, name, sizeof(section->name));
list_add_tail(&section->list, &config_list);
}
return section;
}
static int config_add_tupel(struct conf_section *section, char *option, char *parameter) {
struct conf_tupel *tupel;
if (!section || !option || !parameter)
return 0;
if (!(tupel = malloc(sizeof(struct conf_tupel))))
return 0;
INIT_LIST_HEAD(&tupel->list);
tupel->option = strdup(option);
tupel->parameter = strdup(parameter);
list_add_tail(&tupel->list, &section->tupel);
return 1;
}
/**
* config_parse()
* parsed die configfile
*
* @param char *config
* @return false bei fehler
*/
int config_parse(char *config) {
struct conf_section *section = NULL;
FILE *fz;
int i = 0, ret = 1;
char *row, *tok, *tok2;
if (!config)
return 0;
if (!(row = malloc(1024)))
return 0;
if (!(fz = fopen(config, "r"))) {
log_print("config_parse(): %s", config);
return 0;
}
while (fgets(row, 1024, fz)) {
i++;
if (row[0] == '#' || row[0] <= ' ') {
continue;
} else if (row[0] == '[') {
tok = strtok(row +1, " ]\n");
section = config_add_section(tok);
if (!section) {
log_print("config_parse(): invalid section in row %d", i);
ret = 0;
break;
}
continue;
} else if (!section) {
log_print("config_parse(): missing section in row %d", i);
ret = 0;
break;
}
if ((tok = strtok(row, " \n")) && (tok2 = strtok(NULL, " \n")))
if (!config_add_tupel(section, tok, tok2))
log_print("config_parse(): invalid row %d", i);
}
fclose(fz);
free(row);
#ifdef DEBUG
{
struct conf_section *section;
struct conf_tupel *tupel;
list_for_each_entry(section, &config_list, list)
list_for_each_entry(tupel, &section->tupel, list)
printf("%s: %s = %s\n", section->name, tupel->option, tupel->parameter);
}
#endif
return ret;
}
/**
* config_get_section()
* gibt einen pointer auf die erste section mit dem
* angegebenen namen zurueck
* wenn nicht vorhanden NULL
*
* @param char *name
* @return struct conf_section *
*/
struct conf_section * config_get_section(char *name) {
struct conf_section *section;
list_for_each_entry(section, &config_list, list) {
if (!strcmp(section->name, name))
return section;
}
return NULL;
}
/**
* config_get_parameter()
* gibt den parameter der ersten passenden option
* in einer section zurueck
*
* @param struct conf_section *section
* @param char *option
* @return char *
*/
char * config_get_parameter(struct conf_section *section, char *option) {
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel, list) {
if (!strcmp(tupel->option, option))
return tupel->parameter;
}
return NULL;
}
/**
* config_get_string()
* gibt den parameter des section/option tupels zurueck
* wenn nicht vorhanden, wird def zurueckgegeben
* @param char *section
* @param chat *option
* @param char *def
* @return char *
*/
char * config_get_string(char *section, char *option, char *def) {
struct conf_section *tmp;
char *ret;
tmp = config_get_section(section);
if (tmp && (ret = config_get_parameter(tmp, option)))
return ret;
return def;
}
/**
* config_get_int()
* gibt den parameter des section/option tupels zurueck
* wenn nicht vorhanden, wird def zurueckgegeben
* @param char *section
* @param char *option
* @param int def
* @return int
*/
int config_get_int(char *section, char *option, int def) {
char *ret;
ret = config_get_string(section, option, NULL);
return ret ? atoi(ret) : def;
}

View File

@ -1,79 +0,0 @@
/***************************************************************************
* Copyright (C) 03/2005 by Olaf Rempel *
* razzor@kopf-tisch.de *
* *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <pwd.h>
#include "hlswmaster.h"
/**
* daemonize()
* macht den Prozess zu einen Daemon
* und fuehrt ihn unterem user aus
*
* @param char *pw_name
*
* TODO: hier schon logging benutzen? stderr? wann exit/return?
*/
void daemonize(char *pw_name) {
int fail = 0;
pid_t pid;
struct passwd *pwl;
if ((pid = fork()) < 0) {
log_print("daemonize(): fork()");
exit(-1);
} else if (pid != 0) {
/* Elternprozess beenden */
exit(0);
} else {
/* Kindprozess weiterlaufen lassen */
if (setsid() == -1) {
log_print("daemonize: setsid()");
exit(-1);
}
umask(0) ;
if (pw_name != NULL) {
if((pwl = getpwnam(pw_name)) == NULL) {
log_print("mkdaemon(): getpwnam(\"%s\")", pw_name);
exit(-1);
}
if (setgid(pwl->pw_gid) != 0) {
log_print("mkdaemon(): setgid()");
fail = 1;
}
if (setuid(pwl->pw_uid) != 0) {
log_print("mkdaemon(): setuid()");
fail = 1;
}
if (fail == 0) {
log_print("user changed to: %s, pid: %d", pw_name, getpid());
}
}
}
}

View File

@ -24,34 +24,10 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include "configfile.h"
static FILE *log_fd = NULL; static FILE *log_fd = NULL;
/**
* log_close()
* schliesst das logfile
*/
void log_close() {
fclose(log_fd);
}
/**
* log_open()
* oeffnet ein logfile
* wenn der prozess sich beendet, wird das logfile auch wieder geschlossen
*
* @param char *logfile
*/
void log_open(char *logfile) {
if ((log_fd = fopen(logfile, "a" )) == NULL) {
fprintf(stderr, "log_open(\"%s\"): %s\n", logfile, strerror(errno));
exit(-1);
}
if (atexit(log_close) != 0) {
fprintf(stderr, "log_open(): atexit(): %s\n", strerror(errno));
exit(-1);
}
}
/** /**
* log_print() * log_print()
* schreibt eine Zeile ins Logfile oder auf stderr * schreibt eine Zeile ins Logfile oder auf stderr
@ -88,3 +64,34 @@ void log_print(const char *fmt, ...) {
errno = 0; errno = 0;
fflush(log_fd); fflush(log_fd);
} }
/**
* log_close()
* schliesst das logfile
*/
static void log_close() {
fclose(log_fd);
}
/**
* log_init()
* oeffnet das logfile
* wenn der prozess sich beendet, wird das logfile auch wieder geschlossen
*/
int log_init() {
char *logfile;
logfile = config_get_string("global", "logfile", NULL);
if (logfile) {
if ((log_fd = fopen(logfile, "a" )) == NULL) {
log_print("log_open('%s'): %s", logfile);
return 0;
}
if (atexit(log_close) != 0) {
log_print("log_open(): atexit()");
return 0;
}
}
log_print("==========================");
return 1;
}

View File

@ -22,7 +22,6 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include <getopt.h> #include <getopt.h>
#include "hlswmaster.h" #include "hlswmaster.h"
@ -30,39 +29,37 @@
static struct option opts[] = { static struct option opts[] = {
{"config", 1, 0, 'c'}, {"config", 1, 0, 'c'},
{"user", 1, 0, 'u'}, {"user", 1, 0, 'u'},
{"debug", 1, 0, 'd'}, {"debug", 0, 0, 'd'},
{"no-daemon", 0, 0, 'f'},
{"help", 0, 0, 'h'}, {"help", 0, 0, 'h'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int arg = 0, code = 0;
pthread_t thread1, thread2, thread3, thread4; pthread_t thread1, thread2, thread3, thread4;
int arg = 0, code = 0;
char *config = NULL, *user = NULL, *logfile;
while (code != -1) { while (code != -1) {
code = getopt_long(argc, argv, "c:u:d:fh", opts, &arg); code = getopt_long(argc, argv, "c:u:dh", opts, &arg);
switch (code) { switch (code) {
case 'c': /* config */ case 'c': /* config */
config = optarg;
break; break;
case 'u': /* user */ case 'u': /* user */
user = optarg;
break; break;
case 'd': /* debug */ case 'd': /* debug */
break; break;
case 'f': /* no-daemon */
break;
case 'h': /* help */ case 'h': /* help */
printf("Usage: hlsw-master [options]\n" printf("Usage: hlsw-master [options]\n"
"Options: \n" "Options: \n"
" --config -c configfile use this configfile\n" " --config -c configfile use this configfile\n"
" --user -u username change uid to username\n" " --user -u username change uid to username\n"
" --debug -d debuglevel level: 0 - 7\n" " --debug -d do not fork, and log to stderr\n"
" --no-daemon -f do not fork\n"
" --help -h this help\n" " --help -h this help\n"
"\n"); "\n");
exit(0); exit(0);
@ -77,26 +74,30 @@ int main(int argc, char *argv[]) {
} }
} }
/* parse config file */
if (!config_parse(config))
exit(-1);
plugin_load("plugins/.libs/hlswproxy.so"); /* start logging */
plugin_load("plugins/.libs/q3engine.so"); if (!log_init())
plugin_load("plugins/.libs/quake2.so"); exit(-1);
plugin_load("plugins/.libs/gamespy1.so");
plugin_load("plugins/.libs/gamespy2.so");
plugin_load("plugins/.libs/doom3.so");
plugin_load("plugins/.libs/ut.so");
scan_init(); /* init scan engine */
if (!scan_init())
exit(-1);
// scan_transmit(); /* load plugins */
plugin_load_all();
/* startup threads */
pthread_create(&thread1, NULL, (void *)&scan_transmit, NULL); pthread_create(&thread1, NULL, (void *)&scan_transmit, NULL);
pthread_create(&thread2, NULL, (void *)&scan_receive, NULL); pthread_create(&thread2, NULL, (void *)&scan_receive, NULL);
pthread_create(&thread3, NULL, (void *)&server_collector, NULL); pthread_create(&thread3, NULL, (void *)&server_collector, NULL);
pthread_create(&thread4, NULL, (void *)&client_handler, NULL); pthread_create(&thread4, NULL, (void *)&client_handler, NULL);
sleep(9999); /* wait till dawn */
while (1)
scan_exit(); sleep(3600);
return 0; return 0;
} }

View File

@ -23,6 +23,7 @@
#include "hlswmaster.h" #include "hlswmaster.h"
#include "plugin.h" #include "plugin.h"
#include "configfile.h"
#include "netpkt.h" #include "netpkt.h"
#include "list.h" #include "list.h"
@ -34,33 +35,87 @@ static pthread_mutex_t plugin_lock = PTHREAD_MUTEX_INITIALIZER;
/** /**
* plugin_load() * plugin_load()
* laedt ein plugin * laedt ein shared object,
* fuehrt wenn vorhanden init() aus
* und haengt den plugin an das ende der liste
* *
* @param char *name * @param char *name
* @return false on error * @return false on error
*
* TODO: pfadname als parameter (config-file?)
* TODO: referenz speichern? wo? wie?
*/ */
int plugin_load(char *name) { int plugin_load(char *name) {
struct hlswmaster_plugin *plugin;
void *tmp; void *tmp;
struct conf_section *section;
if (!(tmp = dlopen(name, RTLD_NOW))) dlerror();
log_print("unable to load plugin '%s'", name);
if ((tmp = dlopen(name, RTLD_NOW))) {
if ((plugin = dlsym(tmp, "plugin"))) {
plugin->dlref = tmp;
section = config_get_section(plugin->name);
log_print("loading plugin '%s'", plugin->name);
if (!plugin->init || (plugin->init(section))) {
pthread_mutex_lock(&plugin_lock);
list_add_tail(&plugin->list, &plugin_list);
pthread_mutex_unlock(&plugin_lock);
return 1;
}
log_print("failed to load '%s'", name);
dlclose(tmp);
return 0;
}
log_print("%s", dlerror());
dlclose(tmp);
}
return 0;
}
/**
* plugin_load_all()
* laedt alle in der config angegebenen plugins
*
* @return false on error
*/
int plugin_load_all() {
struct conf_section *section;
struct conf_tupel *tupel;
section = config_get_section("global");
if (section) {
list_for_each_entry(tupel, &section->tupel, list)
if (!strcmp(tupel->option, "plugin"))
plugin_load(tupel->parameter);
}
return 1; return 1;
} }
/** /**
* plugin_unload() * plugin_unload_all()
* entfernt ein plugin * entfernt alle plugins aus der liste,
* ruft wenn vorhanden fini() auf
* und entlaed das shared object
* *
* @param char *name
* @return false on error * @return false on error
*
* TODO: implementieren? oder lieber nicht?
*/ */
int plugin_unload(char *name) { int plugin_unload_all() {
struct hlswmaster_plugin *plugin, *tmp;
pthread_mutex_lock(&plugin_lock);
list_for_each_entry_safe(plugin, tmp, &plugin_list, list) {
list_del(&plugin->list);
if (plugin->fini)
plugin->fini();
log_print("plugin '%s' unloaded", plugin->name);
dlclose(plugin->dlref);
}
pthread_mutex_unlock(&plugin_lock);
return 1; return 1;
} }
@ -112,7 +167,7 @@ int plugins_parse(struct net_pkt *pkt) {
* @param unsigned long timeout * @param unsigned long timeout
* @return true * @return true
* *
* TODO: wird noch nicht benutzt * TODO: wird noch nicht benutzt, welcher thread soll das machen?
*/ */
int plugins_gc(unsigned long timeout) { int plugins_gc(unsigned long timeout) {
struct hlswmaster_plugin *plugin; struct hlswmaster_plugin *plugin;
@ -125,32 +180,3 @@ int plugins_gc(unsigned long timeout) {
pthread_mutex_unlock(&plugin_lock); pthread_mutex_unlock(&plugin_lock);
return 1; return 1;
} }
/**
* register_plugin()
* wird von den Plugins beim laden (durch _init())aufgerufen
*
* @param struct hlswmaster_plugin *me
*/
void register_plugin(struct hlswmaster_plugin *me) {
if (!me->init || (me->init(NULL))) {
pthread_mutex_lock(&plugin_lock);
list_add_tail((struct list_head *)me, &plugin_list);
pthread_mutex_unlock(&plugin_lock);
}
}
/**
* register_plugin()
* wird von den Plugins beim entfernen (durch fini) aufgerufen
*
* @param struct hlswmaster_plugin *me
*/
void unregister_plugin(struct hlswmaster_plugin *me) {
pthread_mutex_lock(&plugin_lock);
list_del((struct list_head *)me);
pthread_mutex_unlock(&plugin_lock);
if (me->fini)
me->fini();
}

View File

@ -30,6 +30,7 @@
#include "list.h" #include "list.h"
#include "netpkt.h" #include "netpkt.h"
#include "configfile.h"
#include "hlswmaster.h" #include "hlswmaster.h"
LIST_HEAD(send_queue); LIST_HEAD(send_queue);
@ -37,7 +38,7 @@ LIST_HEAD(send_queue);
static int scan_sock; static int scan_sock;
/** /**
* _pkt_queue() * pkt_queue()
* packt ein paket in die sender queue * packt ein paket in die sender queue
* @param struct net_pkt *pkt * @param struct net_pkt *pkt
*/ */
@ -51,11 +52,14 @@ void pkt_queue(struct net_pkt *pkt) {
* arbeitet die sender queue ab * arbeitet die sender queue ab
* *
* TODO: ratelimiting * TODO: ratelimiting
* TODO: interval als parameter (config file?)
*/ */
void scan_transmit(void) { void scan_transmit(void) {
struct net_pkt *pkt, *tmp; struct net_pkt *pkt, *tmp;
int interval;
interval = config_get_int("global", "scan_interval", 30);
log_print("starting tx scan thread (%ds interval)", interval);
while (1) { while (1) {
plugins_scan(); plugins_scan();
@ -68,7 +72,7 @@ void scan_transmit(void) {
usleep(10000); usleep(10000);
} }
sleep(30); sleep(interval);
} }
} }
@ -82,6 +86,8 @@ void scan_receive(void) {
fd_set fdsel, fdcpy; fd_set fdsel, fdcpy;
int recvsize, i; int recvsize, i;
log_print("starting rx scan thread");
FD_ZERO(&fdsel); FD_ZERO(&fdsel);
FD_SET(scan_sock, &fdsel); FD_SET(scan_sock, &fdsel);
@ -113,25 +119,34 @@ void scan_receive(void) {
} }
} }
/**
* schliesst den server scan socket
*/
static void scan_close() {
close(scan_sock);
}
/** /**
* scan_init() * scan_init()
* initialisiert den socket fuer den server scan * initialisiert den socket fuer den server scan
* @return false on error * @return false on error
*
* TODO: src ip als parameter (config-file?)
*/ */
int scan_init() { int scan_init() {
struct sockaddr_in dst; struct sockaddr_in dst;
int i = 1; int i = 1, port;
char *ip;
if ((scan_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { if ((scan_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
log_print("scan_init(): socket()"); log_print("scan_init(): socket()");
return 0; return 0;
} }
ip = config_get_string("global", "scan_ip", "0.0.0.0");
port = config_get_int("global", "scan_port", 7130);
dst.sin_family = AF_INET; dst.sin_family = AF_INET;
dst.sin_port = htons(7130); dst.sin_port = htons(port);
inet_aton("0.0.0.0", &dst.sin_addr); inet_aton(ip, &dst.sin_addr);
if (bind(scan_sock, (struct sockaddr *)&dst, sizeof(dst)) < 0) { if (bind(scan_sock, (struct sockaddr *)&dst, sizeof(dst)) < 0) {
log_print("scan_init(): bind()"); log_print("scan_init(): bind()");
@ -142,13 +157,13 @@ int scan_init() {
log_print("scan_init(): setsockopt()"); log_print("scan_init(): setsockopt()");
return 0; return 0;
} }
if (atexit(scan_close) != 0) {
log_print("scan_init(): atexit()");
return 0;
}
log_print("scan socket initialized (%s:%d)", ip, port);
return 1; return 1;
} }
/**
* schliesst den server scan socket
*/
void scan_exit() {
close(scan_sock);
}

View File

@ -105,16 +105,18 @@ int server_add(u_int16_t gameid, u_int32_t ip, u_int16_t port1, u_int16_t port2)
* server_collector() * server_collector()
* loescht alte server aus der liste * loescht alte server aus der liste
* baut aus den verbleibenden die client_liste auf * baut aus den verbleibenden die client_liste auf
*
* TODO: timeout und intervall als config parameter (config file?)
*/ */
void server_collector(void) { void server_collector(void) {
struct game_server *server, *tmp; struct game_server *server, *tmp;
unsigned long now, timeout = 60; unsigned long now;
int timeout, interval;
timeout = config_get_int("global", "serverlist_timeout", 60);
interval = config_get_int("global", "serverlist_interval", 5);
log_print("starting serverlist thread (%ds interval / %ds timeout)", interval, timeout);
while (1) { while (1) {
sleep(5);
now = time(NULL); now = time(NULL);
pthread_mutex_lock(&server_list_lock); pthread_mutex_lock(&server_list_lock);
list_for_each_entry_safe(server, tmp, &server_list, list) { list_for_each_entry_safe(server, tmp, &server_list, list) {
@ -136,5 +138,7 @@ void server_collector(void) {
pthread_mutex_unlock(&server_list_lock); pthread_mutex_unlock(&server_list_lock);
client_pkt_commit(); client_pkt_commit();
sleep(interval);
} }
} }