mirror of
https://github.com/curl/curl.git
synced 2025-09-10 14:12:41 +03:00
tests/server: round of tidy-ups (part 2)
General tidy-ups, to identify and reduce duplications and potential issues, while also making the server modules compile as a single binary. - ensure unique symbols and no shadowing across server sources, by renaming variables. - move globals common to multiple servers into shared `util` module. - drop constants with a single use. - undef macro before re-using them across server sources. - move common functions into shared `util` module. - drop redundant static declarations. - disable IPv6 code when built without IPv6. - start syncing the 3 almost identical copies of `sockdaemon` function. - drop unused `timeval.h` header. - drop `poll()` from `wait_ms()`, for macOS, following an earlier core update. Follow-up toc72cefea0f
#15096 Follow-up to9213e4e497
#16525 Cherry-picked from #15000 Closes #16609
This commit is contained in:
parent
07f99b72d5
commit
bc55b435af
|
@ -63,12 +63,6 @@
|
||||||
/* include memdebug.h last */
|
/* include memdebug.h last */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define DEFAULT_PORT 1883 /* MQTT default port */
|
|
||||||
|
|
||||||
#ifndef DEFAULT_CONFIG
|
|
||||||
#define DEFAULT_CONFIG "mqttd.config"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MQTT_MSG_CONNECT 0x10
|
#define MQTT_MSG_CONNECT 0x10
|
||||||
#define MQTT_MSG_CONNACK 0x20
|
#define MQTT_MSG_CONNACK 0x20
|
||||||
#define MQTT_MSG_PUBLISH 0x30
|
#define MQTT_MSG_PUBLISH 0x30
|
||||||
|
@ -77,7 +71,7 @@
|
||||||
#define MQTT_MSG_SUBACK 0x90
|
#define MQTT_MSG_SUBACK 0x90
|
||||||
#define MQTT_MSG_DISCONNECT 0xe0
|
#define MQTT_MSG_DISCONNECT 0xe0
|
||||||
|
|
||||||
struct configurable {
|
struct mqttd_configurable {
|
||||||
unsigned char version; /* initial version byte in the request must match
|
unsigned char version; /* initial version byte in the request must match
|
||||||
this */
|
this */
|
||||||
bool publish_before_suback;
|
bool publish_before_suback;
|
||||||
|
@ -90,39 +84,23 @@ struct configurable {
|
||||||
#define REQUEST_DUMP "server.input"
|
#define REQUEST_DUMP "server.input"
|
||||||
#define CONFIG_VERSION 5
|
#define CONFIG_VERSION 5
|
||||||
|
|
||||||
static struct configurable config;
|
static struct mqttd_configurable m_config;
|
||||||
|
|
||||||
static const char *configfile = DEFAULT_CONFIG;
|
static void mqttd_resetdefaults(void)
|
||||||
static const char *logdir = "log";
|
|
||||||
static char loglockfile[256];
|
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
static bool use_ipv6 = FALSE;
|
|
||||||
#endif
|
|
||||||
static const char *ipv_inuse = "IPv4";
|
|
||||||
static unsigned short port = DEFAULT_PORT;
|
|
||||||
|
|
||||||
static void resetdefaults(void)
|
|
||||||
{
|
{
|
||||||
logmsg("Reset to defaults");
|
logmsg("Reset to defaults");
|
||||||
config.version = CONFIG_VERSION;
|
m_config.version = CONFIG_VERSION;
|
||||||
config.publish_before_suback = FALSE;
|
m_config.publish_before_suback = FALSE;
|
||||||
config.short_publish = FALSE;
|
m_config.short_publish = FALSE;
|
||||||
config.excessive_remaining = FALSE;
|
m_config.excessive_remaining = FALSE;
|
||||||
config.error_connack = 0;
|
m_config.error_connack = 0;
|
||||||
config.testnum = 0;
|
m_config.testnum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char byteval(char *value)
|
static void mqttd_getconfig(void)
|
||||||
{
|
|
||||||
unsigned long num = strtoul(value, NULL, 10);
|
|
||||||
return num & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getconfig(void)
|
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(configfile, FOPEN_READTEXT);
|
FILE *fp = fopen(configfile, FOPEN_READTEXT);
|
||||||
resetdefaults();
|
mqttd_resetdefaults();
|
||||||
if(fp) {
|
if(fp) {
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
logmsg("parse config file");
|
logmsg("parse config file");
|
||||||
|
@ -131,28 +109,28 @@ static void getconfig(void)
|
||||||
char value[32];
|
char value[32];
|
||||||
if(2 == sscanf(buffer, "%31s %31s", key, value)) {
|
if(2 == sscanf(buffer, "%31s %31s", key, value)) {
|
||||||
if(!strcmp(key, "version")) {
|
if(!strcmp(key, "version")) {
|
||||||
config.version = byteval(value);
|
m_config.version = byteval(value);
|
||||||
logmsg("version [%d] set", config.version);
|
logmsg("version [%d] set", m_config.version);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "PUBLISH-before-SUBACK")) {
|
else if(!strcmp(key, "PUBLISH-before-SUBACK")) {
|
||||||
logmsg("PUBLISH-before-SUBACK set");
|
logmsg("PUBLISH-before-SUBACK set");
|
||||||
config.publish_before_suback = TRUE;
|
m_config.publish_before_suback = TRUE;
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "short-PUBLISH")) {
|
else if(!strcmp(key, "short-PUBLISH")) {
|
||||||
logmsg("short-PUBLISH set");
|
logmsg("short-PUBLISH set");
|
||||||
config.short_publish = TRUE;
|
m_config.short_publish = TRUE;
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "error-CONNACK")) {
|
else if(!strcmp(key, "error-CONNACK")) {
|
||||||
config.error_connack = byteval(value);
|
m_config.error_connack = byteval(value);
|
||||||
logmsg("error-CONNACK = %d", config.error_connack);
|
logmsg("error-CONNACK = %d", m_config.error_connack);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "Testnum")) {
|
else if(!strcmp(key, "Testnum")) {
|
||||||
config.testnum = atoi(value);
|
m_config.testnum = atoi(value);
|
||||||
logmsg("testnum = %d", config.testnum);
|
logmsg("testnum = %d", m_config.testnum);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "excessive-remaining")) {
|
else if(!strcmp(key, "excessive-remaining")) {
|
||||||
logmsg("excessive-remaining set");
|
logmsg("excessive-remaining set");
|
||||||
config.excessive_remaining = TRUE;
|
m_config.excessive_remaining = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,25 +141,6 @@ static void getconfig(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loghex(unsigned char *buffer, ssize_t len)
|
|
||||||
{
|
|
||||||
char data[12000];
|
|
||||||
ssize_t i;
|
|
||||||
unsigned char *ptr = buffer;
|
|
||||||
char *optr = data;
|
|
||||||
ssize_t width = 0;
|
|
||||||
int left = sizeof(data);
|
|
||||||
|
|
||||||
for(i = 0; i < len && (left >= 0); i++) {
|
|
||||||
msnprintf(optr, left, "%02x", ptr[i]);
|
|
||||||
width += 2;
|
|
||||||
optr += 2;
|
|
||||||
left -= 2;
|
|
||||||
}
|
|
||||||
if(width)
|
|
||||||
logmsg("'%s'", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FROM_CLIENT,
|
FROM_CLIENT,
|
||||||
FROM_SERVER
|
FROM_SERVER
|
||||||
|
@ -218,7 +177,7 @@ static int connack(FILE *dump, curl_socket_t fd)
|
||||||
};
|
};
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
|
||||||
packet[3] = config.error_connack;
|
packet[3] = m_config.error_connack;
|
||||||
|
|
||||||
rc = swrite(fd, (char *)packet, sizeof(packet));
|
rc = swrite(fd, (char *)packet, sizeof(packet));
|
||||||
if(rc > 0) {
|
if(rc > 0) {
|
||||||
|
@ -343,7 +302,7 @@ static size_t encode_length(size_t packetlen,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t decode_length(unsigned char *buf,
|
static size_t decode_length(unsigned char *buffer,
|
||||||
size_t buflen, size_t *lenbytes)
|
size_t buflen, size_t *lenbytes)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
@ -352,7 +311,7 @@ static size_t decode_length(unsigned char *buf,
|
||||||
unsigned char encoded = 0x80;
|
unsigned char encoded = 0x80;
|
||||||
|
|
||||||
for(i = 0; (i < buflen) && (encoded & 0x80); i++) {
|
for(i = 0; (i < buflen) && (encoded & 0x80); i++) {
|
||||||
encoded = buf[i];
|
encoded = buffer[i];
|
||||||
len += (encoded & 0x7f) * mult;
|
len += (encoded & 0x7f) * mult;
|
||||||
mult *= 0x80;
|
mult *= 0x80;
|
||||||
}
|
}
|
||||||
|
@ -379,7 +338,7 @@ static int publish(FILE *dump,
|
||||||
unsigned char rembuffer[4];
|
unsigned char rembuffer[4];
|
||||||
size_t encodedlen;
|
size_t encodedlen;
|
||||||
|
|
||||||
if(config.excessive_remaining) {
|
if(m_config.excessive_remaining) {
|
||||||
/* manually set illegal remaining length */
|
/* manually set illegal remaining length */
|
||||||
rembuffer[0] = 0xff;
|
rembuffer[0] = 0xff;
|
||||||
rembuffer[1] = 0xff;
|
rembuffer[1] = 0xff;
|
||||||
|
@ -410,7 +369,7 @@ static int publish(FILE *dump,
|
||||||
memcpy(&packet[payloadindex], payload, payloadlen);
|
memcpy(&packet[payloadindex], payload, payloadlen);
|
||||||
|
|
||||||
sendamount = packetlen;
|
sendamount = packetlen;
|
||||||
if(config.short_publish)
|
if(m_config.short_publish)
|
||||||
sendamount -= 2;
|
sendamount -= 2;
|
||||||
|
|
||||||
rc = swrite(fd, (char *)packet, sendamount);
|
rc = swrite(fd, (char *)packet, sendamount);
|
||||||
|
@ -493,9 +452,9 @@ static curl_socket_t mqttit(curl_socket_t fd)
|
||||||
if(!dump)
|
if(!dump)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
getconfig();
|
mqttd_getconfig();
|
||||||
|
|
||||||
testno = config.testnum;
|
testno = m_config.testnum;
|
||||||
|
|
||||||
if(testno)
|
if(testno)
|
||||||
logmsg("Found test number %ld", testno);
|
logmsg("Found test number %ld", testno);
|
||||||
|
@ -627,7 +586,7 @@ static curl_socket_t mqttit(curl_socket_t fd)
|
||||||
stream = test2fopen(testno, logdir);
|
stream = test2fopen(testno, logdir);
|
||||||
error = getpart(&data, &datalen, "reply", "data", stream);
|
error = getpart(&data, &datalen, "reply", "data", stream);
|
||||||
if(!error) {
|
if(!error) {
|
||||||
if(!config.publish_before_suback) {
|
if(!m_config.publish_before_suback) {
|
||||||
if(suback(dump, fd, packet_id)) {
|
if(suback(dump, fd, packet_id)) {
|
||||||
logmsg("failed sending SUBACK");
|
logmsg("failed sending SUBACK");
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -640,7 +599,7 @@ static curl_socket_t mqttit(curl_socket_t fd)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
free(data);
|
free(data);
|
||||||
if(config.publish_before_suback) {
|
if(m_config.publish_before_suback) {
|
||||||
if(suback(dump, fd, packet_id)) {
|
if(suback(dump, fd, packet_id)) {
|
||||||
logmsg("failed sending SUBACK");
|
logmsg("failed sending SUBACK");
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -698,7 +657,7 @@ end:
|
||||||
if sockfd is CURL_SOCKET_BAD, listendfd is a listening socket we must
|
if sockfd is CURL_SOCKET_BAD, listendfd is a listening socket we must
|
||||||
accept()
|
accept()
|
||||||
*/
|
*/
|
||||||
static bool incoming(curl_socket_t listenfd)
|
static bool mqttd_incoming(curl_socket_t listenfd)
|
||||||
{
|
{
|
||||||
fd_set fds_read;
|
fd_set fds_read;
|
||||||
fd_set fds_write;
|
fd_set fds_write;
|
||||||
|
@ -776,8 +735,9 @@ static bool incoming(curl_socket_t listenfd)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static curl_socket_t sockdaemon(curl_socket_t sock,
|
static curl_socket_t mqttd_sockdaemon(curl_socket_t sock,
|
||||||
unsigned short *listenport)
|
unsigned short *listenport,
|
||||||
|
bool bind_only)
|
||||||
{
|
{
|
||||||
/* passive daemon style */
|
/* passive daemon style */
|
||||||
srvr_sockaddr_union_t listener;
|
srvr_sockaddr_union_t listener;
|
||||||
|
@ -802,7 +762,9 @@ static curl_socket_t sockdaemon(curl_socket_t sock,
|
||||||
rc = wait_ms(delay);
|
rc = wait_ms(delay);
|
||||||
if(rc) {
|
if(rc) {
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
logmsg("wait_ms() failed with error (%d)", rc);
|
error = errno;
|
||||||
|
logmsg("wait_ms() failed with error (%d) %s",
|
||||||
|
error, strerror(error));
|
||||||
sclose(sock);
|
sclose(sock);
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
@ -896,6 +858,12 @@ static curl_socket_t sockdaemon(curl_socket_t sock,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* bindonly option forces no listening */
|
||||||
|
if(bind_only) {
|
||||||
|
logmsg("instructed to bind port without listening");
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
/* start accepting connections */
|
/* start accepting connections */
|
||||||
rc = listen(sock, 5);
|
rc = listen(sock, 5);
|
||||||
if(0 != rc) {
|
if(0 != rc) {
|
||||||
|
@ -916,13 +884,15 @@ int main(int argc, char *argv[])
|
||||||
curl_socket_t msgsock = CURL_SOCKET_BAD;
|
curl_socket_t msgsock = CURL_SOCKET_BAD;
|
||||||
int wrotepidfile = 0;
|
int wrotepidfile = 0;
|
||||||
int wroteportfile = 0;
|
int wroteportfile = 0;
|
||||||
const char *pidname = ".mqttd.pid";
|
|
||||||
const char *portname = ".mqttd.port";
|
|
||||||
bool juggle_again;
|
bool juggle_again;
|
||||||
int error;
|
int error;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
|
|
||||||
|
pidname = ".mqttd.pid";
|
||||||
|
portname = ".mqttd.port";
|
||||||
serverlogfile = "log/mqttd.log";
|
serverlogfile = "log/mqttd.log";
|
||||||
|
configfile = "mqttd.config";
|
||||||
|
server_port = 1883; /* MQTT default port */
|
||||||
|
|
||||||
while(argc > arg) {
|
while(argc > arg) {
|
||||||
if(!strcmp("--version", argv[arg])) {
|
if(!strcmp("--version", argv[arg])) {
|
||||||
|
@ -986,7 +956,7 @@ int main(int argc, char *argv[])
|
||||||
argv[arg]);
|
argv[arg]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
port = util_ultous(ulnum);
|
server_port = util_ultous(ulnum);
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1036,7 +1006,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
{
|
{
|
||||||
/* passive daemon style */
|
/* passive daemon style */
|
||||||
sock = sockdaemon(sock, &port);
|
sock = mqttd_sockdaemon(sock, &server_port, FALSE);
|
||||||
if(CURL_SOCKET_BAD == sock) {
|
if(CURL_SOCKET_BAD == sock) {
|
||||||
goto mqttd_cleanup;
|
goto mqttd_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -1044,20 +1014,20 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
logmsg("Running %s version", ipv_inuse);
|
logmsg("Running %s version", ipv_inuse);
|
||||||
logmsg("Listening on port %hu", port);
|
logmsg("Listening on port %hu", server_port);
|
||||||
|
|
||||||
wrotepidfile = write_pidfile(pidname);
|
wrotepidfile = write_pidfile(pidname);
|
||||||
if(!wrotepidfile) {
|
if(!wrotepidfile) {
|
||||||
goto mqttd_cleanup;
|
goto mqttd_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
wroteportfile = write_portfile(portname, port);
|
wroteportfile = write_portfile(portname, server_port);
|
||||||
if(!wroteportfile) {
|
if(!wroteportfile) {
|
||||||
goto mqttd_cleanup;
|
goto mqttd_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
juggle_again = incoming(sock);
|
juggle_again = mqttd_incoming(sock);
|
||||||
} while(juggle_again);
|
} while(juggle_again);
|
||||||
|
|
||||||
mqttd_cleanup:
|
mqttd_cleanup:
|
||||||
|
|
|
@ -50,9 +50,6 @@
|
||||||
/* include memdebug.h last */
|
/* include memdebug.h last */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
static bool use_ipv6 = FALSE;
|
|
||||||
static const char *ipv_inuse = "IPv4";
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
|
@ -71,14 +68,21 @@ int main(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(!strcmp("--ipv6", argv[arg])) {
|
else if(!strcmp("--ipv6", argv[arg])) {
|
||||||
|
#if defined(CURLRES_IPV6)
|
||||||
ipv_inuse = "IPv6";
|
ipv_inuse = "IPv6";
|
||||||
use_ipv6 = TRUE;
|
use_ipv6 = TRUE;
|
||||||
arg++;
|
arg++;
|
||||||
|
#else
|
||||||
|
puts("IPv6 support has been disabled in this program");
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if(!strcmp("--ipv4", argv[arg])) {
|
else if(!strcmp("--ipv4", argv[arg])) {
|
||||||
/* for completeness, we support this option as well */
|
/* for completeness, we support this option as well */
|
||||||
ipv_inuse = "IPv4";
|
ipv_inuse = "IPv4";
|
||||||
|
#if defined(CURLRES_IPV6)
|
||||||
use_ipv6 = FALSE;
|
use_ipv6 = FALSE;
|
||||||
|
#endif
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -127,13 +131,8 @@ int main(int argc, char *argv[])
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(use_ipv6) {
|
{
|
||||||
puts("IPv6 support has been disabled in this program");
|
struct hostent *he; /* gethostbyname() resolve */
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* gethostbyname() resolve */
|
|
||||||
struct hostent *he;
|
|
||||||
|
|
||||||
#ifdef __AMIGA__
|
#ifdef __AMIGA__
|
||||||
he = gethostbyname((unsigned char *)host);
|
he = gethostbyname((unsigned char *)host);
|
||||||
|
|
|
@ -56,19 +56,15 @@
|
||||||
/* include memdebug.h last */
|
/* include memdebug.h last */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
#undef REQBUFSIZ
|
||||||
static bool use_ipv6 = FALSE;
|
|
||||||
#endif
|
|
||||||
static const char *ipv_inuse = "IPv4";
|
|
||||||
static int serverlogslocked = 0;
|
|
||||||
|
|
||||||
#define REQBUFSIZ 150000
|
#define REQBUFSIZ 150000
|
||||||
|
|
||||||
static long prevtestno = -1; /* previous test number we served */
|
static long rtspd_prevtestno = -1; /* previous test number we served */
|
||||||
static long prevpartno = -1; /* previous part number we served */
|
static long rtspd_prevpartno = -1; /* previous part number we served */
|
||||||
static bool prevbounce = FALSE; /* instructs the server to override the
|
static bool rtspd_prevbounce = FALSE; /* instructs the server to override the
|
||||||
requested part number to prevpartno + 1 when
|
requested part number to
|
||||||
prevtestno and current test are the same */
|
prevpartno + 1 when prevtestno and
|
||||||
|
current test are the same */
|
||||||
|
|
||||||
#define RCMD_NORMALREQ 0 /* default request, use the tests file normally */
|
#define RCMD_NORMALREQ 0 /* default request, use the tests file normally */
|
||||||
#define RCMD_IDLE 1 /* told to sit idle */
|
#define RCMD_IDLE 1 /* told to sit idle */
|
||||||
|
@ -85,7 +81,7 @@ typedef enum {
|
||||||
#define SET_RTP_PKT_LEN(p,l) (((p)[2] = (char)(((l) >> 8) & 0xFF)), \
|
#define SET_RTP_PKT_LEN(p,l) (((p)[2] = (char)(((l) >> 8) & 0xFF)), \
|
||||||
((p)[3] = (char)((l) & 0xFF)))
|
((p)[3] = (char)((l) & 0xFF)))
|
||||||
|
|
||||||
struct httprequest {
|
struct rtspd_httprequest {
|
||||||
char reqbuf[REQBUFSIZ]; /* buffer area for the incoming request */
|
char reqbuf[REQBUFSIZ]; /* buffer area for the incoming request */
|
||||||
size_t checkindex; /* where to start checking of the request */
|
size_t checkindex; /* where to start checking of the request */
|
||||||
size_t offset; /* size of the incoming request */
|
size_t offset; /* size of the incoming request */
|
||||||
|
@ -112,14 +108,6 @@ struct httprequest {
|
||||||
size_t rtp_buffersize;
|
size_t rtp_buffersize;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ProcessRequest(struct httprequest *req);
|
|
||||||
static void storerequest(char *reqbuf, size_t totalsize);
|
|
||||||
|
|
||||||
#define DEFAULT_PORT 8999
|
|
||||||
|
|
||||||
static const char *logdir = "log";
|
|
||||||
static char loglockfile[256];
|
|
||||||
|
|
||||||
#define RTSPDVERSION "curl test suite RTSP server/0.1"
|
#define RTSPDVERSION "curl test suite RTSP server/0.1"
|
||||||
|
|
||||||
#define REQUEST_DUMP "server.input"
|
#define REQUEST_DUMP "server.input"
|
||||||
|
@ -145,7 +133,7 @@ static char loglockfile[256];
|
||||||
|
|
||||||
|
|
||||||
/* sent as reply to a QUIT */
|
/* sent as reply to a QUIT */
|
||||||
static const char *docquit =
|
static const char *docquit_rtsp =
|
||||||
"HTTP/1.1 200 Goodbye" END_OF_HEADERS;
|
"HTTP/1.1 200 Goodbye" END_OF_HEADERS;
|
||||||
|
|
||||||
/* sent as reply to a CONNECT */
|
/* sent as reply to a CONNECT */
|
||||||
|
@ -179,7 +167,7 @@ static const char *doc404_RTSP = "RTSP/1.0 404 Not Found\r\n"
|
||||||
#define RTP_DATA_SIZE 12
|
#define RTP_DATA_SIZE 12
|
||||||
static const char *RTP_DATA = "$_1234\n\0Rsdf";
|
static const char *RTP_DATA = "$_1234\n\0Rsdf";
|
||||||
|
|
||||||
static int ProcessRequest(struct httprequest *req)
|
static int rtspd_ProcessRequest(struct rtspd_httprequest *req)
|
||||||
{
|
{
|
||||||
char *line = &req->reqbuf[req->checkindex];
|
char *line = &req->reqbuf[req->checkindex];
|
||||||
bool chunked = FALSE;
|
bool chunked = FALSE;
|
||||||
|
@ -189,7 +177,7 @@ static int ProcessRequest(struct httprequest *req)
|
||||||
int prot_major, prot_minor;
|
int prot_major, prot_minor;
|
||||||
char *end = strstr(line, END_OF_HEADERS);
|
char *end = strstr(line, END_OF_HEADERS);
|
||||||
|
|
||||||
logmsg("ProcessRequest() called with testno %ld and line [%s]",
|
logmsg("rtspd_ProcessRequest() called with testno %ld and line [%s]",
|
||||||
req->testno, line);
|
req->testno, line);
|
||||||
|
|
||||||
/* try to figure out the request characteristics as soon as possible, but
|
/* try to figure out the request characteristics as soon as possible, but
|
||||||
|
@ -418,10 +406,10 @@ static int ProcessRequest(struct httprequest *req)
|
||||||
|
|
||||||
if(!end) {
|
if(!end) {
|
||||||
/* we don't have a complete request yet! */
|
/* we don't have a complete request yet! */
|
||||||
logmsg("ProcessRequest returned without a complete request");
|
logmsg("rtspd_ProcessRequest returned without a complete request");
|
||||||
return 0; /* not complete yet */
|
return 0; /* not complete yet */
|
||||||
}
|
}
|
||||||
logmsg("ProcessRequest found a complete request");
|
logmsg("rtspd_ProcessRequest found a complete request");
|
||||||
|
|
||||||
if(req->pipe)
|
if(req->pipe)
|
||||||
/* we do have a full set, advance the checkindex to after the end of the
|
/* we do have a full set, advance the checkindex to after the end of the
|
||||||
|
@ -573,7 +561,7 @@ static int ProcessRequest(struct httprequest *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store the entire request in a file */
|
/* store the entire request in a file */
|
||||||
static void storerequest(char *reqbuf, size_t totalsize)
|
static void rtspd_storerequest(char *reqbuf, size_t totalsize)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
@ -627,7 +615,7 @@ storerequest_cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 0 on success, non-zero on failure */
|
/* return 0 on success, non-zero on failure */
|
||||||
static int get_request(curl_socket_t sock, struct httprequest *req)
|
static int rtspd_get_request(curl_socket_t sock, struct rtspd_httprequest *req)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
|
@ -695,7 +683,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
if(fail) {
|
if(fail) {
|
||||||
/* dump the request received so far to the external file */
|
/* dump the request received so far to the external file */
|
||||||
reqbuf[req->offset] = '\0';
|
reqbuf[req->offset] = '\0';
|
||||||
storerequest(reqbuf, req->offset);
|
rtspd_storerequest(reqbuf, req->offset);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,7 +692,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
req->offset += (size_t)got;
|
req->offset += (size_t)got;
|
||||||
reqbuf[req->offset] = '\0';
|
reqbuf[req->offset] = '\0';
|
||||||
|
|
||||||
done_processing = ProcessRequest(req);
|
done_processing = rtspd_ProcessRequest(req);
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
return 1;
|
return 1;
|
||||||
if(done_processing && req->pipe) {
|
if(done_processing && req->pipe) {
|
||||||
|
@ -730,7 +718,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
reqbuf[req->offset] = '\0';
|
reqbuf[req->offset] = '\0';
|
||||||
|
|
||||||
/* dump the request to an external file */
|
/* dump the request to an external file */
|
||||||
storerequest(reqbuf, req->pipelining ? req->checkindex : req->offset);
|
rtspd_storerequest(reqbuf, req->pipelining ? req->checkindex : req->offset);
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -738,7 +726,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns -1 on failure */
|
/* returns -1 on failure */
|
||||||
static int send_doc(curl_socket_t sock, struct httprequest *req)
|
static int rtspd_send_doc(curl_socket_t sock, struct rtspd_httprequest *req)
|
||||||
{
|
{
|
||||||
ssize_t written;
|
ssize_t written;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
@ -791,7 +779,7 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
|
||||||
switch(req->testno) {
|
switch(req->testno) {
|
||||||
case DOCNUMBER_QUIT:
|
case DOCNUMBER_QUIT:
|
||||||
logmsg("Replying to QUIT");
|
logmsg("Replying to QUIT");
|
||||||
buffer = docquit;
|
buffer = docquit_rtsp;
|
||||||
break;
|
break;
|
||||||
case DOCNUMBER_WERULEZ:
|
case DOCNUMBER_WERULEZ:
|
||||||
/* we got a "friends?" question, reply back that we sure are */
|
/* we got a "friends?" question, reply back that we sure are */
|
||||||
|
@ -890,11 +878,11 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
|
||||||
logmsg("connection close instruction \"swsclose\" found in response");
|
logmsg("connection close instruction \"swsclose\" found in response");
|
||||||
}
|
}
|
||||||
if(strstr(buffer, "swsbounce")) {
|
if(strstr(buffer, "swsbounce")) {
|
||||||
prevbounce = TRUE;
|
rtspd_prevbounce = TRUE;
|
||||||
logmsg("enable \"swsbounce\" in the next request");
|
logmsg("enable \"swsbounce\" in the next request");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
prevbounce = FALSE;
|
rtspd_prevbounce = FALSE;
|
||||||
|
|
||||||
dump = fopen(responsedump, "ab");
|
dump = fopen(responsedump, "ab");
|
||||||
if(!dump) {
|
if(!dump) {
|
||||||
|
@ -1016,8 +1004,8 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
|
||||||
free(cmd);
|
free(cmd);
|
||||||
req->open = persistent;
|
req->open = persistent;
|
||||||
|
|
||||||
prevtestno = req->testno;
|
rtspd_prevtestno = req->testno;
|
||||||
prevpartno = req->partno;
|
rtspd_prevpartno = req->partno;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1031,17 +1019,17 @@ int main(int argc, char *argv[])
|
||||||
int wrotepidfile = 0;
|
int wrotepidfile = 0;
|
||||||
int wroteportfile = 0;
|
int wroteportfile = 0;
|
||||||
int flag;
|
int flag;
|
||||||
unsigned short port = DEFAULT_PORT;
|
unsigned short port = 8999;
|
||||||
const char *pidname = ".rtsp.pid";
|
struct rtspd_httprequest req;
|
||||||
const char *portname = NULL; /* none by default */
|
|
||||||
struct httprequest req;
|
|
||||||
int rc;
|
int rc;
|
||||||
int error;
|
int error;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
|
|
||||||
|
pidname = ".rtsp.pid";
|
||||||
serverlogfile = "log/rtspd.log";
|
serverlogfile = "log/rtspd.log";
|
||||||
|
serverlogslocked = 0;
|
||||||
|
|
||||||
while(argc > arg) {
|
while(argc > arg) {
|
||||||
if(!strcmp("--version", argv[arg])) {
|
if(!strcmp("--version", argv[arg])) {
|
||||||
|
@ -1284,9 +1272,9 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* initialization of httprequest struct is done in get_request(), but due
|
/* initialization of httprequest struct is done in rtspd_get_request(),
|
||||||
to pipelining treatment the pipelining struct field must be initialized
|
but due to pipelining treatment the pipelining struct field must be
|
||||||
previously to FALSE every time a new connection arrives. */
|
initialized previously to FALSE every time a new connection arrives. */
|
||||||
|
|
||||||
req.pipelining = FALSE;
|
req.pipelining = FALSE;
|
||||||
|
|
||||||
|
@ -1294,24 +1282,24 @@ int main(int argc, char *argv[])
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(get_request(msgsock, &req))
|
if(rtspd_get_request(msgsock, &req))
|
||||||
/* non-zero means error, break out of loop */
|
/* non-zero means error, break out of loop */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(prevbounce) {
|
if(rtspd_prevbounce) {
|
||||||
/* bounce treatment requested */
|
/* bounce treatment requested */
|
||||||
if(req.testno == prevtestno) {
|
if(req.testno == rtspd_prevtestno) {
|
||||||
req.partno = prevpartno + 1;
|
req.partno = rtspd_prevpartno + 1;
|
||||||
logmsg("BOUNCE part number to %ld", req.partno);
|
logmsg("BOUNCE part number to %ld", req.partno);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prevbounce = FALSE;
|
rtspd_prevbounce = FALSE;
|
||||||
prevtestno = -1;
|
rtspd_prevtestno = -1;
|
||||||
prevpartno = -1;
|
rtspd_prevpartno = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_doc(msgsock, &req);
|
rtspd_send_doc(msgsock, &req);
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -114,20 +114,14 @@
|
||||||
/* include memdebug.h last */
|
/* include memdebug.h last */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define DEFAULT_PORT 8999
|
|
||||||
|
|
||||||
/* buffer is this excessively large only to be able to support things like
|
/* buffer is this excessively large only to be able to support things like
|
||||||
test 1003 which tests exceedingly large server response lines */
|
test 1003 which tests exceedingly large server response lines */
|
||||||
#define BUFFER_SIZE 17010
|
#define BUFFER_SIZE 17010
|
||||||
|
|
||||||
static bool verbose = FALSE;
|
static bool verbose = FALSE;
|
||||||
static bool bind_only = FALSE;
|
static bool s_bind_only = FALSE;
|
||||||
#ifdef USE_IPV6
|
static unsigned short server_connectport = 0; /* if non-zero,
|
||||||
static bool use_ipv6 = FALSE;
|
we activate this mode */
|
||||||
#endif
|
|
||||||
static const char *ipv_inuse = "IPv4";
|
|
||||||
static unsigned short port = DEFAULT_PORT;
|
|
||||||
static unsigned short connectport = 0; /* if non-zero, we activate this mode */
|
|
||||||
|
|
||||||
enum sockmode {
|
enum sockmode {
|
||||||
PASSIVE_LISTEN, /* as a server waiting for connections */
|
PASSIVE_LISTEN, /* as a server waiting for connections */
|
||||||
|
@ -1126,7 +1120,8 @@ static bool juggle(curl_socket_t *sockfdp,
|
||||||
else if(!memcmp("PORT", buffer, 4)) {
|
else if(!memcmp("PORT", buffer, 4)) {
|
||||||
/* Question asking us what PORT number we are listening to.
|
/* Question asking us what PORT number we are listening to.
|
||||||
Replies to PORT with "IPv[num]/[port]" */
|
Replies to PORT with "IPv[num]/[port]" */
|
||||||
msnprintf((char *)buffer, sizeof(buffer), "%s/%hu\n", ipv_inuse, port);
|
msnprintf((char *)buffer, sizeof(buffer), "%s/%hu\n",
|
||||||
|
ipv_inuse, server_port);
|
||||||
buffer_len = (ssize_t)strlen((char *)buffer);
|
buffer_len = (ssize_t)strlen((char *)buffer);
|
||||||
msnprintf(data, sizeof(data), "PORT\n%04zx\n", buffer_len);
|
msnprintf(data, sizeof(data), "PORT\n%04zx\n", buffer_len);
|
||||||
if(!write_stdout(data, 10))
|
if(!write_stdout(data, 10))
|
||||||
|
@ -1231,8 +1226,9 @@ static bool juggle(curl_socket_t *sockfdp,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static curl_socket_t sockdaemon(curl_socket_t sock,
|
static curl_socket_t sockfilt_sockdaemon(curl_socket_t sock,
|
||||||
unsigned short *listenport)
|
unsigned short *listenport,
|
||||||
|
bool bind_only)
|
||||||
{
|
{
|
||||||
/* passive daemon style */
|
/* passive daemon style */
|
||||||
srvr_sockaddr_union_t listener;
|
srvr_sockaddr_union_t listener;
|
||||||
|
@ -1380,8 +1376,6 @@ int main(int argc, char *argv[])
|
||||||
curl_socket_t msgsock = CURL_SOCKET_BAD;
|
curl_socket_t msgsock = CURL_SOCKET_BAD;
|
||||||
int wrotepidfile = 0;
|
int wrotepidfile = 0;
|
||||||
int wroteportfile = 0;
|
int wroteportfile = 0;
|
||||||
const char *pidname = ".sockfilt.pid";
|
|
||||||
const char *portname = NULL; /* none by default */
|
|
||||||
bool juggle_again;
|
bool juggle_again;
|
||||||
int rc;
|
int rc;
|
||||||
int error;
|
int error;
|
||||||
|
@ -1389,7 +1383,9 @@ int main(int argc, char *argv[])
|
||||||
enum sockmode mode = PASSIVE_LISTEN; /* default */
|
enum sockmode mode = PASSIVE_LISTEN; /* default */
|
||||||
const char *addr = NULL;
|
const char *addr = NULL;
|
||||||
|
|
||||||
|
pidname = ".sockfilt.pid";
|
||||||
serverlogfile = "log/sockfilt.log";
|
serverlogfile = "log/sockfilt.log";
|
||||||
|
server_port = 8999;
|
||||||
|
|
||||||
while(argc > arg) {
|
while(argc > arg) {
|
||||||
if(!strcmp("--version", argv[arg])) {
|
if(!strcmp("--version", argv[arg])) {
|
||||||
|
@ -1437,7 +1433,7 @@ int main(int argc, char *argv[])
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
else if(!strcmp("--bindonly", argv[arg])) {
|
else if(!strcmp("--bindonly", argv[arg])) {
|
||||||
bind_only = TRUE;
|
s_bind_only = TRUE;
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
else if(!strcmp("--port", argv[arg])) {
|
else if(!strcmp("--port", argv[arg])) {
|
||||||
|
@ -1445,7 +1441,7 @@ int main(int argc, char *argv[])
|
||||||
if(argc > arg) {
|
if(argc > arg) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
|
unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
|
||||||
port = util_ultous(ulnum);
|
server_port = util_ultous(ulnum);
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1462,7 +1458,7 @@ int main(int argc, char *argv[])
|
||||||
argv[arg]);
|
argv[arg]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
connectport = util_ultous(ulnum);
|
server_connectport = util_ultous(ulnum);
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1518,7 +1514,7 @@ int main(int argc, char *argv[])
|
||||||
goto sockfilt_cleanup;
|
goto sockfilt_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(connectport) {
|
if(server_connectport) {
|
||||||
/* Active mode, we should connect to the given port number */
|
/* Active mode, we should connect to the given port number */
|
||||||
mode = ACTIVE;
|
mode = ACTIVE;
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
|
@ -1526,7 +1522,7 @@ int main(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
memset(&me.sa4, 0, sizeof(me.sa4));
|
memset(&me.sa4, 0, sizeof(me.sa4));
|
||||||
me.sa4.sin_family = AF_INET;
|
me.sa4.sin_family = AF_INET;
|
||||||
me.sa4.sin_port = htons(connectport);
|
me.sa4.sin_port = htons(server_connectport);
|
||||||
me.sa4.sin_addr.s_addr = INADDR_ANY;
|
me.sa4.sin_addr.s_addr = INADDR_ANY;
|
||||||
if(!addr)
|
if(!addr)
|
||||||
addr = "127.0.0.1";
|
addr = "127.0.0.1";
|
||||||
|
@ -1538,7 +1534,7 @@ int main(int argc, char *argv[])
|
||||||
else {
|
else {
|
||||||
memset(&me.sa6, 0, sizeof(me.sa6));
|
memset(&me.sa6, 0, sizeof(me.sa6));
|
||||||
me.sa6.sin6_family = AF_INET6;
|
me.sa6.sin6_family = AF_INET6;
|
||||||
me.sa6.sin6_port = htons(connectport);
|
me.sa6.sin6_port = htons(server_connectport);
|
||||||
if(!addr)
|
if(!addr)
|
||||||
addr = "::1";
|
addr = "::1";
|
||||||
Curl_inet_pton(AF_INET6, addr, &me.sa6.sin6_addr);
|
Curl_inet_pton(AF_INET6, addr, &me.sa6.sin6_addr);
|
||||||
|
@ -1549,7 +1545,7 @@ int main(int argc, char *argv[])
|
||||||
if(rc) {
|
if(rc) {
|
||||||
error = SOCKERRNO;
|
error = SOCKERRNO;
|
||||||
logmsg("Error connecting to port %hu (%d) %s",
|
logmsg("Error connecting to port %hu (%d) %s",
|
||||||
connectport, error, sstrerror(error));
|
server_connectport, error, sstrerror(error));
|
||||||
write_stdout("FAIL\n", 5);
|
write_stdout("FAIL\n", 5);
|
||||||
goto sockfilt_cleanup;
|
goto sockfilt_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -1558,7 +1554,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* passive daemon style */
|
/* passive daemon style */
|
||||||
sock = sockdaemon(sock, &port);
|
sock = sockfilt_sockdaemon(sock, &server_port, s_bind_only);
|
||||||
if(CURL_SOCKET_BAD == sock) {
|
if(CURL_SOCKET_BAD == sock) {
|
||||||
write_stdout("FAIL\n", 5);
|
write_stdout("FAIL\n", 5);
|
||||||
goto sockfilt_cleanup;
|
goto sockfilt_cleanup;
|
||||||
|
@ -1568,12 +1564,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
logmsg("Running %s version", ipv_inuse);
|
logmsg("Running %s version", ipv_inuse);
|
||||||
|
|
||||||
if(connectport)
|
if(server_connectport)
|
||||||
logmsg("Connected to port %hu", connectport);
|
logmsg("Connected to port %hu", server_connectport);
|
||||||
else if(bind_only)
|
else if(s_bind_only)
|
||||||
logmsg("Bound without listening on port %hu", port);
|
logmsg("Bound without listening on port %hu", server_port);
|
||||||
else
|
else
|
||||||
logmsg("Listening on port %hu", port);
|
logmsg("Listening on port %hu", server_port);
|
||||||
|
|
||||||
wrotepidfile = write_pidfile(pidname);
|
wrotepidfile = write_pidfile(pidname);
|
||||||
if(!wrotepidfile) {
|
if(!wrotepidfile) {
|
||||||
|
@ -1581,7 +1577,7 @@ int main(int argc, char *argv[])
|
||||||
goto sockfilt_cleanup;
|
goto sockfilt_cleanup;
|
||||||
}
|
}
|
||||||
if(portname) {
|
if(portname) {
|
||||||
wroteportfile = write_portfile(portname, port);
|
wroteportfile = write_portfile(portname, server_port);
|
||||||
if(!wroteportfile) {
|
if(!wroteportfile) {
|
||||||
write_stdout("FAIL\n", 5);
|
write_stdout("FAIL\n", 5);
|
||||||
goto sockfilt_cleanup;
|
goto sockfilt_cleanup;
|
||||||
|
|
|
@ -85,20 +85,10 @@
|
||||||
/* include memdebug.h last */
|
/* include memdebug.h last */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define DEFAULT_PORT 8905
|
|
||||||
|
|
||||||
#ifndef DEFAULT_REQFILE
|
|
||||||
#define DEFAULT_REQFILE "log/socksd-request.log"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DEFAULT_CONFIG
|
|
||||||
#define DEFAULT_CONFIG "socksd.config"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *backendaddr = "127.0.0.1";
|
static const char *backendaddr = "127.0.0.1";
|
||||||
static unsigned short backendport = 0; /* default is use client's */
|
static unsigned short backendport = 0; /* default is use client's */
|
||||||
|
|
||||||
struct configurable {
|
struct socksd_configurable {
|
||||||
unsigned char version; /* initial version byte in the request must match
|
unsigned char version; /* initial version byte in the request must match
|
||||||
this */
|
this */
|
||||||
unsigned char nmethods_min; /* minimum number of nmethods to expect */
|
unsigned char nmethods_min; /* minimum number of nmethods to expect */
|
||||||
|
@ -123,34 +113,24 @@ struct configurable {
|
||||||
#define CONFIG_ADDR backendaddr
|
#define CONFIG_ADDR backendaddr
|
||||||
#define CONFIG_CONNECTREP 0
|
#define CONFIG_CONNECTREP 0
|
||||||
|
|
||||||
static struct configurable config;
|
static struct socksd_configurable s_config;
|
||||||
|
|
||||||
static const char *reqlogfile = DEFAULT_REQFILE;
|
static const char *reqlogfile = "log/socksd-request.log";
|
||||||
static const char *configfile = DEFAULT_CONFIG;
|
|
||||||
|
|
||||||
static const char *socket_type = "IPv4";
|
static void socksd_resetdefaults(void)
|
||||||
static unsigned short port = DEFAULT_PORT;
|
|
||||||
|
|
||||||
static void resetdefaults(void)
|
|
||||||
{
|
{
|
||||||
logmsg("Reset to defaults");
|
logmsg("Reset to defaults");
|
||||||
config.version = CONFIG_VERSION;
|
s_config.version = CONFIG_VERSION;
|
||||||
config.nmethods_min = CONFIG_NMETHODS_MIN;
|
s_config.nmethods_min = CONFIG_NMETHODS_MIN;
|
||||||
config.nmethods_max = CONFIG_NMETHODS_MAX;
|
s_config.nmethods_max = CONFIG_NMETHODS_MAX;
|
||||||
config.responseversion = CONFIG_RESPONSEVERSION;
|
s_config.responseversion = CONFIG_RESPONSEVERSION;
|
||||||
config.responsemethod = CONFIG_RESPONSEMETHOD;
|
s_config.responsemethod = CONFIG_RESPONSEMETHOD;
|
||||||
config.reqcmd = CONFIG_REQCMD;
|
s_config.reqcmd = CONFIG_REQCMD;
|
||||||
config.connectrep = CONFIG_CONNECTREP;
|
s_config.connectrep = CONFIG_CONNECTREP;
|
||||||
config.port = CONFIG_PORT;
|
s_config.port = CONFIG_PORT;
|
||||||
strcpy(config.addr, CONFIG_ADDR);
|
strcpy(s_config.addr, CONFIG_ADDR);
|
||||||
strcpy(config.user, "user");
|
strcpy(s_config.user, "user");
|
||||||
strcpy(config.password, "password");
|
strcpy(s_config.password, "password");
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char byteval(char *value)
|
|
||||||
{
|
|
||||||
unsigned long num = strtoul(value, NULL, 10);
|
|
||||||
return num & 0xff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short shortval(char *value)
|
static unsigned short shortval(char *value)
|
||||||
|
@ -159,12 +139,10 @@ static unsigned short shortval(char *value)
|
||||||
return num & 0xffff;
|
return num & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socket_domain = AF_INET;
|
static void socksd_getconfig(void)
|
||||||
|
|
||||||
static void getconfig(void)
|
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(configfile, FOPEN_READTEXT);
|
FILE *fp = fopen(configfile, FOPEN_READTEXT);
|
||||||
resetdefaults();
|
socksd_resetdefaults();
|
||||||
if(fp) {
|
if(fp) {
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
logmsg("parse config file");
|
logmsg("parse config file");
|
||||||
|
@ -173,32 +151,32 @@ static void getconfig(void)
|
||||||
char value[260];
|
char value[260];
|
||||||
if(2 == sscanf(buffer, "%31s %259s", key, value)) {
|
if(2 == sscanf(buffer, "%31s %259s", key, value)) {
|
||||||
if(!strcmp(key, "version")) {
|
if(!strcmp(key, "version")) {
|
||||||
config.version = byteval(value);
|
s_config.version = byteval(value);
|
||||||
logmsg("version [%d] set", config.version);
|
logmsg("version [%d] set", s_config.version);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "nmethods_min")) {
|
else if(!strcmp(key, "nmethods_min")) {
|
||||||
config.nmethods_min = byteval(value);
|
s_config.nmethods_min = byteval(value);
|
||||||
logmsg("nmethods_min [%d] set", config.nmethods_min);
|
logmsg("nmethods_min [%d] set", s_config.nmethods_min);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "nmethods_max")) {
|
else if(!strcmp(key, "nmethods_max")) {
|
||||||
config.nmethods_max = byteval(value);
|
s_config.nmethods_max = byteval(value);
|
||||||
logmsg("nmethods_max [%d] set", config.nmethods_max);
|
logmsg("nmethods_max [%d] set", s_config.nmethods_max);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "backend")) {
|
else if(!strcmp(key, "backend")) {
|
||||||
strcpy(config.addr, value);
|
strcpy(s_config.addr, value);
|
||||||
logmsg("backend [%s] set", config.addr);
|
logmsg("backend [%s] set", s_config.addr);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "backendport")) {
|
else if(!strcmp(key, "backendport")) {
|
||||||
config.port = shortval(value);
|
s_config.port = shortval(value);
|
||||||
logmsg("backendport [%d] set", config.port);
|
logmsg("backendport [%d] set", s_config.port);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "user")) {
|
else if(!strcmp(key, "user")) {
|
||||||
strcpy(config.user, value);
|
strcpy(s_config.user, value);
|
||||||
logmsg("user [%s] set", config.user);
|
logmsg("user [%s] set", s_config.user);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "password")) {
|
else if(!strcmp(key, "password")) {
|
||||||
strcpy(config.password, value);
|
strcpy(s_config.password, value);
|
||||||
logmsg("password [%s] set", config.password);
|
logmsg("password [%s] set", s_config.password);
|
||||||
}
|
}
|
||||||
/* Methods:
|
/* Methods:
|
||||||
o X'00' NO AUTHENTICATION REQUIRED
|
o X'00' NO AUTHENTICATION REQUIRED
|
||||||
|
@ -206,12 +184,12 @@ static void getconfig(void)
|
||||||
o X'02' USERNAME/PASSWORD
|
o X'02' USERNAME/PASSWORD
|
||||||
*/
|
*/
|
||||||
else if(!strcmp(key, "method")) {
|
else if(!strcmp(key, "method")) {
|
||||||
config.responsemethod = byteval(value);
|
s_config.responsemethod = byteval(value);
|
||||||
logmsg("method [%d] set", config.responsemethod);
|
logmsg("method [%d] set", s_config.responsemethod);
|
||||||
}
|
}
|
||||||
else if(!strcmp(key, "response")) {
|
else if(!strcmp(key, "response")) {
|
||||||
config.connectrep = byteval(value);
|
s_config.connectrep = byteval(value);
|
||||||
logmsg("response [%d] set", config.connectrep);
|
logmsg("response [%d] set", s_config.connectrep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,25 +197,6 @@ static void getconfig(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loghex(unsigned char *buffer, ssize_t len)
|
|
||||||
{
|
|
||||||
char data[1200];
|
|
||||||
ssize_t i;
|
|
||||||
unsigned char *ptr = buffer;
|
|
||||||
char *optr = data;
|
|
||||||
ssize_t width = 0;
|
|
||||||
int left = sizeof(data);
|
|
||||||
|
|
||||||
for(i = 0; i < len && (left >= 0); i++) {
|
|
||||||
msnprintf(optr, left, "%02x", ptr[i]);
|
|
||||||
width += 2;
|
|
||||||
optr += 2;
|
|
||||||
left -= 2;
|
|
||||||
}
|
|
||||||
if(width)
|
|
||||||
logmsg("'%s'", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RFC 1928, SOCKS5 byte index */
|
/* RFC 1928, SOCKS5 byte index */
|
||||||
#define SOCKS5_VERSION 0
|
#define SOCKS5_VERSION 0
|
||||||
#define SOCKS5_NMETHODS 1 /* number of methods that is listed */
|
#define SOCKS5_NMETHODS 1 /* number of methods that is listed */
|
||||||
|
@ -303,13 +262,13 @@ static curl_socket_t socks4(curl_socket_t fd,
|
||||||
logmsg("SOCKS4 connect message too short: %zd", rc);
|
logmsg("SOCKS4 connect message too short: %zd", rc);
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
if(!config.port)
|
if(!s_config.port)
|
||||||
s4port = (unsigned short)((buffer[SOCKS4_DSTPORT] << 8) |
|
s4port = (unsigned short)((buffer[SOCKS4_DSTPORT] << 8) |
|
||||||
(buffer[SOCKS4_DSTPORT + 1]));
|
(buffer[SOCKS4_DSTPORT + 1]));
|
||||||
else
|
else
|
||||||
s4port = config.port;
|
s4port = s_config.port;
|
||||||
|
|
||||||
connfd = socksconnect(s4port, config.addr);
|
connfd = socksconnect(s4port, s_config.addr);
|
||||||
if(connfd == CURL_SOCKET_BAD) {
|
if(connfd == CURL_SOCKET_BAD) {
|
||||||
/* failed */
|
/* failed */
|
||||||
cd = 91;
|
cd = 91;
|
||||||
|
@ -353,7 +312,7 @@ static curl_socket_t sockit(curl_socket_t fd)
|
||||||
curl_socket_t connfd = CURL_SOCKET_BAD;
|
curl_socket_t connfd = CURL_SOCKET_BAD;
|
||||||
unsigned short s5port;
|
unsigned short s5port;
|
||||||
|
|
||||||
getconfig();
|
socksd_getconfig();
|
||||||
|
|
||||||
rc = recv(fd, (char *)buffer, sizeof(buffer), 0);
|
rc = recv(fd, (char *)buffer, sizeof(buffer), 0);
|
||||||
if(rc <= 0) {
|
if(rc <= 0) {
|
||||||
|
@ -372,14 +331,14 @@ static curl_socket_t sockit(curl_socket_t fd)
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buffer[SOCKS5_VERSION] != config.version) {
|
if(buffer[SOCKS5_VERSION] != s_config.version) {
|
||||||
logmsg("VERSION byte not %d", config.version);
|
logmsg("VERSION byte not %d", s_config.version);
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
if((buffer[SOCKS5_NMETHODS] < config.nmethods_min) ||
|
if((buffer[SOCKS5_NMETHODS] < s_config.nmethods_min) ||
|
||||||
(buffer[SOCKS5_NMETHODS] > config.nmethods_max)) {
|
(buffer[SOCKS5_NMETHODS] > s_config.nmethods_max)) {
|
||||||
logmsg("NMETHODS byte not within %d - %d ",
|
logmsg("NMETHODS byte not within %d - %d ",
|
||||||
config.nmethods_min, config.nmethods_max);
|
s_config.nmethods_min, s_config.nmethods_max);
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
/* after NMETHODS follows that many bytes listing the methods the client
|
/* after NMETHODS follows that many bytes listing the methods the client
|
||||||
|
@ -391,8 +350,8 @@ static curl_socket_t sockit(curl_socket_t fd)
|
||||||
logmsg("Incoming request deemed fine!");
|
logmsg("Incoming request deemed fine!");
|
||||||
|
|
||||||
/* respond with two bytes: VERSION + METHOD */
|
/* respond with two bytes: VERSION + METHOD */
|
||||||
response[0] = config.responseversion;
|
response[0] = s_config.responseversion;
|
||||||
response[1] = config.responsemethod;
|
response[1] = s_config.responsemethod;
|
||||||
rc = (send)(fd, (char *)response, 2, 0);
|
rc = (send)(fd, (char *)response, 2, 0);
|
||||||
if(rc != 2) {
|
if(rc != 2) {
|
||||||
logmsg("Sending response failed!");
|
logmsg("Sending response failed!");
|
||||||
|
@ -411,7 +370,7 @@ static curl_socket_t sockit(curl_socket_t fd)
|
||||||
logmsg("READ %zd bytes", rc);
|
logmsg("READ %zd bytes", rc);
|
||||||
loghex(buffer, rc);
|
loghex(buffer, rc);
|
||||||
|
|
||||||
if(config.responsemethod == 2) {
|
if(s_config.responsemethod == 2) {
|
||||||
/* RFC 1929 authentication
|
/* RFC 1929 authentication
|
||||||
+----+------+----------+------+----------+
|
+----+------+----------+------+----------+
|
||||||
|VER | ULEN | UNAME | PLEN | PASSWD |
|
|VER | ULEN | UNAME | PLEN | PASSWD |
|
||||||
|
@ -440,10 +399,10 @@ static curl_socket_t sockit(curl_socket_t fd)
|
||||||
logmsg("Too short packet for ulen %d plen %d: %zd", ulen, plen, rc);
|
logmsg("Too short packet for ulen %d plen %d: %zd", ulen, plen, rc);
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
if((ulen != strlen(config.user)) ||
|
if((ulen != strlen(s_config.user)) ||
|
||||||
(plen != strlen(config.password)) ||
|
(plen != strlen(s_config.password)) ||
|
||||||
memcmp(&buffer[SOCKS5_UNAME], config.user, ulen) ||
|
memcmp(&buffer[SOCKS5_UNAME], s_config.user, ulen) ||
|
||||||
memcmp(&buffer[SOCKS5_UNAME + ulen + 1], config.password, plen)) {
|
memcmp(&buffer[SOCKS5_UNAME + ulen + 1], s_config.password, plen)) {
|
||||||
/* no match! */
|
/* no match! */
|
||||||
logmsg("mismatched credentials!");
|
logmsg("mismatched credentials!");
|
||||||
login = FALSE;
|
login = FALSE;
|
||||||
|
@ -475,18 +434,18 @@ static curl_socket_t sockit(curl_socket_t fd)
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buffer[SOCKS5_VERSION] != config.version) {
|
if(buffer[SOCKS5_VERSION] != s_config.version) {
|
||||||
logmsg("Request VERSION byte not %d", config.version);
|
logmsg("Request VERSION byte not %d", s_config.version);
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
/* 1 == CONNECT */
|
/* 1 == CONNECT */
|
||||||
if(buffer[SOCKS5_REQCMD] != config.reqcmd) {
|
if(buffer[SOCKS5_REQCMD] != s_config.reqcmd) {
|
||||||
logmsg("Request COMMAND byte not %d", config.reqcmd);
|
logmsg("Request COMMAND byte not %d", s_config.reqcmd);
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
/* reserved, should be zero */
|
/* reserved, should be zero */
|
||||||
if(buffer[SOCKS5_RESERVED]) {
|
if(buffer[SOCKS5_RESERVED]) {
|
||||||
logmsg("Request COMMAND byte not %d", config.reqcmd);
|
logmsg("Request COMMAND byte not %d", s_config.reqcmd);
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
/* ATYP:
|
/* ATYP:
|
||||||
|
@ -550,26 +509,26 @@ static curl_socket_t sockit(curl_socket_t fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!config.port) {
|
if(!s_config.port) {
|
||||||
unsigned char *portp = &buffer[SOCKS5_DSTADDR + len];
|
unsigned char *portp = &buffer[SOCKS5_DSTADDR + len];
|
||||||
s5port = (unsigned short)((portp[0] << 8) | (portp[1]));
|
s5port = (unsigned short)((portp[0] << 8) | (portp[1]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s5port = config.port;
|
s5port = s_config.port;
|
||||||
|
|
||||||
if(!config.connectrep)
|
if(!s_config.connectrep)
|
||||||
connfd = socksconnect(s5port, config.addr);
|
connfd = socksconnect(s5port, s_config.addr);
|
||||||
|
|
||||||
if(connfd == CURL_SOCKET_BAD) {
|
if(connfd == CURL_SOCKET_BAD) {
|
||||||
/* failed */
|
/* failed */
|
||||||
rep = 1;
|
rep = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rep = config.connectrep;
|
rep = s_config.connectrep;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
response[SOCKS5_VERSION] = config.responseversion;
|
response[SOCKS5_VERSION] = s_config.responseversion;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
o REP Reply field:
|
o REP Reply field:
|
||||||
|
@ -663,7 +622,7 @@ static int tunnel(struct perclient *cp, fd_set *fds)
|
||||||
if sockfd is CURL_SOCKET_BAD, listendfd is a listening socket we must
|
if sockfd is CURL_SOCKET_BAD, listendfd is a listening socket we must
|
||||||
accept()
|
accept()
|
||||||
*/
|
*/
|
||||||
static bool incoming(curl_socket_t listenfd)
|
static bool socksd_incoming(curl_socket_t listenfd)
|
||||||
{
|
{
|
||||||
fd_set fds_read;
|
fd_set fds_read;
|
||||||
fd_set fds_write;
|
fd_set fds_write;
|
||||||
|
@ -799,12 +758,10 @@ static bool incoming(curl_socket_t listenfd)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static curl_socket_t sockdaemon(curl_socket_t sock,
|
static curl_socket_t socksd_sockdaemon(curl_socket_t sock,
|
||||||
unsigned short *listenport
|
unsigned short *listenport,
|
||||||
#ifdef USE_UNIX_SOCKETS
|
const char *unix_socket,
|
||||||
, const char *unix_socket
|
bool bind_only)
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* passive daemon style */
|
/* passive daemon style */
|
||||||
srvr_sockaddr_union_t listener;
|
srvr_sockaddr_union_t listener;
|
||||||
|
@ -816,6 +773,10 @@ static curl_socket_t sockdaemon(curl_socket_t sock,
|
||||||
int attempt = 0;
|
int attempt = 0;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
#ifndef USE_UNIX_SOCKETS
|
||||||
|
(void)unix_socket;
|
||||||
|
#endif
|
||||||
|
|
||||||
do {
|
do {
|
||||||
attempt++;
|
attempt++;
|
||||||
flag = 1;
|
flag = 1;
|
||||||
|
@ -938,6 +899,12 @@ static curl_socket_t sockdaemon(curl_socket_t sock,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* bindonly option forces no listening */
|
||||||
|
if(bind_only) {
|
||||||
|
logmsg("instructed to bind port without listening");
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
/* start accepting connections */
|
/* start accepting connections */
|
||||||
rc = listen(sock, 5);
|
rc = listen(sock, 5);
|
||||||
if(0 != rc) {
|
if(0 != rc) {
|
||||||
|
@ -958,18 +925,19 @@ int main(int argc, char *argv[])
|
||||||
curl_socket_t msgsock = CURL_SOCKET_BAD;
|
curl_socket_t msgsock = CURL_SOCKET_BAD;
|
||||||
int wrotepidfile = 0;
|
int wrotepidfile = 0;
|
||||||
int wroteportfile = 0;
|
int wroteportfile = 0;
|
||||||
const char *pidname = ".socksd.pid";
|
|
||||||
const char *portname = NULL; /* none by default */
|
|
||||||
bool juggle_again;
|
bool juggle_again;
|
||||||
int error;
|
int error;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
|
|
||||||
#ifdef USE_UNIX_SOCKETS
|
|
||||||
const char *unix_socket = NULL;
|
const char *unix_socket = NULL;
|
||||||
|
#ifdef USE_UNIX_SOCKETS
|
||||||
bool unlink_socket = false;
|
bool unlink_socket = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pidname = ".socksd.pid";
|
||||||
serverlogfile = "log/socksd.log";
|
serverlogfile = "log/socksd.log";
|
||||||
|
configfile = "socksd.config";
|
||||||
|
server_port = 8905;
|
||||||
|
|
||||||
while(argc > arg) {
|
while(argc > arg) {
|
||||||
if(!strcmp("--version", argv[arg])) {
|
if(!strcmp("--version", argv[arg])) {
|
||||||
|
@ -1054,7 +1022,7 @@ int main(int argc, char *argv[])
|
||||||
if(argc > arg) {
|
if(argc > arg) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
|
unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
|
||||||
port = util_ultous(ulnum);
|
server_port = util_ultous(ulnum);
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1099,11 +1067,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
{
|
{
|
||||||
/* passive daemon style */
|
/* passive daemon style */
|
||||||
sock = sockdaemon(sock, &port
|
sock = socksd_sockdaemon(sock, &server_port, unix_socket, FALSE);
|
||||||
#ifdef USE_UNIX_SOCKETS
|
|
||||||
, unix_socket
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
if(CURL_SOCKET_BAD == sock) {
|
if(CURL_SOCKET_BAD == sock) {
|
||||||
goto socks5_cleanup;
|
goto socks5_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -1120,7 +1084,7 @@ int main(int argc, char *argv[])
|
||||||
logmsg("Listening on Unix socket %s", unix_socket);
|
logmsg("Listening on Unix socket %s", unix_socket);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
logmsg("Listening on port %hu", port);
|
logmsg("Listening on port %hu", server_port);
|
||||||
|
|
||||||
wrotepidfile = write_pidfile(pidname);
|
wrotepidfile = write_pidfile(pidname);
|
||||||
if(!wrotepidfile) {
|
if(!wrotepidfile) {
|
||||||
|
@ -1128,14 +1092,14 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if(portname) {
|
if(portname) {
|
||||||
wroteportfile = write_portfile(portname, port);
|
wroteportfile = write_portfile(portname, server_port);
|
||||||
if(!wroteportfile) {
|
if(!wroteportfile) {
|
||||||
goto socks5_cleanup;
|
goto socks5_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
juggle_again = incoming(sock);
|
juggle_again = socksd_incoming(sock);
|
||||||
} while(juggle_again);
|
} while(juggle_again);
|
||||||
|
|
||||||
socks5_cleanup:
|
socks5_cleanup:
|
||||||
|
|
|
@ -58,26 +58,26 @@
|
||||||
/* include memdebug.h last */
|
/* include memdebug.h last */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
static int socket_domain = AF_INET;
|
|
||||||
static bool use_gopher = FALSE;
|
static bool use_gopher = FALSE;
|
||||||
static int serverlogslocked = 0;
|
|
||||||
static bool is_proxy = FALSE;
|
static bool is_proxy = FALSE;
|
||||||
|
|
||||||
|
#undef REQBUFSIZ
|
||||||
#define REQBUFSIZ (2*1024*1024)
|
#define REQBUFSIZ (2*1024*1024)
|
||||||
|
|
||||||
#define MAX_SLEEP_TIME_MS 250
|
#define MAX_SLEEP_TIME_MS 250
|
||||||
|
|
||||||
static long prevtestno = -1; /* previous test number we served */
|
static long sws_prevtestno = -1; /* previous test number we served */
|
||||||
static long prevpartno = -1; /* previous part number we served */
|
static long sws_prevpartno = -1; /* previous part number we served */
|
||||||
static bool prevbounce = FALSE; /* instructs the server to override the
|
static bool sws_prevbounce = FALSE; /* instructs the server to override the
|
||||||
requested part number to prevpartno + 1 when
|
requested part number to
|
||||||
prevtestno and current test are the same */
|
prevpartno + 1 when prevtestno and
|
||||||
|
current test are the same */
|
||||||
|
|
||||||
#define RCMD_NORMALREQ 0 /* default request, use the tests file normally */
|
#define RCMD_NORMALREQ 0 /* default request, use the tests file normally */
|
||||||
#define RCMD_IDLE 1 /* told to sit idle */
|
#define RCMD_IDLE 1 /* told to sit idle */
|
||||||
#define RCMD_STREAM 2 /* told to stream */
|
#define RCMD_STREAM 2 /* told to stream */
|
||||||
|
|
||||||
struct httprequest {
|
struct sws_httprequest {
|
||||||
char reqbuf[REQBUFSIZ]; /* buffer area for the incoming request */
|
char reqbuf[REQBUFSIZ]; /* buffer area for the incoming request */
|
||||||
bool connect_request; /* if a CONNECT */
|
bool connect_request; /* if a CONNECT */
|
||||||
unsigned short connect_port; /* the port number CONNECT used */
|
unsigned short connect_port; /* the port number CONNECT used */
|
||||||
|
@ -101,7 +101,7 @@ struct httprequest {
|
||||||
- skip bytes. */
|
- skip bytes. */
|
||||||
int rcmd; /* doing a special command, see defines above */
|
int rcmd; /* doing a special command, see defines above */
|
||||||
int prot_version; /* HTTP version * 10 */
|
int prot_version; /* HTTP version * 10 */
|
||||||
int callcount; /* times ProcessRequest() gets called */
|
int callcount; /* times sws_ProcessRequest() gets called */
|
||||||
bool skipall; /* skip all incoming data */
|
bool skipall; /* skip all incoming data */
|
||||||
bool noexpect; /* refuse Expect: (don't read the body) */
|
bool noexpect; /* refuse Expect: (don't read the body) */
|
||||||
bool connmon; /* monitor the state of the connection, log disconnects */
|
bool connmon; /* monitor the state of the connection, log disconnects */
|
||||||
|
@ -117,14 +117,6 @@ struct httprequest {
|
||||||
static curl_socket_t all_sockets[MAX_SOCKETS];
|
static curl_socket_t all_sockets[MAX_SOCKETS];
|
||||||
static size_t num_sockets = 0;
|
static size_t num_sockets = 0;
|
||||||
|
|
||||||
static int ProcessRequest(struct httprequest *req);
|
|
||||||
static void storerequest(const char *reqbuf, size_t totalsize);
|
|
||||||
|
|
||||||
#define DEFAULT_PORT 8999
|
|
||||||
|
|
||||||
static const char *logdir = "log";
|
|
||||||
static char loglockfile[256];
|
|
||||||
|
|
||||||
#define SWSVERSION "curl test suite HTTP server/0.1"
|
#define SWSVERSION "curl test suite HTTP server/0.1"
|
||||||
|
|
||||||
#define REQUEST_DUMP "server.input"
|
#define REQUEST_DUMP "server.input"
|
||||||
|
@ -136,8 +128,7 @@ static char loglockfile[256];
|
||||||
#define RESPONSE_PROXY_DUMP "proxy.response"
|
#define RESPONSE_PROXY_DUMP "proxy.response"
|
||||||
|
|
||||||
/* file in which additional instructions may be found */
|
/* file in which additional instructions may be found */
|
||||||
#define DEFAULT_CMDFILE "log/server.cmd"
|
static const char *cmdfile = "log/server.cmd";
|
||||||
static const char *cmdfile = DEFAULT_CMDFILE;
|
|
||||||
|
|
||||||
/* very-big-path support */
|
/* very-big-path support */
|
||||||
#define MAXDOCNAMELEN 140000
|
#define MAXDOCNAMELEN 140000
|
||||||
|
@ -174,7 +165,7 @@ static const char *cmdfile = DEFAULT_CMDFILE;
|
||||||
static const char *end_of_headers = END_OF_HEADERS;
|
static const char *end_of_headers = END_OF_HEADERS;
|
||||||
|
|
||||||
/* sent as reply to a QUIT */
|
/* sent as reply to a QUIT */
|
||||||
static const char *docquit =
|
static const char *docquit_sws =
|
||||||
"HTTP/1.1 200 Goodbye" END_OF_HEADERS;
|
"HTTP/1.1 200 Goodbye" END_OF_HEADERS;
|
||||||
|
|
||||||
/* send back this on 404 file not found */
|
/* send back this on 404 file not found */
|
||||||
|
@ -212,7 +203,7 @@ static bool socket_domain_is_ip(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* parse the file on disk that might have a test number for us */
|
/* parse the file on disk that might have a test number for us */
|
||||||
static int parse_cmdfile(struct httprequest *req)
|
static int parse_cmdfile(struct sws_httprequest *req)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(cmdfile, FOPEN_READTEXT);
|
FILE *f = fopen(cmdfile, FOPEN_READTEXT);
|
||||||
if(f) {
|
if(f) {
|
||||||
|
@ -230,7 +221,7 @@ static int parse_cmdfile(struct httprequest *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* based on the testno, parse the correct server commands */
|
/* based on the testno, parse the correct server commands */
|
||||||
static int parse_servercmd(struct httprequest *req)
|
static int sws_parse_servercmd(struct sws_httprequest *req)
|
||||||
{
|
{
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
int error;
|
int error;
|
||||||
|
@ -334,7 +325,7 @@ static int parse_servercmd(struct httprequest *req)
|
||||||
return 0; /* OK! */
|
return 0; /* OK! */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ProcessRequest(struct httprequest *req)
|
static int sws_ProcessRequest(struct sws_httprequest *req)
|
||||||
{
|
{
|
||||||
char *line = &req->reqbuf[req->checkindex];
|
char *line = &req->reqbuf[req->checkindex];
|
||||||
bool chunked = FALSE;
|
bool chunked = FALSE;
|
||||||
|
@ -515,7 +506,7 @@ static int ProcessRequest(struct httprequest *req)
|
||||||
req->testno = DOCNUMBER_404;
|
req->testno = DOCNUMBER_404;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
parse_servercmd(req);
|
sws_parse_servercmd(req);
|
||||||
}
|
}
|
||||||
else if((req->offset >= 3)) {
|
else if((req->offset >= 3)) {
|
||||||
unsigned char *l = (unsigned char *)line;
|
unsigned char *l = (unsigned char *)line;
|
||||||
|
@ -544,7 +535,7 @@ static int ProcessRequest(struct httprequest *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find and parse <servercmd> for this test */
|
/* find and parse <servercmd> for this test */
|
||||||
parse_servercmd(req);
|
sws_parse_servercmd(req);
|
||||||
|
|
||||||
if(use_gopher) {
|
if(use_gopher) {
|
||||||
/* when using gopher we cannot check the request until the entire
|
/* when using gopher we cannot check the request until the entire
|
||||||
|
@ -757,7 +748,7 @@ static int ProcessRequest(struct httprequest *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store the entire request in a file */
|
/* store the entire request in a file */
|
||||||
static void storerequest(const char *reqbuf, size_t totalsize)
|
static void sws_storerequest(const char *reqbuf, size_t totalsize)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
@ -811,7 +802,7 @@ storerequest_cleanup:
|
||||||
dumpfile, errno, strerror(errno));
|
dumpfile, errno, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_httprequest(struct httprequest *req)
|
static void init_httprequest(struct sws_httprequest *req)
|
||||||
{
|
{
|
||||||
req->checkindex = 0;
|
req->checkindex = 0;
|
||||||
req->offset = 0;
|
req->offset = 0;
|
||||||
|
@ -838,11 +829,11 @@ static void init_httprequest(struct httprequest *req)
|
||||||
req->upgrade_request = 0;
|
req->upgrade_request = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_doc(curl_socket_t sock, struct httprequest *req);
|
static int sws_send_doc(curl_socket_t sock, struct sws_httprequest *req);
|
||||||
|
|
||||||
/* returns 1 if the connection should be serviced again immediately, 0 if there
|
/* returns 1 if the connection should be serviced again immediately, 0 if there
|
||||||
is no data waiting, or < 0 if it should be closed */
|
is no data waiting, or < 0 if it should be closed */
|
||||||
static int get_request(curl_socket_t sock, struct httprequest *req)
|
static int sws_get_request(curl_socket_t sock, struct sws_httprequest *req)
|
||||||
{
|
{
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
char *reqbuf = req->reqbuf;
|
char *reqbuf = req->reqbuf;
|
||||||
|
@ -852,11 +843,11 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
if(req->upgrade_request) {
|
if(req->upgrade_request) {
|
||||||
/* upgraded connection, work it differently until end of connection */
|
/* upgraded connection, work it differently until end of connection */
|
||||||
logmsg("Upgraded connection, this is no longer HTTP/1");
|
logmsg("Upgraded connection, this is no longer HTTP/1");
|
||||||
send_doc(sock, req);
|
sws_send_doc(sock, req);
|
||||||
|
|
||||||
/* dump the request received so far to the external file */
|
/* dump the request received so far to the external file */
|
||||||
reqbuf[req->offset] = '\0';
|
reqbuf[req->offset] = '\0';
|
||||||
storerequest(reqbuf, req->offset);
|
sws_storerequest(reqbuf, req->offset);
|
||||||
req->offset = 0;
|
req->offset = 0;
|
||||||
|
|
||||||
/* read websocket traffic */
|
/* read websocket traffic */
|
||||||
|
@ -906,7 +897,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
logmsg("log the websocket traffic");
|
logmsg("log the websocket traffic");
|
||||||
/* dump the incoming websocket traffic to the external file */
|
/* dump the incoming websocket traffic to the external file */
|
||||||
reqbuf[req->offset] = '\0';
|
reqbuf[req->offset] = '\0';
|
||||||
storerequest(reqbuf, req->offset);
|
sws_storerequest(reqbuf, req->offset);
|
||||||
req->offset = 0;
|
req->offset = 0;
|
||||||
}
|
}
|
||||||
init_httprequest(req);
|
init_httprequest(req);
|
||||||
|
@ -945,7 +936,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
if(fail) {
|
if(fail) {
|
||||||
/* dump the request received so far to the external file */
|
/* dump the request received so far to the external file */
|
||||||
reqbuf[req->offset] = '\0';
|
reqbuf[req->offset] = '\0';
|
||||||
storerequest(reqbuf, req->offset);
|
sws_storerequest(reqbuf, req->offset);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,7 +945,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
req->offset += (size_t)got;
|
req->offset += (size_t)got;
|
||||||
reqbuf[req->offset] = '\0';
|
reqbuf[req->offset] = '\0';
|
||||||
|
|
||||||
req->done_processing = ProcessRequest(req);
|
req->done_processing = sws_ProcessRequest(req);
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -976,7 +967,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
|
|
||||||
/* at the end of a request dump it to an external file */
|
/* at the end of a request dump it to an external file */
|
||||||
if(fail || req->done_processing)
|
if(fail || req->done_processing)
|
||||||
storerequest(reqbuf, req->offset);
|
sws_storerequest(reqbuf, req->offset);
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -984,7 +975,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns -1 on failure */
|
/* returns -1 on failure */
|
||||||
static int send_doc(curl_socket_t sock, struct httprequest *req)
|
static int sws_send_doc(curl_socket_t sock, struct sws_httprequest *req)
|
||||||
{
|
{
|
||||||
ssize_t written;
|
ssize_t written;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
@ -1036,7 +1027,7 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
|
||||||
switch(req->testno) {
|
switch(req->testno) {
|
||||||
case DOCNUMBER_QUIT:
|
case DOCNUMBER_QUIT:
|
||||||
logmsg("Replying to QUIT");
|
logmsg("Replying to QUIT");
|
||||||
buffer = docquit;
|
buffer = docquit_sws;
|
||||||
break;
|
break;
|
||||||
case DOCNUMBER_WERULEZ:
|
case DOCNUMBER_WERULEZ:
|
||||||
/* we got a "friends?" question, reply back that we sure are */
|
/* we got a "friends?" question, reply back that we sure are */
|
||||||
|
@ -1130,11 +1121,11 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
|
||||||
logmsg("connection close instruction \"swsclose\" found in response");
|
logmsg("connection close instruction \"swsclose\" found in response");
|
||||||
}
|
}
|
||||||
if(strstr(buffer, "swsbounce")) {
|
if(strstr(buffer, "swsbounce")) {
|
||||||
prevbounce = TRUE;
|
sws_prevbounce = TRUE;
|
||||||
logmsg("enable \"swsbounce\" in the next request");
|
logmsg("enable \"swsbounce\" in the next request");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
prevbounce = FALSE;
|
sws_prevbounce = FALSE;
|
||||||
|
|
||||||
dump = fopen(responsedump, "ab");
|
dump = fopen(responsedump, "ab");
|
||||||
if(!dump) {
|
if(!dump) {
|
||||||
|
@ -1204,8 +1195,8 @@ retry:
|
||||||
logmsg("Sending response failed. Only (%zu bytes) of (%zu bytes) "
|
logmsg("Sending response failed. Only (%zu bytes) of (%zu bytes) "
|
||||||
"were sent",
|
"were sent",
|
||||||
responsesize-count, responsesize);
|
responsesize-count, responsesize);
|
||||||
prevtestno = req->testno;
|
sws_prevtestno = req->testno;
|
||||||
prevpartno = req->partno;
|
sws_prevpartno = req->partno;
|
||||||
free(ptr);
|
free(ptr);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1252,8 +1243,8 @@ retry:
|
||||||
free(cmd);
|
free(cmd);
|
||||||
req->open = use_gopher ? FALSE : persistent;
|
req->open = use_gopher ? FALSE : persistent;
|
||||||
|
|
||||||
prevtestno = req->testno;
|
sws_prevtestno = req->testno;
|
||||||
prevpartno = req->partno;
|
sws_prevpartno = req->partno;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1586,7 +1577,7 @@ static void http_connect(curl_socket_t *infdp,
|
||||||
/* a new connection on listener socket (most likely from client) */
|
/* a new connection on listener socket (most likely from client) */
|
||||||
curl_socket_t datafd = accept(rootfd, NULL, NULL);
|
curl_socket_t datafd = accept(rootfd, NULL, NULL);
|
||||||
if(datafd != CURL_SOCKET_BAD) {
|
if(datafd != CURL_SOCKET_BAD) {
|
||||||
static struct httprequest *req2;
|
static struct sws_httprequest *req2;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if(!req2) {
|
if(!req2) {
|
||||||
req2 = malloc(sizeof(*req2));
|
req2 = malloc(sizeof(*req2));
|
||||||
|
@ -1606,7 +1597,7 @@ static void http_connect(curl_socket_t *infdp,
|
||||||
#endif
|
#endif
|
||||||
init_httprequest(req2);
|
init_httprequest(req2);
|
||||||
while(!req2->done_processing) {
|
while(!req2->done_processing) {
|
||||||
err = get_request(datafd, req2);
|
err = sws_get_request(datafd, req2);
|
||||||
if(err < 0) {
|
if(err < 0) {
|
||||||
/* this socket must be closed, done or not */
|
/* this socket must be closed, done or not */
|
||||||
break;
|
break;
|
||||||
|
@ -1615,7 +1606,7 @@ static void http_connect(curl_socket_t *infdp,
|
||||||
|
|
||||||
/* skip this and close the socket if err < 0 */
|
/* skip this and close the socket if err < 0 */
|
||||||
if(err >= 0) {
|
if(err >= 0) {
|
||||||
err = send_doc(datafd, req2);
|
err = sws_send_doc(datafd, req2);
|
||||||
if(!err && req2->connect_request) {
|
if(!err && req2->connect_request) {
|
||||||
/* sleep to prevent triggering libcurl known bug #39. */
|
/* sleep to prevent triggering libcurl known bug #39. */
|
||||||
for(loop = 2; (loop > 0) && !got_exit_signal; loop--)
|
for(loop = 2; (loop > 0) && !got_exit_signal; loop--)
|
||||||
|
@ -1849,7 +1840,7 @@ http_connect_cleanup:
|
||||||
*infdp = CURL_SOCKET_BAD;
|
*infdp = CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void http_upgrade(struct httprequest *req)
|
static void http_upgrade(struct sws_httprequest *req)
|
||||||
{
|
{
|
||||||
(void)req;
|
(void)req;
|
||||||
logmsg("Upgraded to ... %u", req->upgrade_request);
|
logmsg("Upgraded to ... %u", req->upgrade_request);
|
||||||
|
@ -1938,7 +1929,8 @@ static curl_socket_t accept_connection(curl_socket_t sock)
|
||||||
|
|
||||||
/* returns 1 if the connection should be serviced again immediately, 0 if there
|
/* returns 1 if the connection should be serviced again immediately, 0 if there
|
||||||
is no data waiting, or < 0 if it should be closed */
|
is no data waiting, or < 0 if it should be closed */
|
||||||
static int service_connection(curl_socket_t msgsock, struct httprequest *req,
|
static int service_connection(curl_socket_t msgsock,
|
||||||
|
struct sws_httprequest *req,
|
||||||
curl_socket_t listensock,
|
curl_socket_t listensock,
|
||||||
const char *connecthost,
|
const char *connecthost,
|
||||||
int keepalive_secs)
|
int keepalive_secs)
|
||||||
|
@ -1947,27 +1939,27 @@ static int service_connection(curl_socket_t msgsock, struct httprequest *req,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
while(!req->done_processing) {
|
while(!req->done_processing) {
|
||||||
int rc = get_request(msgsock, req);
|
int rc = sws_get_request(msgsock, req);
|
||||||
if(rc <= 0) {
|
if(rc <= 0) {
|
||||||
/* Nothing further to read now, possibly because the socket was closed */
|
/* Nothing further to read now, possibly because the socket was closed */
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prevbounce) {
|
if(sws_prevbounce) {
|
||||||
/* bounce treatment requested */
|
/* bounce treatment requested */
|
||||||
if(req->testno == prevtestno) {
|
if(req->testno == sws_prevtestno) {
|
||||||
req->partno = prevpartno + 1;
|
req->partno = sws_prevpartno + 1;
|
||||||
logmsg("BOUNCE part number to %ld", req->partno);
|
logmsg("BOUNCE part number to %ld", req->partno);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prevbounce = FALSE;
|
sws_prevbounce = FALSE;
|
||||||
prevtestno = -1;
|
sws_prevtestno = -1;
|
||||||
prevpartno = -1;
|
sws_prevpartno = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_doc(msgsock, req);
|
sws_send_doc(msgsock, req);
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -2019,19 +2011,16 @@ int main(int argc, char *argv[])
|
||||||
int wrotepidfile = 0;
|
int wrotepidfile = 0;
|
||||||
int wroteportfile = 0;
|
int wroteportfile = 0;
|
||||||
int flag;
|
int flag;
|
||||||
unsigned short port = DEFAULT_PORT;
|
unsigned short port = 8999;
|
||||||
#ifdef USE_UNIX_SOCKETS
|
#ifdef USE_UNIX_SOCKETS
|
||||||
const char *unix_socket = NULL;
|
const char *unix_socket = NULL;
|
||||||
bool unlink_socket = false;
|
bool unlink_socket = false;
|
||||||
#endif
|
#endif
|
||||||
const char *pidname = ".http.pid";
|
struct sws_httprequest *req = NULL;
|
||||||
const char *portname = ".http.port";
|
|
||||||
struct httprequest *req = NULL;
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int error;
|
int error;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
const char *connecthost = "127.0.0.1";
|
const char *connecthost = "127.0.0.1";
|
||||||
const char *socket_type = "IPv4";
|
|
||||||
char port_str[11];
|
char port_str[11];
|
||||||
const char *location_str = port_str;
|
const char *location_str = port_str;
|
||||||
int keepalive_secs = 5;
|
int keepalive_secs = 5;
|
||||||
|
@ -2040,7 +2029,10 @@ int main(int argc, char *argv[])
|
||||||
/* a default CONNECT port is basically pointless but still ... */
|
/* a default CONNECT port is basically pointless but still ... */
|
||||||
size_t socket_idx;
|
size_t socket_idx;
|
||||||
|
|
||||||
|
pidname = ".http.pid";
|
||||||
|
portname = ".http.port";
|
||||||
serverlogfile = "log/sws.log";
|
serverlogfile = "log/sws.log";
|
||||||
|
serverlogslocked = 0;
|
||||||
|
|
||||||
while(argc > arg) {
|
while(argc > arg) {
|
||||||
if(!strcmp("--version", argv[arg])) {
|
if(!strcmp("--version", argv[arg])) {
|
||||||
|
@ -2337,8 +2329,8 @@ int main(int argc, char *argv[])
|
||||||
if(!wroteportfile)
|
if(!wroteportfile)
|
||||||
goto sws_cleanup;
|
goto sws_cleanup;
|
||||||
|
|
||||||
/* initialization of httprequest struct is done before get_request(), but
|
/* initialization of httprequest struct is done before sws_get_request(),
|
||||||
the pipelining struct field must be initialized previously to FALSE
|
but the pipelining struct field must be initialized previously to FALSE
|
||||||
every time a new connection arrives. */
|
every time a new connection arrives. */
|
||||||
|
|
||||||
init_httprequest(req);
|
init_httprequest(req);
|
||||||
|
@ -2440,7 +2432,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if(req->connmon) {
|
if(req->connmon) {
|
||||||
const char *keepopen = "[DISCONNECT]\n";
|
const char *keepopen = "[DISCONNECT]\n";
|
||||||
storerequest(keepopen, strlen(keepopen));
|
sws_storerequest(keepopen, strlen(keepopen));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!req->open)
|
if(!req->open)
|
||||||
|
|
|
@ -152,8 +152,6 @@ struct bf {
|
||||||
|
|
||||||
#define REQUEST_DUMP "server.input"
|
#define REQUEST_DUMP "server.input"
|
||||||
|
|
||||||
#define DEFAULT_PORT 8999 /* UDP */
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* GLOBAL VARIABLES *
|
* GLOBAL VARIABLES *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
@ -185,7 +183,7 @@ static int current; /* index of buffer in use */
|
||||||
static int newline = 0; /* fillbuf: in middle of newline expansion */
|
static int newline = 0; /* fillbuf: in middle of newline expansion */
|
||||||
static int prevchar = -1; /* putbuf: previous char (cr check) */
|
static int prevchar = -1; /* putbuf: previous char (cr check) */
|
||||||
|
|
||||||
static tftphdr_storage_t buf;
|
static tftphdr_storage_t trsbuf;
|
||||||
static tftphdr_storage_t ackbuf;
|
static tftphdr_storage_t ackbuf;
|
||||||
|
|
||||||
static srvr_sockaddr_union_t from;
|
static srvr_sockaddr_union_t from;
|
||||||
|
@ -196,18 +194,8 @@ static curl_socket_t peer = CURL_SOCKET_BAD;
|
||||||
static unsigned int timeout;
|
static unsigned int timeout;
|
||||||
static unsigned int maxtimeout = 5 * TIMEOUT;
|
static unsigned int maxtimeout = 5 * TIMEOUT;
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
static int tftpd_wrotepidfile = 0;
|
||||||
static bool use_ipv6 = FALSE;
|
static int tftpd_wroteportfile = 0;
|
||||||
#endif
|
|
||||||
static const char *ipv_inuse = "IPv4";
|
|
||||||
|
|
||||||
static const char *logdir = "log";
|
|
||||||
static char loglockfile[256];
|
|
||||||
static const char *pidname = ".tftpd.pid";
|
|
||||||
static const char *portname = NULL; /* none by default */
|
|
||||||
static int serverlogslocked = 0;
|
|
||||||
static int wrotepidfile = 0;
|
|
||||||
static int wroteportfile = 0;
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGSETJMP
|
#ifdef HAVE_SIGSETJMP
|
||||||
static sigjmp_buf timeoutbuf;
|
static sigjmp_buf timeoutbuf;
|
||||||
|
@ -282,12 +270,12 @@ static void timer(int signum)
|
||||||
|
|
||||||
timeout += rexmtval;
|
timeout += rexmtval;
|
||||||
if(timeout >= maxtimeout) {
|
if(timeout >= maxtimeout) {
|
||||||
if(wrotepidfile) {
|
if(tftpd_wrotepidfile) {
|
||||||
wrotepidfile = 0;
|
tftpd_wrotepidfile = 0;
|
||||||
unlink(pidname);
|
unlink(pidname);
|
||||||
}
|
}
|
||||||
if(wroteportfile) {
|
if(tftpd_wroteportfile) {
|
||||||
wroteportfile = 0;
|
tftpd_wroteportfile = 0;
|
||||||
unlink(portname);
|
unlink(portname);
|
||||||
}
|
}
|
||||||
if(serverlogslocked) {
|
if(serverlogslocked) {
|
||||||
|
@ -549,7 +537,7 @@ int main(int argc, char **argv)
|
||||||
struct tftphdr *tp;
|
struct tftphdr *tp;
|
||||||
ssize_t n = 0;
|
ssize_t n = 0;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
unsigned short port = DEFAULT_PORT;
|
unsigned short port = 8999; /* UDP */
|
||||||
curl_socket_t sock = CURL_SOCKET_BAD;
|
curl_socket_t sock = CURL_SOCKET_BAD;
|
||||||
int flag;
|
int flag;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -559,7 +547,9 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
memset(&test, 0, sizeof(test));
|
memset(&test, 0, sizeof(test));
|
||||||
|
|
||||||
|
pidname = ".tftpd.pid";
|
||||||
serverlogfile = "log/tftpd.log";
|
serverlogfile = "log/tftpd.log";
|
||||||
|
serverlogslocked = 0;
|
||||||
|
|
||||||
while(argc > arg) {
|
while(argc > arg) {
|
||||||
if(!strcmp("--version", argv[arg])) {
|
if(!strcmp("--version", argv[arg])) {
|
||||||
|
@ -743,15 +733,15 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wrotepidfile = write_pidfile(pidname);
|
tftpd_wrotepidfile = write_pidfile(pidname);
|
||||||
if(!wrotepidfile) {
|
if(!tftpd_wrotepidfile) {
|
||||||
result = 1;
|
result = 1;
|
||||||
goto tftpd_cleanup;
|
goto tftpd_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(portname) {
|
if(portname) {
|
||||||
wroteportfile = write_portfile(portname, port);
|
tftpd_wroteportfile = write_portfile(portname, port);
|
||||||
if(!wroteportfile) {
|
if(!tftpd_wroteportfile) {
|
||||||
result = 1;
|
result = 1;
|
||||||
goto tftpd_cleanup;
|
goto tftpd_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -769,7 +759,7 @@ int main(int argc, char **argv)
|
||||||
else
|
else
|
||||||
fromlen = sizeof(from.sa6);
|
fromlen = sizeof(from.sa6);
|
||||||
#endif
|
#endif
|
||||||
n = (ssize_t)recvfrom(sock, &buf.storage[0], sizeof(buf.storage), 0,
|
n = (ssize_t)recvfrom(sock, &trsbuf.storage[0], sizeof(trsbuf.storage), 0,
|
||||||
&from.sa, &fromlen);
|
&from.sa, &fromlen);
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
break;
|
break;
|
||||||
|
@ -817,7 +807,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
maxtimeout = 5*TIMEOUT;
|
maxtimeout = 5*TIMEOUT;
|
||||||
|
|
||||||
tp = &buf.hdr;
|
tp = &trsbuf.hdr;
|
||||||
tp->th_opcode = ntohs(tp->th_opcode);
|
tp->th_opcode = ntohs(tp->th_opcode);
|
||||||
if(tp->th_opcode == opcode_RRQ || tp->th_opcode == opcode_WRQ) {
|
if(tp->th_opcode == opcode_RRQ || tp->th_opcode == opcode_WRQ) {
|
||||||
memset(&test, 0, sizeof(test));
|
memset(&test, 0, sizeof(test));
|
||||||
|
@ -854,9 +844,9 @@ tftpd_cleanup:
|
||||||
if(got_exit_signal)
|
if(got_exit_signal)
|
||||||
logmsg("signalled to die");
|
logmsg("signalled to die");
|
||||||
|
|
||||||
if(wrotepidfile)
|
if(tftpd_wrotepidfile)
|
||||||
unlink(pidname);
|
unlink(pidname);
|
||||||
if(wroteportfile)
|
if(tftpd_wroteportfile)
|
||||||
unlink(portname);
|
unlink(portname);
|
||||||
|
|
||||||
if(serverlogslocked) {
|
if(serverlogslocked) {
|
||||||
|
@ -916,7 +906,7 @@ static int do_tftp(struct testcase *test, struct tftphdr *tp, ssize_t size)
|
||||||
filename = cp;
|
filename = cp;
|
||||||
do {
|
do {
|
||||||
bool endofit = true;
|
bool endofit = true;
|
||||||
while(cp < &buf.storage[size]) {
|
while(cp < &trsbuf.storage[size]) {
|
||||||
if(*cp == '\0') {
|
if(*cp == '\0') {
|
||||||
endofit = false;
|
endofit = false;
|
||||||
break;
|
break;
|
||||||
|
@ -929,7 +919,7 @@ static int do_tftp(struct testcase *test, struct tftphdr *tp, ssize_t size)
|
||||||
|
|
||||||
/* before increasing pointer, make sure it is still within the legal
|
/* before increasing pointer, make sure it is still within the legal
|
||||||
space */
|
space */
|
||||||
if((cp + 1) < &buf.storage[size]) {
|
if((cp + 1) < &trsbuf.storage[size]) {
|
||||||
++cp;
|
++cp;
|
||||||
if(first) {
|
if(first) {
|
||||||
/* store the mode since we need it later */
|
/* store the mode since we need it later */
|
||||||
|
@ -1003,7 +993,7 @@ static int do_tftp(struct testcase *test, struct tftphdr *tp, ssize_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Based on the testno, parse the correct server commands. */
|
/* Based on the testno, parse the correct server commands. */
|
||||||
static int parse_servercmd(struct testcase *req)
|
static int tftpd_parse_servercmd(struct testcase *req)
|
||||||
{
|
{
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
int error;
|
int error;
|
||||||
|
@ -1117,7 +1107,7 @@ static int validate_access(struct testcase *test,
|
||||||
|
|
||||||
test->testno = testno;
|
test->testno = testno;
|
||||||
|
|
||||||
(void)parse_servercmd(test);
|
(void)tftpd_parse_servercmd(test);
|
||||||
|
|
||||||
stream = test2fopen(testno, logdir);
|
stream = test2fopen(testno, logdir);
|
||||||
|
|
||||||
|
@ -1324,7 +1314,7 @@ send_ack:
|
||||||
alarm(rexmtval);
|
alarm(rexmtval);
|
||||||
#endif
|
#endif
|
||||||
/* normally times out and quits */
|
/* normally times out and quits */
|
||||||
n = sread(peer, &buf.storage[0], sizeof(buf.storage));
|
n = sread(peer, &trsbuf.storage[0], sizeof(trsbuf.storage));
|
||||||
#ifdef HAVE_ALARM
|
#ifdef HAVE_ALARM
|
||||||
alarm(0);
|
alarm(0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1354,7 +1344,7 @@ static void nak(int error)
|
||||||
int length;
|
int length;
|
||||||
struct errmsg *pe;
|
struct errmsg *pe;
|
||||||
|
|
||||||
tp = &buf.hdr;
|
tp = &trsbuf.hdr;
|
||||||
tp->th_opcode = htons(opcode_ERROR);
|
tp->th_opcode = htons(opcode_ERROR);
|
||||||
tp->th_code = htons((unsigned short)error);
|
tp->th_code = htons((unsigned short)error);
|
||||||
for(pe = errmsgs; pe->e_code >= 0; pe++)
|
for(pe = errmsgs; pe->e_code >= 0; pe++)
|
||||||
|
@ -1370,6 +1360,6 @@ static void nak(int error)
|
||||||
* report from glibc with FORTIFY_SOURCE */
|
* report from glibc with FORTIFY_SOURCE */
|
||||||
memcpy(tp->th_msg, pe->e_msg, length + 1);
|
memcpy(tp->th_msg, pe->e_msg, length + 1);
|
||||||
length += 5;
|
length += 5;
|
||||||
if(swrite(peer, &buf.storage[0], length) != length)
|
if(swrite(peer, &trsbuf.storage[0], length) != length)
|
||||||
logmsg("nak: fail\n");
|
logmsg("nak: fail\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,6 @@
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_POLL_H
|
|
||||||
#include <poll.h>
|
|
||||||
#elif defined(HAVE_SYS_POLL_H)
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MSDOS
|
#ifdef MSDOS
|
||||||
#include <dos.h> /* delay() */
|
#include <dos.h> /* delay() */
|
||||||
|
@ -53,10 +48,23 @@
|
||||||
#include "curlx.h" /* from the private lib dir */
|
#include "curlx.h" /* from the private lib dir */
|
||||||
#include "getpart.h"
|
#include "getpart.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "timeval.h"
|
|
||||||
#include "timediff.h"
|
#include "timediff.h"
|
||||||
|
|
||||||
const char *serverlogfile = NULL; /* needs init from main() */
|
/* need init from main() */
|
||||||
|
const char *pidname = NULL;
|
||||||
|
const char *portname = NULL; /* none by default */
|
||||||
|
const char *serverlogfile = NULL;
|
||||||
|
int serverlogslocked;
|
||||||
|
const char *configfile = NULL;
|
||||||
|
const char *logdir = "log";
|
||||||
|
char loglockfile[256];
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
bool use_ipv6 = FALSE;
|
||||||
|
#endif
|
||||||
|
const char *ipv_inuse = "IPv4";
|
||||||
|
unsigned short server_port = 0;
|
||||||
|
const char *socket_type = "IPv4";
|
||||||
|
int socket_domain = AF_INET;
|
||||||
|
|
||||||
static struct timeval tvnow(void);
|
static struct timeval tvnow(void);
|
||||||
|
|
||||||
|
@ -137,6 +145,31 @@ void logmsg(const char *msg, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loghex(unsigned char *buffer, ssize_t len)
|
||||||
|
{
|
||||||
|
char data[12000];
|
||||||
|
ssize_t i;
|
||||||
|
unsigned char *ptr = buffer;
|
||||||
|
char *optr = data;
|
||||||
|
ssize_t width = 0;
|
||||||
|
int left = sizeof(data);
|
||||||
|
|
||||||
|
for(i = 0; i < len && (left >= 0); i++) {
|
||||||
|
msnprintf(optr, left, "%02x", ptr[i]);
|
||||||
|
width += 2;
|
||||||
|
optr += 2;
|
||||||
|
left -= 2;
|
||||||
|
}
|
||||||
|
if(width)
|
||||||
|
logmsg("'%s'", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char byteval(char *value)
|
||||||
|
{
|
||||||
|
unsigned long num = strtoul(value, NULL, 10);
|
||||||
|
return num & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/* use instead of perror() on generic Windows */
|
/* use instead of perror() on generic Windows */
|
||||||
static void win32_perror(const char *msg)
|
static void win32_perror(const char *msg)
|
||||||
|
@ -239,13 +272,6 @@ static long timediff(struct timeval newer, struct timeval older)
|
||||||
*/
|
*/
|
||||||
int wait_ms(int timeout_ms)
|
int wait_ms(int timeout_ms)
|
||||||
{
|
{
|
||||||
#if !defined(MSDOS) && !defined(USE_WINSOCK)
|
|
||||||
#ifndef HAVE_POLL
|
|
||||||
struct timeval pending_tv;
|
|
||||||
#endif
|
|
||||||
struct timeval initial_tv;
|
|
||||||
int pending_ms;
|
|
||||||
#endif
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
if(!timeout_ms)
|
if(!timeout_ms)
|
||||||
|
@ -259,17 +285,17 @@ int wait_ms(int timeout_ms)
|
||||||
#elif defined(USE_WINSOCK)
|
#elif defined(USE_WINSOCK)
|
||||||
Sleep((DWORD)timeout_ms);
|
Sleep((DWORD)timeout_ms);
|
||||||
#else
|
#else
|
||||||
pending_ms = timeout_ms;
|
/* avoid using poll() for this since it behaves incorrectly with no sockets
|
||||||
initial_tv = tvnow();
|
on Apple operating systems */
|
||||||
|
{
|
||||||
|
struct timeval pending_tv;
|
||||||
|
struct timeval initial_tv = tvnow();
|
||||||
|
int pending_ms = timeout_ms;
|
||||||
do {
|
do {
|
||||||
int error;
|
int error;
|
||||||
#ifdef HAVE_POLL
|
|
||||||
r = poll(NULL, 0, pending_ms);
|
|
||||||
#else
|
|
||||||
pending_tv.tv_sec = pending_ms / 1000;
|
pending_tv.tv_sec = pending_ms / 1000;
|
||||||
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
|
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
|
||||||
r = select(0, NULL, NULL, NULL, &pending_tv);
|
r = select(0, NULL, NULL, NULL, &pending_tv);
|
||||||
#endif /* HAVE_POLL */
|
|
||||||
if(r != -1)
|
if(r != -1)
|
||||||
break;
|
break;
|
||||||
error = errno;
|
error = errno;
|
||||||
|
@ -279,6 +305,7 @@ int wait_ms(int timeout_ms)
|
||||||
if(pending_ms <= 0)
|
if(pending_ms <= 0)
|
||||||
break;
|
break;
|
||||||
} while(r == -1);
|
} while(r == -1);
|
||||||
|
}
|
||||||
#endif /* USE_WINSOCK */
|
#endif /* USE_WINSOCK */
|
||||||
if(r)
|
if(r)
|
||||||
r = -1;
|
r = -1;
|
||||||
|
|
|
@ -51,14 +51,27 @@ enum {
|
||||||
|
|
||||||
char *data_to_hex(char *data, size_t len);
|
char *data_to_hex(char *data, size_t len);
|
||||||
void logmsg(const char *msg, ...) CURL_PRINTF(1, 2);
|
void logmsg(const char *msg, ...) CURL_PRINTF(1, 2);
|
||||||
|
void loghex(unsigned char *buffer, ssize_t len);
|
||||||
|
unsigned char byteval(char *value);
|
||||||
|
|
||||||
#define SERVERLOGS_LOCKDIR "lock" /* within logdir */
|
#define SERVERLOGS_LOCKDIR "lock" /* within logdir */
|
||||||
|
|
||||||
/* global variable, where to find the 'data' dir */
|
/* global variables */
|
||||||
extern const char *path;
|
extern const char *path; /* where to find the 'data' dir */
|
||||||
|
extern const char *pidname;
|
||||||
/* global variable, log file name */
|
extern const char *portname;
|
||||||
extern const char *serverlogfile;
|
extern const char *serverlogfile; /* log file name */
|
||||||
|
extern int serverlogslocked;
|
||||||
|
extern const char *configfile;
|
||||||
|
extern const char *logdir;
|
||||||
|
extern char loglockfile[256];
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
extern bool use_ipv6;
|
||||||
|
#endif
|
||||||
|
extern const char *ipv_inuse;
|
||||||
|
extern unsigned short server_port;
|
||||||
|
extern const char *socket_type;
|
||||||
|
extern int socket_domain;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
int win32_init(void);
|
int win32_init(void);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user