Skip to content

Commit

Permalink
Merge pull request acassen#2150 from pqarmitage/updates
Browse files Browse the repository at this point in the history
Update parser recalculating buffer length
  • Loading branch information
pqarmitage authored Jun 30, 2022
2 parents ed0b727 + 2a7950a commit 2c081d0
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 3 deletions.
4 changes: 3 additions & 1 deletion lib/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2746,7 +2746,6 @@ read_line(char *buf, size_t size)

do {
recheck = false;
len = strlen(buf);
if (buf[0] == '@') {
/* If the line starts '@', check the following word matches the system id.
@^ reverses the sense of the match */
Expand Down Expand Up @@ -2821,6 +2820,9 @@ read_line(char *buf, size_t size)
recheck = true;
if (strchr(buf, '$'))
recheck = true;

if (recheck)
len = strlen(buf);
}
} while (recheck);
} while (buf[0] == '\0' || check_include(buf));
Expand Down
1 change: 1 addition & 0 deletions test/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
tcp_server
tcp_client
139 changes: 139 additions & 0 deletions test/tcp_client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdbool.h>

static void
print_usage(FILE *fp, const char *name)
{
fprintf(fp, "Usage: %s [options]\n", name);
fprintf(fp, "\t-a addr\t\tbind to addr\n");
fprintf(fp, "\t-p port\t\tlisten on port\n");
fprintf(fp, "\t-s\t\tsilent\n");
fprintf(fp, "\t-u\t\tuse UDP\n");
fprintf(fp, "\t-d dly\tdelay dly seconds after connect\n");
fprintf(fp, "\t-e\t\techo\n");
fprintf(fp, "\t-f\t\tenable tcp_fastopen\n");
fprintf(fp, "\t-h\t\tprint this\n");
}

int main(int argc, char **argv)
{
struct addrinfo hint = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM };
struct addrinfo *res;
int ret;
int sock;
char *addr_str;
char *port_str;
bool silent = false;
bool echo_data = false;
int sock_type = SOCK_STREAM;
bool tcp_fastopen = false;
ssize_t r;
ssize_t len;
int opt;
char *endptr;
int msglen = 4000;
char *msg = malloc(msglen);
uint8_t *buf = malloc(msglen);
unsigned delay_after_connect = 0;


while ((opt = getopt(argc, argv, ":ha:p:sud:ef")) != -1) {
switch (opt) {
case 'a':
addr_str = optarg;
break;
case 'p':
#if 0
port_num = strtol(optarg, &endptr, 10);
if (*endptr || port_num <= 0 || port_num > 65535) {
fprintf(stderr, "Port number '%s' invalid\n", optarg);
exit(EXIT_FAILURE);
}
port = port_num;
#endif
port_str = optarg;
break;
case 's':
silent = true;
break;
case 'u':
sock_type = SOCK_DGRAM;
break;
case 'd':
delay_after_connect = strtol(optarg, &endptr, 10);
break;
case 'e':
echo_data = true;
break;
case 'h':
print_usage(stdout, argv[0]);
exit(0);
case 'f':
tcp_fastopen = true;
break;
case ':':
fprintf(stderr, "Option '%c' is missing an argument\n", optopt);
break;
default: /* '?' */
print_usage(stderr, argv[0]);
exit(EXIT_FAILURE);
}
}

ret = getaddrinfo(addr_str, port_str, &hint, &res);
if (ret == -1) {
printf("getaddrinfo failed %d (%s)\n", ret, gai_strerror(ret));
exit(1);
}

sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == -1) {
printf("socket failed %d (%m)\n", errno);
exit(1);
}

if (tcp_fastopen) {
r = sendto(sock, &msg, msglen, MSG_FASTOPEN, res->ai_addr, res->ai_addrlen);
if (r != msglen)
printf("fastopen sendto returned %d (errno %d)\n", r, errno);
} else {
r = connect(sock, res->ai_addr, res->ai_addrlen);
if (r)
printf("connect returned %d (errno %d)\n", r, errno);
}

if (delay_after_connect) {
sleep(delay_after_connect);
printf("Woken up\n");
}

int i = 0;
while (i++ < 5) {
uint16_t *p = (uint16_t *)msg;
for (int h = 0; h < msglen / sizeof(*p); h++)
*p++ = h + i;
write(sock, msg, msglen / 2);
if ((len = read(sock, buf, msglen - 1)) <= 0) {
printf("read returned %d (%m)\n", errno);
exit(1);
} else
printf("read read %zd bytes %u %u %u %u\n", len, buf[0], buf[1], buf[2], buf[3]);

sleep(1);
}

shutdown(sock, SHUT_WR);
len = read(sock, buf, msglen - 1);
printf("Final read returned %d\n", len);
shutdown(sock, SHUT_RD);
close(sock);
sleep(1);

freeaddrinfo(res);
}
38 changes: 36 additions & 2 deletions test/tcp_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
Expand Down Expand Up @@ -270,14 +271,16 @@ print_usage(FILE *fp, const char *name)
fprintf(fp, "\t-v ver\t\tset HTML version to use (default 1.1)\n");
fprintf(fp, "\t-w url resp\tsend HTTP response for url\n");
fprintf(fp, "\t-W\t\tsend a pre-build HTTP response for GET /\n");
fprintf(fp, "\t-M[mail server name]\t\tbe an email server\n");
fprintf(fp, "\t-M[server_name]\tbe an email server\n");
fprintf(fp, "\t-l val\t\tASCII value to use for EOL char\n");
fprintf(fp, "\t-d delay\tdelay in ms before replying\n");
fprintf(fp, "\t-r\t\tuse random delay\n");
fprintf(fp, "\t-m mod\t\tOnly report every mod'th connection\n");
fprintf(fp, "\t-Z\t\ttoggle close on send (default off)\n");
fprintf(fp, "\t-g\t\tdebug data\n");
fprintf(fp, "\t-G\t\tdebug\n");
fprintf(fp, "\t-f qlen\t\tenable tcp_fastopen\n");
fprintf(fp, "\t-i [len|str]\tsend len bytes or string str immedately after accept\n");
fprintf(fp, "\t-h\t\tprint this\n");
}

Expand All @@ -304,8 +307,12 @@ int main(int argc, char **argv)
unsigned backlog = 4;
bool close_after_send = false;
char *html_version = "1.1";
unsigned tcp_fastopen = 0;
unsigned immediate_data_len;
char *immediate_data = NULL;
bool immediate_data_malloc = false;

while ((opt = getopt(argc, argv, ":h46a:p:sueb:c:l:d:rm:v:WM::w:ZDgG")) != -1) {
while ((opt = getopt(argc, argv, ":h46a:p:sueb:c:l:d:rm:v:WM::w:ZDgGf:i:")) != -1) {
switch (opt) {
case '4':
family = AF_INET;
Expand Down Expand Up @@ -396,6 +403,22 @@ int main(int argc, char **argv)
case 'h':
print_usage(stdout, argv[0]);
exit(0);
case 'f':
tcp_fastopen = strtoul(optarg, &endptr, 10);
break;
case 'i':
if (immediate_data && immediate_data_malloc)
free(immediate_data);
immediate_data_len = strtoul(optarg, &endptr, 10);;
if (!*endptr && immediate_data_len) {
immediate_data = malloc(immediate_data_len);
immediate_data_malloc = true;
} else {
immediate_data = optarg;
immediate_data_len = strlen(immediate_data);
immediate_data_malloc = false;
}
break;
case ':':
fprintf(stderr, "Option '%c' is missing an argument\n", optopt);
break;
Expand Down Expand Up @@ -443,6 +466,13 @@ int main(int argc, char **argv)
exit(1);
}

if (tcp_fastopen) {
if (setsockopt(listenfd, SOL_TCP, TCP_FASTOPEN, &tcp_fastopen, sizeof(tcp_fastopen))) {
printf("(%d) Set TCP_FASTOPEN failed, errno %d (%m)\n", getpid(), errno);
exit(1);
}
}

if (family == AF_INET) {
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
Expand Down Expand Up @@ -487,6 +517,10 @@ int main(int argc, char **argv)
printf("(%d) Received connection %lu\n", getpid(), connection_num);
if ((childpid = fork()) == 0) {
close(listenfd);

if (immediate_data)
write(connfd, immediate_data, immediate_data_len);

if (echo_data || cmd_resp_list || email_server)
process_data(connfd);
else
Expand Down

0 comments on commit 2c081d0

Please sign in to comment.