Skip to content

Commit

Permalink
Merge pull request #76 from fstirlitz/inetd-mode-fix
Browse files Browse the repository at this point in the history
inetd mode fix; resolves #75
  • Loading branch information
yoe committed Apr 4, 2018
2 parents 73bf94e + 3e45197 commit 24e4912
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -8,4 +8,4 @@ compiler:
install:
- sh .travis/before_install
group: travis_latest
script: ./autogen.sh && ./configure && make && make NBD_TEST_SILENT=1 check
script: ./autogen.sh && ./configure --enable-syslog && make && make NBD_TEST_SILENT=1 check
26 changes: 13 additions & 13 deletions nbd-server.c
Expand Up @@ -3538,19 +3538,6 @@ int main(int argc, char *argv[]) {

if(serve) {
g_array_append_val(servers, *serve);

if(strcmp(genconf.modernport, "0")==0) {
#ifndef ISSERVER
err("inetd mode requires syslog");
#endif
CLIENT* client = g_malloc(sizeof(CLIENT));
client->net = -1;
if(!commit_client(client, serve)) {
exit(EXIT_FAILURE);
}
mainloop_threaded(client);
return 0;
}
}

if(!servers || !servers->len) {
Expand Down Expand Up @@ -3594,5 +3581,18 @@ int main(int argc, char *argv[]) {
#endif
));
#endif

if((genconf.modernport != NULL) && strcmp(genconf.modernport, "0")==0) {
#ifndef ISSERVER
err("inetd mode requires syslog");
#endif
CLIENT* client = negotiate(0, servers, &genconf);
if(!client) {
exit(EXIT_FAILURE);
}
mainloop_threaded(client);
return 0;
}

serveloop(servers, &genconf);
}
3 changes: 2 additions & 1 deletion tests/run/Makefile.am
Expand Up @@ -4,7 +4,7 @@ else
TLSSRC =
endif
TESTS_ENVIRONMENT=$(srcdir)/simple_test
TESTS = cfg1 cfgmulti cfgnew cfgsize write flush integrity dirconfig list \
TESTS = cfg1 cfgmulti cfgnew cfgsize write flush integrity dirconfig list inetd \
rowrite tree rotree unix integrityhuge handshake tls tlshuge tlswrongcert
check_PROGRAMS = nbd-tester-client
## Various Automake versions don't play nice with files in parent
Expand Down Expand Up @@ -44,6 +44,7 @@ rowrite:
tree:
rotree:
unix:
inetd:
handshake:
tls:
tlshuge:
Expand Down
167 changes: 88 additions & 79 deletions tests/run/nbd-tester-client.c
Expand Up @@ -60,8 +60,6 @@ static gchar *cacertfile = NULL;
static gchar *tlshostname = NULL;

typedef enum {
CONNECTION_TYPE_NONE,
CONNECTION_TYPE_CONNECT,
CONNECTION_TYPE_INIT_PASSWD,
CONNECTION_TYPE_CLISERV,
CONNECTION_TYPE_FULL,
Expand Down Expand Up @@ -574,16 +572,12 @@ int setup_connection_common(int sock, char *name, CONNECTION_TYPE ctype,
return sock;
}

int setup_unix_connection(gchar * unixsock, gchar * name, CONNECTION_TYPE ctype,
int *serverflags, int testflags)
int setup_unix_connection(gchar * unixsock)
{
struct sockaddr_un addr;
int sock;

sock = 0;
if (ctype < CONNECTION_TYPE_CONNECT) {
goto end;
}
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
strncpy(errstr, strerror(errno), errstr_len);
goto err;
Expand All @@ -598,7 +592,6 @@ int setup_unix_connection(gchar * unixsock, gchar * name, CONNECTION_TYPE ctype,
strncpy(errstr, strerror(errno), errstr_len);
goto err_open;
}
sock = setup_connection_common(sock, name, ctype, serverflags, testflags);
goto end;
err_open:
close(sock);
Expand All @@ -608,16 +601,13 @@ int setup_unix_connection(gchar * unixsock, gchar * name, CONNECTION_TYPE ctype,
return sock;
}

int setup_inet_connection(gchar * hostname, int port, gchar * name,
CONNECTION_TYPE ctype, int *serverflags, int testflags)
int setup_inet_connection(gchar * hostname, int port)
{
int sock;
struct hostent *host;
struct sockaddr_in addr;

sock = 0;
if (ctype < CONNECTION_TYPE_CONNECT)
goto end;
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
strncpy(errstr, strerror(errno), errstr_len);
goto err;
Expand All @@ -634,7 +624,6 @@ int setup_inet_connection(gchar * hostname, int port, gchar * name,
strncpy(errstr, strerror(errno), errstr_len);
goto err_open;
}
sock = setup_connection_common(sock, name, ctype, serverflags, testflags);
goto end;
err_open:
close(sock);
Expand All @@ -644,19 +633,33 @@ int setup_inet_connection(gchar * hostname, int port, gchar * name,
return sock;
}

int setup_connection(gchar * hostname, gchar * unixsock, int port, gchar * name,
CONNECTION_TYPE ctype, int *serverflags, int testflags)
int setup_inetd_connection(gchar **argv)
{
if (hostname != NULL) {
return setup_inet_connection(hostname, port, name, ctype,
serverflags, testflags);
} else if (unixsock != NULL) {
return setup_unix_connection(unixsock, name, ctype,
serverflags, testflags);
} else {
g_error("need a hostname or a unix domain socket!");
int sv[2];
pid_t child;

if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
strncpy(errstr, strerror(errno), errstr_len);
return -1;
}

child = vfork();
if (child == 0) {
dup2(sv[0], 0);
close(sv[0]);
close(sv[1]);
execvp(argv[0], argv);
} else if (child == -1) {
close(sv[0]);
close(sv[1]);
strncpy(errstr, strerror(errno), errstr_len);
return -1;
}

close(sv[0]);
setmysockopt(sv[1]);

return sv[1];
}

int close_connection(int sock, CLOSE_TYPE type)
Expand Down Expand Up @@ -731,8 +734,7 @@ int read_packet_check_header(int sock, size_t datasize, long long int curhandle)
return retval;
}

int oversize_test(gchar * hostname, gchar * unixsock, int port, char *name,
int sock, char sock_is_open, char close_sock, int testflags)
int oversize_test(char *name, int sock, char close_sock, int testflags)
{
int retval = 0;
struct nbd_request req;
Expand All @@ -744,15 +746,13 @@ int oversize_test(gchar * hostname, gchar * unixsock, int port, char *name,
bool got_err;

/* This should work */
if (!sock_is_open) {
if ((sock =
setup_connection(hostname, unixsock, port, name,
CONNECTION_TYPE_FULL,
&serverflags, testflags)) < 0) {
g_warning("Could not open socket: %s", errstr);
retval = -1;
goto err;
}
if ((sock =
setup_connection_common(sock, name,
CONNECTION_TYPE_FULL,
&serverflags, testflags)) < 0) {
g_warning("Could not open socket: %s", errstr);
retval = -1;
goto err;
}
req.magic = htonl(NBD_REQUEST_MAGIC);
req.type = htonl(NBD_CMD_READ);
Expand Down Expand Up @@ -816,23 +816,20 @@ int oversize_test(gchar * hostname, gchar * unixsock, int port, char *name,
return retval;
}

int handshake_test(gchar * hostname, gchar * unixsock, int port, char *name,
int sock, char sock_is_open, char close_sock, int testflags)
int handshake_test(char *name, int sock, char close_sock, int testflags)
{
int retval = -1;
int serverflags = 0;
u64 tmp64;
uint32_t tmp32 = 0;

/* This should work */
if (!sock_is_open) {
if ((sock =
setup_connection(hostname, unixsock, port, name,
CONNECTION_TYPE_FULL,
&serverflags, testflags)) < 0) {
g_warning("Could not open socket: %s", errstr);
goto err;
}
if ((sock =
setup_connection_common(sock, name,
CONNECTION_TYPE_FULL,
&serverflags, testflags)) < 0) {
g_warning("Could not open socket: %s", errstr);
goto err;
}

/* Intentionally throw an unknown option at the server */
Expand Down Expand Up @@ -899,8 +896,7 @@ int handshake_test(gchar * hostname, gchar * unixsock, int port, char *name,
return retval;
}

int throughput_test(gchar * hostname, gchar * unixsock, int port, char *name,
int sock, char sock_is_open, char close_sock, int testflags)
int throughput_test(char *name, int sock, char close_sock, int testflags)
{
long long int i;
char writebuf[1024];
Expand All @@ -924,20 +920,18 @@ int throughput_test(gchar * hostname, gchar * unixsock, int port, char *name,

memset(writebuf, 'X', 1024);
size = 0;
if (!sock_is_open) {
if ((sock =
setup_connection(hostname, unixsock, port, name,
CONNECTION_TYPE_FULL,
&serverflags, testflags)) < 0) {
g_warning("Could not open socket: %s", errstr);
if(testflags & TEST_EXPECT_ERROR) {
g_message("Test failed, as expected");
retval = 0;
} else {
retval = -1;
}
goto err;
if ((sock =
setup_connection_common(sock, name,
CONNECTION_TYPE_FULL,
&serverflags, testflags)) < 0) {
g_warning("Could not open socket: %s", errstr);
if(testflags & TEST_EXPECT_ERROR) {
g_message("Test failed, as expected");
retval = 0;
} else {
retval = -1;
}
goto err;
}
if ((testflags & TEST_FLUSH)
&& ((serverflags & (NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA))
Expand Down Expand Up @@ -1170,8 +1164,7 @@ uint64_t getrandomhandle(GHashTable * phash)
return handle;
}

int integrity_test(gchar * hostname, gchar * unixsock, int port, char *name,
int sock, char sock_is_open, char close_sock, int testflags)
int integrity_test(char *name, int sock, char close_sock, int testflags)
{
struct nbd_reply rep;
fd_set rset;
Expand Down Expand Up @@ -1203,14 +1196,12 @@ int integrity_test(gchar * hostname, gchar * unixsock, int port, char *name,
GHashTable *handlehash = g_hash_table_new(g_int64_hash, g_int64_equal);

size = 0;
if (!sock_is_open) {
if ((sock =
setup_connection(hostname, unixsock, port, name,
CONNECTION_TYPE_FULL,
&serverflags, testflags)) < 0) {
g_warning("Could not open socket: %s", errstr);
goto err;
}
if ((sock =
setup_connection_common(sock, name,
CONNECTION_TYPE_FULL,
&serverflags, testflags)) < 0) {
g_warning("Could not open socket: %s", errstr);
goto err;
}

if ((serverflags & (NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA))
Expand Down Expand Up @@ -1720,14 +1711,14 @@ void handle_nonopt(char *opt, gchar ** hostname, long int *p)
}
}

typedef int (*testfunc) (gchar *, gchar *, int, char *, int, char, char, int);
typedef int (*testfunc) (char *, int, char, int);

int main(int argc, char **argv)
{
gchar *hostname = NULL, *unixsock = NULL;
long int p = 0;
long int p = 10809;
char *name = NULL;
int sock = 0;
int sock = -1;
int c;
int testflags = 0;
testfunc test = throughput_test;
Expand All @@ -1752,16 +1743,13 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
logging(MY_NAME);
while ((c = getopt(argc, argv, "FN:t:owfilu:hC:K:A:H:")) >= 0) {
while ((c = getopt(argc, argv, "FN:t:owfilu:hC:K:A:H:I")) >= 0) {
switch (c) {
case 1:
handle_nonopt(optarg, &hostname, &p);
break;
case 'N':
name = g_strdup(optarg);
if (!p) {
p = 10809;
}
break;
case 'F':
testflags |= TEST_EXPECT_ERROR;
Expand All @@ -1781,6 +1769,9 @@ int main(int argc, char **argv)
case 'f':
testflags |= TEST_FLUSH;
break;
case 'I':
p = -1;
break;
case 'i':
test = integrity_test;
break;
Expand Down Expand Up @@ -1816,8 +1807,10 @@ int main(int argc, char **argv)
}
}

while (optind < argc) {
handle_nonopt(argv[optind++], &hostname, &p);
if (p != -1) {
while (optind < argc) {
handle_nonopt(argv[optind++], &hostname, &p);
}
}

if (keyfile && !certfile)
Expand All @@ -1826,7 +1819,23 @@ int main(int argc, char **argv)
if (!tlshostname && hostname)
tlshostname = g_strdup(hostname);

if (test(hostname, unixsock, (int)p, name, sock, FALSE, TRUE, testflags)
if (hostname != NULL) {
sock = setup_inet_connection(hostname, p);
} else if (unixsock != NULL) {
sock = setup_unix_connection(unixsock);
} else if (p == -1) {
sock = setup_inetd_connection(argv + optind);
} else {
g_error("need a hostname, a unix domain socket or inetd-mode command line!");
return -1;
}

if (sock == -1) {
g_warning("Could not establish a connection: %s", errstr);
exit(EXIT_FAILURE);
}

if (test(name, sock, TRUE, testflags)
< 0) {
g_warning("Could not run test: %s", errstr);
exit(EXIT_FAILURE);
Expand Down

0 comments on commit 24e4912

Please sign in to comment.