WIP: rewrite the network stack to use libevent
This commit is contained in:
@ -16,9 +16,5 @@ add_library(${PROJECT_NAME} STATIC ${SOURCES})
|
||||
|
||||
# Find dependencies
|
||||
find_package(Boost REQUIRED)
|
||||
|
||||
# Link dependencies if found
|
||||
if (Boost_FOUND)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries (${PROJECT_NAME} ${Boost_LIBRARIES})
|
||||
endif (Boost_FOUND)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${Boost_LIBRARIES})
|
||||
|
@ -1,95 +0,0 @@
|
||||
#ifndef __INC_LIBTHECORE_FDWATCH_H__
|
||||
#define __INC_LIBTHECORE_FDWATCH_H__
|
||||
|
||||
#if defined(WIN32) || defined(__linux__)
|
||||
|
||||
typedef struct fdwatch FDWATCH;
|
||||
typedef struct fdwatch * LPFDWATCH;
|
||||
|
||||
enum EFdwatch
|
||||
{
|
||||
FDW_NONE = 0,
|
||||
FDW_READ = 1,
|
||||
FDW_WRITE = 2,
|
||||
FDW_WRITE_ONESHOT = 4,
|
||||
FDW_EOF = 8,
|
||||
};
|
||||
|
||||
struct fdwatch
|
||||
{
|
||||
fd_set rfd_set;
|
||||
fd_set wfd_set;
|
||||
|
||||
socket_t* select_fds;
|
||||
int* select_rfdidx;
|
||||
|
||||
int nselect_fds;
|
||||
|
||||
fd_set working_rfd_set;
|
||||
fd_set working_wfd_set;
|
||||
|
||||
int nfiles;
|
||||
|
||||
void** fd_data;
|
||||
int* fd_rw;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef struct fdwatch FDWATCH;
|
||||
typedef struct fdwatch* LPFDWATCH;
|
||||
|
||||
enum EFdwatch
|
||||
{
|
||||
FDW_NONE = 0,
|
||||
FDW_READ = 1,
|
||||
FDW_WRITE = 2,
|
||||
FDW_WRITE_ONESHOT = 4,
|
||||
FDW_EOF = 8,
|
||||
};
|
||||
|
||||
typedef struct kevent KEVENT;
|
||||
typedef struct kevent* LPKEVENT;
|
||||
typedef int KQUEUE;
|
||||
|
||||
struct fdwatch
|
||||
{
|
||||
KQUEUE kq;
|
||||
|
||||
int nfiles;
|
||||
|
||||
LPKEVENT kqevents;
|
||||
int nkqevents;
|
||||
|
||||
LPKEVENT kqrevents;
|
||||
int* fd_event_idx;
|
||||
|
||||
void** fd_data;
|
||||
int* fd_rw;
|
||||
};
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern LPFDWATCH fdwatch_new(int nfiles);
|
||||
extern void fdwatch_clear_fd(LPFDWATCH fdw, socket_t fd);
|
||||
extern void fdwatch_delete(LPFDWATCH fdw);
|
||||
extern int fdwatch_check_fd(LPFDWATCH fdw, socket_t fd);
|
||||
extern int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx);
|
||||
extern void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx);
|
||||
extern void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void* client_data, int rw, int oneshot);
|
||||
extern int fdwatch(LPFDWATCH fdw, struct timeval *timeout);
|
||||
extern void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx);
|
||||
extern void fdwatch_del_fd(LPFDWATCH fdw, socket_t fd);
|
||||
extern int fdwatch_get_buffer_size(LPFDWATCH fdw, socket_t fd);
|
||||
extern int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Filename: socket.c
|
||||
* Description: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
*
|
||||
* Author: <20><><EFBFBD><EFBFBD> (server), myevan (Client)
|
||||
*/
|
||||
#ifndef __INC_LIBTHECORE_SOCKET_H__
|
||||
#define __INC_LIBTHECORE_SOCKET_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef __WIN32__
|
||||
typedef int socklen_t;
|
||||
#else
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
extern int socket_read(socket_t desc, char* read_point, size_t space_left);
|
||||
extern int socket_write(socket_t desc, const char *data, size_t length);
|
||||
|
||||
extern int socket_udp_read(socket_t desc, char * read_point, size_t space_left, struct sockaddr * from, socklen_t * fromlen);
|
||||
extern int socket_tcp_bind(const char * ip, int port);
|
||||
extern int socket_udp_bind(const char * ip, int port);
|
||||
|
||||
extern socket_t socket_accept(socket_t s, struct sockaddr_in *peer);
|
||||
extern void socket_close(socket_t s);
|
||||
extern socket_t socket_connect(const char* host, WORD port);
|
||||
|
||||
extern void socket_nonblock(socket_t s);
|
||||
extern void socket_block(socket_t s);
|
||||
extern void socket_dontroute(socket_t s);
|
||||
extern void socket_lingeroff(socket_t s);
|
||||
extern void socket_lingeron(socket_t s);
|
||||
|
||||
extern void socket_sndbuf(socket_t s, unsigned int opt);
|
||||
extern void socket_rcvbuf(socket_t s, unsigned int opt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,100 +1,16 @@
|
||||
#ifndef __INC_LIBTHECORE_STDAFX_H__
|
||||
#define __INC_LIBTHECORE_STDAFX_H__
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define INLINE __inline__
|
||||
#elif defined(_MSC_VER)
|
||||
#define INLINE inline
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <tchar.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <conio.h>
|
||||
#include <process.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <locale.h>
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "xdirent.h"
|
||||
#include "xgetopt.h"
|
||||
|
||||
#define S_ISDIR(m) (m & _S_IFDIR)
|
||||
#define snprintf _snprintf
|
||||
|
||||
struct timespec
|
||||
{
|
||||
time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* and nanoseconds */
|
||||
};
|
||||
|
||||
#define __USE_SELECT__
|
||||
|
||||
#define PATH_MAX _MAX_PATH
|
||||
|
||||
// C runtime library adjustments
|
||||
#define strncat(dst, src, size) strcat_s(dst, size, src)
|
||||
#define strncpy(dst, src, size) strncpy_s(dst, size, src, _TRUNCATE)
|
||||
#define strtoull(str, endptr, base) _strtoui64(str, endptr, base)
|
||||
#define strtof(str, endptr) (float)strtod(str, endptr)
|
||||
#define strcasecmp(s1, s2) stricmp(s1, s2)
|
||||
#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
|
||||
#define atoll(str) _atoi64(str)
|
||||
#define localtime_r(timet, result) localtime_s(result, timet)
|
||||
#define strtok_r(s, delim, ptrptr) strtok_s(s, delim, ptrptr)
|
||||
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
#define typeof(t) BOOST_TYPEOF(t)
|
||||
|
||||
// dummy declaration of non-supported signals
|
||||
#define SIGUSR1 30 /* user defined signal 1 */
|
||||
#define SIGUSR2 31 /* user defined signal 2 */
|
||||
|
||||
inline void usleep(unsigned long usec) {
|
||||
::Sleep(usec / 1000);
|
||||
}
|
||||
inline unsigned sleep(unsigned sec) {
|
||||
::Sleep(sec * 1000);
|
||||
return 0;
|
||||
}
|
||||
inline double rint(double x)
|
||||
{
|
||||
return ::floor(x+.5);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#define __USE_SELECT__
|
||||
#ifdef __CYGWIN__
|
||||
#define _POSIX_SOURCE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <climits>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
@ -112,28 +28,10 @@ inline double rint(double x)
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/event.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#define true (!false)
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
#include "typedef.h"
|
||||
#include "heart.h"
|
||||
#include "fdwatch.h"
|
||||
#include "socket.h"
|
||||
#include "buffer.h"
|
||||
#include "signal.h"
|
||||
#include "signals.h"
|
||||
#include "log.h"
|
||||
#include "main.h"
|
||||
#include "utils.h"
|
||||
|
@ -1,27 +1,23 @@
|
||||
#ifndef __INC_LIBTHECORE_TYPEDEF_H__
|
||||
#define __INC_LIBTHECORE_TYPEDEF_H__
|
||||
|
||||
typedef unsigned long int QWORD;
|
||||
typedef unsigned char UBYTE;
|
||||
typedef signed char sbyte;
|
||||
typedef unsigned short sh_int;
|
||||
#include <cstdint>
|
||||
|
||||
typedef uint64_t QWORD;
|
||||
typedef uint8_t UBYTE;
|
||||
typedef int8_t sbyte;
|
||||
typedef uint16_t sh_int;
|
||||
|
||||
#ifndef __WIN32__
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#endif
|
||||
|
||||
typedef unsigned int DWORD;
|
||||
typedef int BOOL;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
typedef int socket_t;
|
||||
typedef uint32_t DWORD;
|
||||
typedef uint32_t BOOL;
|
||||
typedef uint8_t BYTE;
|
||||
typedef uint16_t WORD;
|
||||
typedef int32_t LONG;
|
||||
typedef uint32_t ULONG;
|
||||
typedef int32_t INT;
|
||||
typedef uint32_t UINT;
|
||||
|
||||
#else
|
||||
|
||||
|
@ -1,461 +0,0 @@
|
||||
#define __LIBTHECORE__
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifndef __USE_SELECT__
|
||||
|
||||
LPFDWATCH fdwatch_new(int nfiles)
|
||||
{
|
||||
LPFDWATCH fdw;
|
||||
int kq;
|
||||
|
||||
kq = kqueue();
|
||||
|
||||
if (kq == -1)
|
||||
{
|
||||
sys_err("%s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CREATE(fdw, FDWATCH, 1);
|
||||
|
||||
fdw->kq = kq;
|
||||
fdw->nfiles = nfiles;
|
||||
fdw->nkqevents = 0;
|
||||
|
||||
CREATE(fdw->kqevents, KEVENT, nfiles * 2);
|
||||
CREATE(fdw->kqrevents, KEVENT, nfiles * 2);
|
||||
CREATE(fdw->fd_event_idx, int, nfiles);
|
||||
CREATE(fdw->fd_rw, int, nfiles);
|
||||
CREATE(fdw->fd_data, void*, nfiles);
|
||||
|
||||
return (fdw);
|
||||
}
|
||||
|
||||
void fdwatch_delete(LPFDWATCH fdw)
|
||||
{
|
||||
free(fdw->fd_data);
|
||||
free(fdw->fd_rw);
|
||||
free(fdw->kqevents);
|
||||
free(fdw->kqrevents);
|
||||
free(fdw->fd_event_idx);
|
||||
free(fdw);
|
||||
}
|
||||
|
||||
int fdwatch(LPFDWATCH fdw, struct timeval *timeout)
|
||||
{
|
||||
int i, r;
|
||||
struct timespec ts;
|
||||
|
||||
if (fdw->nkqevents)
|
||||
sys_log(2, "fdwatch: nkqevents %d", fdw->nkqevents);
|
||||
|
||||
if (!timeout)
|
||||
{
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
r = kevent(fdw->kq, fdw->kqevents, fdw->nkqevents, fdw->kqrevents, fdw->nfiles, &ts);
|
||||
}
|
||||
else
|
||||
{
|
||||
ts.tv_sec = timeout->tv_sec;
|
||||
ts.tv_nsec = timeout->tv_usec;
|
||||
|
||||
r = kevent(fdw->kq, fdw->kqevents, fdw->nkqevents, fdw->kqrevents, fdw->nfiles, &ts);
|
||||
}
|
||||
|
||||
fdw->nkqevents = 0;
|
||||
|
||||
if (r == -1)
|
||||
return -1;
|
||||
|
||||
memset(fdw->fd_event_idx, 0, sizeof(int) * fdw->nfiles);
|
||||
|
||||
for (i = 0; i < r; i++)
|
||||
{
|
||||
int fd = fdw->kqrevents[i].ident;
|
||||
|
||||
if (fd >= fdw->nfiles)
|
||||
sys_err("ident overflow %d nfiles: %d", fdw->kqrevents[i].ident, fdw->nfiles);
|
||||
else
|
||||
{
|
||||
if (fdw->kqrevents[i].filter == EVFILT_WRITE)
|
||||
fdw->fd_event_idx[fd] = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
void fdwatch_register(LPFDWATCH fdw, int flag, int fd, int rw)
|
||||
{
|
||||
if (flag == EV_DELETE)
|
||||
{
|
||||
if (fdw->fd_rw[fd] & FDW_READ)
|
||||
{
|
||||
fdw->kqevents[fdw->nkqevents].ident = fd;
|
||||
fdw->kqevents[fdw->nkqevents].flags = flag;
|
||||
fdw->kqevents[fdw->nkqevents].filter = EVFILT_READ;
|
||||
++fdw->nkqevents;
|
||||
}
|
||||
|
||||
if (fdw->fd_rw[fd] & FDW_WRITE)
|
||||
{
|
||||
fdw->kqevents[fdw->nkqevents].ident = fd;
|
||||
fdw->kqevents[fdw->nkqevents].flags = flag;
|
||||
fdw->kqevents[fdw->nkqevents].filter = EVFILT_WRITE;
|
||||
++fdw->nkqevents;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fdw->kqevents[fdw->nkqevents].ident = fd;
|
||||
fdw->kqevents[fdw->nkqevents].flags = flag;
|
||||
fdw->kqevents[fdw->nkqevents].filter = (rw == FDW_READ) ? EVFILT_READ : EVFILT_WRITE;
|
||||
|
||||
++fdw->nkqevents;
|
||||
}
|
||||
}
|
||||
|
||||
void fdwatch_clear_fd(LPFDWATCH fdw, socket_t fd)
|
||||
{
|
||||
fdw->fd_data[fd] = NULL;
|
||||
fdw->fd_rw[fd] = 0;
|
||||
}
|
||||
|
||||
void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void * client_data, int rw, int oneshot)
|
||||
{
|
||||
int flag;
|
||||
|
||||
if (fd >= fdw->nfiles)
|
||||
{
|
||||
sys_err("fd overflow %d", fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fdw->fd_rw[fd] & rw)
|
||||
return;
|
||||
|
||||
fdw->fd_rw[fd] |= rw;
|
||||
sys_log(2, "FDWATCH_REGISTER fdw %p fd %d rw %d data %p", fdw, fd, rw, client_data);
|
||||
|
||||
if (!oneshot)
|
||||
flag = EV_ADD;
|
||||
else
|
||||
{
|
||||
sys_log(2, "ADD ONESHOT fd_rw %d", fdw->fd_rw[fd]);
|
||||
flag = EV_ADD | EV_ONESHOT;
|
||||
fdw->fd_rw[fd] |= FDW_WRITE_ONESHOT;
|
||||
}
|
||||
|
||||
fdw->fd_data[fd] = client_data;
|
||||
fdwatch_register(fdw, flag, fd, rw);
|
||||
}
|
||||
|
||||
void fdwatch_del_fd(LPFDWATCH fdw, socket_t fd)
|
||||
{
|
||||
fdwatch_register(fdw, EV_DELETE, fd, 0);
|
||||
fdwatch_clear_fd(fdw, fd);
|
||||
}
|
||||
|
||||
void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
||||
{
|
||||
assert(event_idx < fdw->nfiles * 2);
|
||||
|
||||
if (fdw->kqrevents[event_idx].ident != fd)
|
||||
return;
|
||||
|
||||
fdw->kqrevents[event_idx].ident = 0;
|
||||
}
|
||||
|
||||
int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
||||
{
|
||||
assert(event_idx < fdw->nfiles * 2);
|
||||
|
||||
if (fdw->kqrevents[event_idx].ident != fd)
|
||||
return 0;
|
||||
|
||||
if (fdw->kqrevents[event_idx].flags & EV_ERROR)
|
||||
return FDW_EOF;
|
||||
|
||||
if (fdw->kqrevents[event_idx].flags & EV_EOF)
|
||||
return FDW_EOF;
|
||||
|
||||
if (fdw->kqrevents[event_idx].filter == EVFILT_READ)
|
||||
{
|
||||
if (fdw->fd_rw[fd] & FDW_READ)
|
||||
return FDW_READ;
|
||||
}
|
||||
else if (fdw->kqrevents[event_idx].filter == EVFILT_WRITE)
|
||||
{
|
||||
if (fdw->fd_rw[fd] & FDW_WRITE)
|
||||
{
|
||||
if (fdw->fd_rw[fd] & FDW_WRITE_ONESHOT)
|
||||
fdw->fd_rw[fd] &= ~FDW_WRITE;
|
||||
|
||||
return FDW_WRITE;
|
||||
}
|
||||
}
|
||||
else
|
||||
sys_err("fdwatch_check_event: Unknown filter %d (descriptor %d)", fdw->kqrevents[event_idx].filter, fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx)
|
||||
{
|
||||
assert(event_idx < fdw->nfiles * 2);
|
||||
return fdw->kqrevents[event_idx].ident;
|
||||
}
|
||||
|
||||
int fdwatch_get_buffer_size(LPFDWATCH fdw, socket_t fd)
|
||||
{
|
||||
int event_idx = fdw->fd_event_idx[fd];
|
||||
|
||||
if (fdw->kqrevents[event_idx].filter == EVFILT_WRITE)
|
||||
return fdw->kqrevents[event_idx].data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx)
|
||||
{
|
||||
int fd;
|
||||
|
||||
assert(event_idx < fdw->nfiles * 2);
|
||||
|
||||
fd = fdw->kqrevents[event_idx].ident;
|
||||
|
||||
if (fd >= fdw->nfiles)
|
||||
return NULL;
|
||||
|
||||
return (fdw->fd_data[fd]);
|
||||
}
|
||||
#else // ifndef __USE_SELECT__
|
||||
|
||||
#ifdef __WIN32__
|
||||
static int win32_init_refcount = 0;
|
||||
|
||||
static bool win32_init()
|
||||
{
|
||||
if (win32_init_refcount > 0)
|
||||
{
|
||||
win32_init_refcount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
WORD wVersion = MAKEWORD(2, 0);
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup(wVersion, &wsaData) != 0)
|
||||
return false;
|
||||
|
||||
win32_init_refcount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void win32_deinit()
|
||||
{
|
||||
if (--win32_init_refcount <= 0)
|
||||
WSACleanup();
|
||||
}
|
||||
#endif
|
||||
|
||||
LPFDWATCH fdwatch_new(int nfiles)
|
||||
{
|
||||
LPFDWATCH fdw;
|
||||
|
||||
#ifdef __WIN32__
|
||||
if (!win32_init())
|
||||
return NULL;
|
||||
#endif
|
||||
// nfiles value is limited to FD_SETSIZE (64)
|
||||
CREATE(fdw, FDWATCH, 1);
|
||||
fdw->nfiles = MIN(nfiles, FD_SETSIZE);
|
||||
|
||||
FD_ZERO(&fdw->rfd_set);
|
||||
FD_ZERO(&fdw->wfd_set);
|
||||
|
||||
CREATE(fdw->select_fds, socket_t, nfiles);
|
||||
CREATE(fdw->select_rfdidx, int, nfiles);
|
||||
|
||||
fdw->nselect_fds = 0;
|
||||
|
||||
CREATE(fdw->fd_rw, int, nfiles);
|
||||
CREATE(fdw->fd_data, void*, nfiles);
|
||||
|
||||
return (fdw);
|
||||
}
|
||||
|
||||
void fdwatch_delete(LPFDWATCH fdw)
|
||||
{
|
||||
free(fdw->fd_data);
|
||||
free(fdw->fd_rw);
|
||||
free(fdw->select_fds);
|
||||
free(fdw->select_rfdidx);
|
||||
free(fdw);
|
||||
|
||||
#ifdef __WIN32__
|
||||
win32_deinit();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int fdwatch_get_fdidx(LPFDWATCH fdw, socket_t fd) {
|
||||
int i;
|
||||
for (i = 0; i < fdw->nselect_fds; ++i) {
|
||||
if (fdw->select_fds[i] == fd) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fdwatch_add_fd(LPFDWATCH fdw, socket_t fd, void* client_data, int rw, int oneshot)
|
||||
{
|
||||
int idx = fdwatch_get_fdidx(fdw, fd);
|
||||
if (idx < 0) {
|
||||
if (fdw->nselect_fds >= fdw->nfiles) {
|
||||
return;
|
||||
}
|
||||
idx = fdw->nselect_fds;
|
||||
fdw->select_fds[fdw->nselect_fds++] = fd;
|
||||
fdw->fd_rw[idx] = rw;
|
||||
} else {
|
||||
fdw->fd_rw[idx] |= rw;
|
||||
}
|
||||
fdw->fd_data[idx] = client_data;
|
||||
|
||||
if (rw & FDW_READ)
|
||||
FD_SET(fd, &fdw->rfd_set);
|
||||
|
||||
if (rw & FDW_WRITE)
|
||||
FD_SET(fd, &fdw->wfd_set);
|
||||
}
|
||||
|
||||
void fdwatch_del_fd(LPFDWATCH fdw, socket_t fd)
|
||||
{
|
||||
if (fdw->nselect_fds <= 0) {
|
||||
return;
|
||||
}
|
||||
int idx = fdwatch_get_fdidx(fdw, fd);
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
--fdw->nselect_fds;
|
||||
|
||||
fdw->select_fds[idx] = fdw->select_fds[fdw->nselect_fds];
|
||||
fdw->fd_data[idx] = fdw->fd_data[fdw->nselect_fds];
|
||||
fdw->fd_rw[idx] = fdw->fd_rw[fdw->nselect_fds];
|
||||
|
||||
FD_CLR(fd, &fdw->rfd_set);
|
||||
FD_CLR(fd, &fdw->wfd_set);
|
||||
}
|
||||
|
||||
int fdwatch(LPFDWATCH fdw, struct timeval *timeout)
|
||||
{
|
||||
int r, i, event_idx;
|
||||
struct timeval tv;
|
||||
|
||||
fdw->working_rfd_set = fdw->rfd_set;
|
||||
fdw->working_wfd_set = fdw->wfd_set;
|
||||
|
||||
if (!timeout)
|
||||
{
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
r = select(0, &fdw->working_rfd_set, &fdw->working_wfd_set, (fd_set*) 0, &tv);
|
||||
}
|
||||
else
|
||||
{
|
||||
tv = *timeout;
|
||||
r = select(0, &fdw->working_rfd_set, &fdw->working_wfd_set, (fd_set*) 0, &tv);
|
||||
}
|
||||
|
||||
if (r == -1)
|
||||
return -1;
|
||||
|
||||
event_idx = 0;
|
||||
|
||||
for (i = 0; i < fdw->nselect_fds; ++i)
|
||||
{
|
||||
if (fdwatch_check_fd(fdw, fdw->select_fds[i]))
|
||||
fdw->select_rfdidx[event_idx++] = i;
|
||||
}
|
||||
|
||||
return event_idx;
|
||||
}
|
||||
|
||||
int fdwatch_check_fd(LPFDWATCH fdw, socket_t fd)
|
||||
{
|
||||
int idx = fdwatch_get_fdidx(fdw, fd);
|
||||
if (idx < 0) {
|
||||
return 0;
|
||||
}
|
||||
int result = 0;
|
||||
if ((fdw->fd_rw[idx] & FDW_READ) && FD_ISSET(fd, &fdw->working_rfd_set)) {
|
||||
result |= FDW_READ;
|
||||
}
|
||||
if ((fdw->fd_rw[idx] & FDW_WRITE) && FD_ISSET(fd, &fdw->working_wfd_set)) {
|
||||
result |= FDW_WRITE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void * fdwatch_get_client_data(LPFDWATCH fdw, unsigned int event_idx)
|
||||
{
|
||||
int idx = fdw->select_rfdidx[event_idx];
|
||||
if (idx < 0 || fdw->nfiles <= idx) {
|
||||
return NULL;
|
||||
}
|
||||
return fdw->fd_data[idx];
|
||||
}
|
||||
|
||||
int fdwatch_get_ident(LPFDWATCH fdw, unsigned int event_idx)
|
||||
{
|
||||
int idx = fdw->select_rfdidx[event_idx];
|
||||
if (idx < 0 || fdw->nfiles <= idx) {
|
||||
return 0;
|
||||
}
|
||||
return (int)fdw->select_fds[idx];
|
||||
}
|
||||
|
||||
void fdwatch_clear_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
||||
{
|
||||
int idx = fdw->select_rfdidx[event_idx];
|
||||
if (idx < 0 || fdw->nfiles <= idx) {
|
||||
return;
|
||||
}
|
||||
socket_t rfd = fdw->select_fds[idx];
|
||||
if (fd != rfd) {
|
||||
return;
|
||||
}
|
||||
FD_CLR(fd, &fdw->working_rfd_set);
|
||||
FD_CLR(fd, &fdw->working_wfd_set);
|
||||
}
|
||||
|
||||
int fdwatch_check_event(LPFDWATCH fdw, socket_t fd, unsigned int event_idx)
|
||||
{
|
||||
int idx = fdw->select_rfdidx[event_idx];
|
||||
if (idx < 0 || fdw->nfiles <= idx) {
|
||||
return 0;
|
||||
}
|
||||
socket_t rfd = fdw->select_fds[idx];
|
||||
if (fd != rfd) {
|
||||
return 0;
|
||||
}
|
||||
int result = fdwatch_check_fd(fdw, fd);
|
||||
if (result & FDW_READ) {
|
||||
return FDW_READ;
|
||||
} else if (result & FDW_WRITE) {
|
||||
return FDW_WRITE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdwatch_get_buffer_size(LPFDWATCH fdw, socket_t fd)
|
||||
{
|
||||
return INT_MAX; // XXX TODO
|
||||
}
|
||||
|
||||
#endif
|
@ -42,7 +42,7 @@ void log_file_rotate(LPLOGFILE logfile);
|
||||
void log_file_check(LPLOGFILE logfile);
|
||||
void log_file_set_dir(const char *dir);
|
||||
|
||||
static unsigned int log_level_bits = 0;
|
||||
static unsigned int log_level_bits = 7;
|
||||
|
||||
void log_set_level(unsigned int bit)
|
||||
{
|
||||
|
@ -8,11 +8,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "memory.h"
|
||||
|
||||
extern void GOST_Init();
|
||||
|
||||
LPHEART thecore_heart = NULL;
|
||||
|
||||
volatile int shutdowned = FALSE;
|
||||
volatile int shutdowned = false;
|
||||
volatile int tics = 0;
|
||||
unsigned int thecore_profiler[NUM_PF];
|
||||
|
||||
@ -67,7 +65,7 @@ int thecore_init(int fps, HEARTFUNC heartbeat_func)
|
||||
|
||||
void thecore_shutdown()
|
||||
{
|
||||
shutdowned = TRUE;
|
||||
shutdowned = true;
|
||||
}
|
||||
|
||||
int thecore_idle(void)
|
||||
|
@ -35,7 +35,7 @@ RETSIGTYPE checkpointing(int sig)
|
||||
|
||||
RETSIGTYPE hupsig(int sig)
|
||||
{
|
||||
shutdowned = TRUE;
|
||||
shutdowned = true;
|
||||
sys_err("SIGHUP, SIGINT, SIGTERM signal has been received. shutting down.");
|
||||
}
|
||||
|
@ -1,555 +0,0 @@
|
||||
/*
|
||||
* Filename: socket.c
|
||||
* Description: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ҽ<EFBFBD>.
|
||||
*
|
||||
* Author: <20><><EFBFBD><EFBFBD> aka. Cronan
|
||||
*/
|
||||
#define __LIBTHECORE__
|
||||
#include "stdafx.h"
|
||||
|
||||
/* Forwards */
|
||||
void socket_lingeron(socket_t s);
|
||||
void socket_lingeroff(socket_t s);
|
||||
void socket_timeout(socket_t s, long sec, long usec);
|
||||
void socket_reuse(socket_t s);
|
||||
void socket_keepalive(socket_t s);
|
||||
|
||||
int socket_udp_read(socket_t desc, char * read_point, size_t space_left, struct sockaddr * from, socklen_t * fromlen)
|
||||
{
|
||||
/*
|
||||
ssize_t recvfrom(int s, void * buf, size_t len, int flags, struct sockaddr * from, socklen_t * fromlen);
|
||||
*/
|
||||
ssize_t ret;
|
||||
ret = recvfrom(desc, read_point, space_left, 0, from, fromlen);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int socket_read(socket_t desc, char* read_point, size_t space_left)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = recv(desc, read_point, space_left, 0);
|
||||
|
||||
if (ret > 0)
|
||||
return ret;
|
||||
|
||||
if (ret == 0) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
return -1;
|
||||
|
||||
#ifdef EINTR /* Interrupted system call - various platforms */
|
||||
if (errno == EINTR)
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
#ifdef EAGAIN /* POSIX */
|
||||
if (errno == EAGAIN)
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
#ifdef EWOULDBLOCK /* BSD */
|
||||
if (errno == EWOULDBLOCK)
|
||||
return (0);
|
||||
#endif /* EWOULDBLOCK */
|
||||
|
||||
#ifdef EDEADLK /* Macintosh */
|
||||
if (errno == EDEADLK)
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
int wsa_error = WSAGetLastError();
|
||||
if (wsa_error == WSAEWOULDBLOCK) {
|
||||
return 0;
|
||||
}
|
||||
sys_log(0, "socket_read: WSAGetLastError returned %d", wsa_error);
|
||||
#endif
|
||||
|
||||
sys_err("about to lose connection");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int socket_write_tcp(socket_t desc, const char *txt, int length)
|
||||
{
|
||||
int bytes_written = send(desc, txt, length, 0);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>
|
||||
if (bytes_written > 0)
|
||||
return (bytes_written);
|
||||
|
||||
if (bytes_written == 0)
|
||||
return -1;
|
||||
|
||||
#ifdef EAGAIN /* POSIX */
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef EWOULDBLOCK /* BSD */
|
||||
if (errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef EDEADLK /* Macintosh */
|
||||
if (errno == EDEADLK)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
int wsa_error = WSAGetLastError();
|
||||
if (wsa_error == WSAEWOULDBLOCK) {
|
||||
return 0;
|
||||
}
|
||||
sys_log(0, "socket_write_tcp: WSAGetLastError returned %d", wsa_error);
|
||||
#endif
|
||||
|
||||
/* Looks like the error was fatal. Too bad. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int socket_write(socket_t desc, const char *data, size_t length)
|
||||
{
|
||||
size_t total;
|
||||
int bytes_written;
|
||||
|
||||
total = length;
|
||||
|
||||
do
|
||||
{
|
||||
if ((bytes_written = socket_write_tcp(desc, data, total)) < 0)
|
||||
{
|
||||
#ifdef EWOULDBLOCK
|
||||
if (errno == EWOULDBLOCK)
|
||||
errno = EAGAIN;
|
||||
#endif
|
||||
if (errno == EAGAIN)
|
||||
sys_err("socket write would block, about to close!");
|
||||
else
|
||||
sys_err("write to desc error"); // '<27><><EFBFBD><EFBFBD>' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD>.
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
data += bytes_written;
|
||||
total -= bytes_written;
|
||||
}
|
||||
}
|
||||
while (total > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_bind(const char * ip, int port, int protocol)
|
||||
{
|
||||
int s;
|
||||
#ifdef __WIN32
|
||||
SOCKADDR_IN sa;
|
||||
#else
|
||||
struct sockaddr_in sa;
|
||||
#endif
|
||||
|
||||
if ((s = socket(AF_INET, protocol, 0)) < 0)
|
||||
{
|
||||
sys_err("socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
socket_reuse(s);
|
||||
#ifndef __linux__
|
||||
#if defined(WIN32)
|
||||
// Winsock2: SO_DONTLINGER, SO_KEEPALIVE, SO_LINGER, and SO_OOBINLINE are
|
||||
// not supported on sockets of type SOCK_DGRAM
|
||||
if (protocol == SOCK_STREAM) {
|
||||
socket_lingeroff(s);
|
||||
}
|
||||
#else
|
||||
socket_lingeroff(s);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߿<EFBFBD><DFBF><EFBFBD><EFBFBD>θ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BIND ip<69><70> INADDR_ANY<4E><59> <20><><EFBFBD><EFBFBD>
|
||||
//(<28><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||||
#ifndef __WIN32__
|
||||
sa.sin_addr.s_addr = inet_addr(ip);
|
||||
#else
|
||||
sa.sin_addr.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
sa.sin_port = htons((unsigned short) port);
|
||||
|
||||
if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
|
||||
{
|
||||
sys_err("bind: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#ifndef __linux__
|
||||
socket_nonblock(s);
|
||||
#endif
|
||||
|
||||
if (protocol == SOCK_STREAM)
|
||||
{
|
||||
sys_log(0, "SYSTEM: BINDING TCP PORT ON [%d] (fd %d)", port, s);
|
||||
listen(s, SOMAXCONN);
|
||||
}
|
||||
else
|
||||
sys_log(0, "SYSTEM: BINDING UDP PORT ON [%d] (fd %d)", port, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int socket_tcp_bind(const char * ip, int port)
|
||||
{
|
||||
return socket_bind(ip, port, SOCK_STREAM);
|
||||
}
|
||||
|
||||
int socket_udp_bind(const char * ip, int port)
|
||||
{
|
||||
return socket_bind(ip, port, SOCK_DGRAM);
|
||||
}
|
||||
|
||||
void socket_close(socket_t s)
|
||||
{
|
||||
#ifdef __WIN32__
|
||||
closesocket(s);
|
||||
#else
|
||||
close(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
socket_t socket_accept(socket_t s, struct sockaddr_in *peer)
|
||||
{
|
||||
socket_t desc;
|
||||
socklen_t i;
|
||||
|
||||
i = sizeof(*peer);
|
||||
|
||||
if ((desc = accept(s, (struct sockaddr *) peer, &i)) == -1)
|
||||
{
|
||||
sys_err("accept: %s (fd %d)", strerror(errno), s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (desc >= 65500)
|
||||
{
|
||||
sys_err("SOCKET FD 65500 LIMIT! %d", desc);
|
||||
socket_close(s);
|
||||
return -1;
|
||||
}
|
||||
#ifndef __linux__
|
||||
socket_nonblock(desc);
|
||||
socket_lingeroff(desc);
|
||||
#endif
|
||||
return (desc);
|
||||
}
|
||||
|
||||
socket_t socket_connect(const char* host, WORD port)
|
||||
{
|
||||
socket_t s = 0;
|
||||
struct sockaddr_in server_addr;
|
||||
int rslt;
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD>ּ<EFBFBD> <20><><EFBFBD><EFBFBD>ü <20>ʱ<EFBFBD>ȭ */
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
|
||||
if (isdigit(*host))
|
||||
server_addr.sin_addr.s_addr = inet_addr(host);
|
||||
else
|
||||
{
|
||||
struct hostent *hp;
|
||||
|
||||
if ((hp = gethostbyname(host)) == NULL)
|
||||
{
|
||||
sys_err("socket_connect(): can not connect to %s:%d", host, port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy((char* ) &server_addr.sin_addr, hp->h_addr, sizeof(server_addr.sin_addr));
|
||||
}
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
socket_keepalive(s);
|
||||
socket_sndbuf(s, 233016);
|
||||
socket_rcvbuf(s, 233016);
|
||||
socket_timeout(s, 10, 0);
|
||||
socket_lingeron(s);
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û */
|
||||
if ((rslt = connect(s, (struct sockaddr *) &server_addr, sizeof(server_addr))) < 0)
|
||||
{
|
||||
socket_close(s);
|
||||
|
||||
#ifdef __WIN32__
|
||||
switch (WSAGetLastError())
|
||||
#else
|
||||
switch (rslt)
|
||||
#endif
|
||||
{
|
||||
#ifdef __WIN32__
|
||||
case WSAETIMEDOUT:
|
||||
#else
|
||||
case EINTR:
|
||||
#endif
|
||||
sys_err("HOST %s:%d connection timeout.", host, port);
|
||||
break;
|
||||
#ifdef __WIN32__
|
||||
case WSAECONNREFUSED:
|
||||
#else
|
||||
case ECONNREFUSED:
|
||||
#endif
|
||||
sys_err("HOST %s:%d port is not opened. connection refused.", host, port);
|
||||
break;
|
||||
#ifdef __WIN32__
|
||||
case WSAENETUNREACH:
|
||||
#else
|
||||
case ENETUNREACH:
|
||||
#endif
|
||||
sys_err("HOST %s:%d is not reachable from this host.", host, port);
|
||||
break;
|
||||
|
||||
default:
|
||||
sys_err("HOST %s:%d, could not connect.", host, port);
|
||||
break;
|
||||
}
|
||||
|
||||
perror("connect");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
#ifndef __WIN32__
|
||||
|
||||
#ifndef O_NONBLOCK
|
||||
#define O_NONBLOCK O_NDELAY
|
||||
#endif
|
||||
|
||||
void socket_nonblock(socket_t s)
|
||||
{
|
||||
int flags;
|
||||
|
||||
flags = fcntl(s, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
|
||||
if (fcntl(s, F_SETFL, flags) < 0)
|
||||
{
|
||||
sys_err("fcntl: nonblock: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void socket_block(socket_t s)
|
||||
{
|
||||
int flags;
|
||||
|
||||
flags = fcntl(s, F_GETFL, 0);
|
||||
flags &= ~O_NONBLOCK;
|
||||
|
||||
if (fcntl(s, F_SETFL, flags) < 0)
|
||||
{
|
||||
sys_err("fcntl: nonblock: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void socket_nonblock(socket_t s)
|
||||
{
|
||||
unsigned long val = 1;
|
||||
ioctlsocket(s, FIONBIO, &val);
|
||||
}
|
||||
|
||||
void socket_block(socket_t s)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
ioctlsocket(s, FIONBIO, &val);
|
||||
}
|
||||
#endif
|
||||
|
||||
void socket_dontroute(socket_t s)
|
||||
{
|
||||
int set;
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (const char *) &set, sizeof(int)) < 0)
|
||||
{
|
||||
sys_err("setsockopt: dontroute: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void socket_lingeroff(socket_t s)
|
||||
{
|
||||
#if defined(__WIN32__)
|
||||
int linger;
|
||||
linger = 0;
|
||||
#else
|
||||
struct linger linger;
|
||||
|
||||
linger.l_onoff = 0;
|
||||
linger.l_linger = 0;
|
||||
#endif
|
||||
if (setsockopt(s, SOL_SOCKET, SO_LINGER, (const char*) &linger, sizeof(linger)) < 0)
|
||||
{
|
||||
sys_err("setsockopt: linger: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void socket_lingeron(socket_t s)
|
||||
{
|
||||
#if defined(__WIN32__)
|
||||
int linger;
|
||||
linger = 0;
|
||||
#else
|
||||
struct linger linger;
|
||||
|
||||
linger.l_onoff = 1;
|
||||
linger.l_linger = 0;
|
||||
#endif
|
||||
if (setsockopt(s, SOL_SOCKET, SO_LINGER, (const char*) &linger, sizeof(linger)) < 0)
|
||||
{
|
||||
sys_err("setsockopt: linger: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void socket_rcvbuf(socket_t s, unsigned int opt)
|
||||
{
|
||||
socklen_t optlen;
|
||||
|
||||
optlen = sizeof(opt);
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const char*) &opt, optlen) < 0)
|
||||
{
|
||||
sys_err("setsockopt: rcvbuf: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
opt = 0;
|
||||
optlen = sizeof(opt);
|
||||
|
||||
if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*) &opt, &optlen) < 0)
|
||||
{
|
||||
sys_err("getsockopt: rcvbuf: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
sys_log(1, "SYSTEM: %d: receive buffer changed to %d", s, opt);
|
||||
}
|
||||
|
||||
void socket_sndbuf(socket_t s, unsigned int opt)
|
||||
{
|
||||
socklen_t optlen;
|
||||
|
||||
optlen = sizeof(opt);
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (const char*) &opt, optlen) < 0)
|
||||
{
|
||||
sys_err("setsockopt: sndbuf: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
opt = 0;
|
||||
optlen = sizeof(opt);
|
||||
|
||||
if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*) &opt, &optlen) < 0)
|
||||
{
|
||||
sys_err("getsockopt: sndbuf: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
sys_log(1, "SYSTEM: %d: send buffer changed to %d", s, opt);
|
||||
}
|
||||
|
||||
// sec : seconds, usec : microseconds
|
||||
void socket_timeout(socket_t s, long sec, long usec)
|
||||
{
|
||||
#ifndef __WIN32__
|
||||
struct timeval rcvopt;
|
||||
struct timeval sndopt;
|
||||
socklen_t optlen = sizeof(rcvopt);
|
||||
|
||||
rcvopt.tv_sec = sndopt.tv_sec = sec;
|
||||
rcvopt.tv_usec = sndopt.tv_usec = usec;
|
||||
#else
|
||||
socklen_t rcvopt, sndopt;
|
||||
socklen_t optlen = sizeof(rcvopt);
|
||||
sndopt = rcvopt = (sec * 1000) + (usec / 1000);
|
||||
#endif
|
||||
|
||||
#ifndef __linux__
|
||||
if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*) &rcvopt, optlen) < 0)
|
||||
{
|
||||
sys_err("setsockopt: timeout: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*) &rcvopt, &optlen) < 0)
|
||||
{
|
||||
sys_err("getsockopt: timeout: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
optlen = sizeof(sndopt);
|
||||
#ifndef __linux__
|
||||
if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char*) &sndopt, optlen) < 0)
|
||||
{
|
||||
sys_err("setsockopt: timeout: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*) &sndopt, &optlen) < 0)
|
||||
{
|
||||
sys_err("getsockopt: timeout: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __WIN32__
|
||||
sys_log(1, "SYSTEM: %d: TIMEOUT RCV: %d.%d, SND: %d.%d", s, rcvopt.tv_sec, rcvopt.tv_usec, sndopt.tv_sec, sndopt.tv_usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
void socket_reuse(socket_t s)
|
||||
{
|
||||
int opt = 1;
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*) &opt, sizeof(opt)) < 0)
|
||||
{
|
||||
sys_err("setsockopt: reuse: %s", strerror(errno));
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void socket_keepalive(socket_t s)
|
||||
{
|
||||
int opt = 1;
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (const char*) &opt, sizeof(opt)) < 0)
|
||||
{
|
||||
perror("setsockopt: keepalive");
|
||||
socket_close(s);
|
||||
return;
|
||||
}
|
||||
}
|
@ -262,7 +262,7 @@ void parse_token(char *src, char *token, char *value)
|
||||
|
||||
struct tm * tm_calc(const struct tm * curr_tm, int days)
|
||||
{
|
||||
char yoon = FALSE;
|
||||
bool yoon = false;
|
||||
static struct tm new_tm;
|
||||
int monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
@ -281,10 +281,10 @@ struct tm * tm_calc(const struct tm * curr_tm, int days)
|
||||
if (!((new_tm.tm_year + 1900) % 100))
|
||||
{
|
||||
if (!((new_tm.tm_year + 1900) % 400))
|
||||
yoon = TRUE;
|
||||
yoon = true;
|
||||
}
|
||||
else
|
||||
yoon = TRUE;
|
||||
yoon = true;
|
||||
}
|
||||
|
||||
if (yoon)
|
||||
|
Reference in New Issue
Block a user