Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce latency caused by TCP delayed ACK #28

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions socketcand.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ int port;
int verbose_flag=0;
int daemon_flag=0;
int disable_beacon=0;
int tcp_quickack_flag=0;
int state = STATE_NO_BUS;
int previous_state = -1;
char bus_name[MAX_BUSNAME];
Expand All @@ -103,6 +104,14 @@ struct sockaddr_un remote_unaddr;
socklen_t remote_unaddrlen;
char* interface_string;

void tcp_quickack(int s)
{
int i = 1;

if (tcp_quickack_flag)
setsockopt(s, IPPROTO_TCP, TCP_QUICKACK, &i, sizeof(int));
}

int state_changed(char *buf, int current_state)
{
if(!strcmp("< rawmode >", buf))
Expand Down Expand Up @@ -233,6 +242,7 @@ int main(int argc, char **argv)
{"verbose", no_argument, 0, 'v'},
{"interfaces", required_argument, 0, 'i'},
{"port", required_argument, 0, 'p'},
{"quick-ack", no_argument, 0, 'q'},
{"afuxname", required_argument, 0, 'u'},
{"listen", required_argument, 0, 'l'},
{"daemon", no_argument, 0, 'd'},
Expand All @@ -242,7 +252,7 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};

c = getopt_long (argc, argv, "vi:p:u:l:dznh", long_options, &option_index);
c = getopt_long (argc, argv, "vi:p:qu:l:dznh", long_options, &option_index);

if (c == -1)
break;
Expand All @@ -268,6 +278,11 @@ int main(int argc, char **argv)
port = atoi(optarg);
break;

case 'q':
PRINT_VERBOSE("TCP_QUICKACK socket option activated\n");
tcp_quickack_flag = 1;
break;

case 'u':
afuxname = realloc(afuxname, strlen(optarg)+1);
strcpy(afuxname, optarg);
Expand Down Expand Up @@ -483,6 +498,7 @@ int main(int argc, char **argv)
if(previous_state != STATE_NO_BUS) {
strcpy(buf, "< hi >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
previous_state = STATE_NO_BUS;
}
/* client has to start with a command */
Expand All @@ -506,18 +522,21 @@ int main(int argc, char **argv)
if(found) {
strcpy(buf, "< ok >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
state = STATE_BCM;
break;
} else {
PRINT_INFO("client tried to access unauthorized bus.\n");
strcpy(buf, "< error could not open bus >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
state = STATE_SHUTDOWN;
}
} else {
PRINT_ERROR("unknown command '%s'.\n", buf);
strcpy(buf, "< error unknown command >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
}
break;

Expand Down Expand Up @@ -554,6 +573,7 @@ int receive_command(int socket, char *buffer) {
*/
if(!more_elements) {
cmd_index += read(socket, cmd_buffer+cmd_index, MAXLEN-cmd_index);
tcp_quickack(client_socket);
#ifdef DEBUG_RECEPTION
PRINT_VERBOSE("\tRead from socket\n");
#endif
Expand Down Expand Up @@ -705,11 +725,12 @@ void determine_adress() {
void print_usage(void) {
printf("%s Version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
printf("Report bugs to %s\n\n", PACKAGE_BUGREPORT);
printf("Usage: socketcand [-v | --verbose] [-i interfaces | --interfaces interfaces]\n\t\t[-p port | --port port] [-l interface | --listen interface]\n\t\t[-u name | --afuxname name] [-n | --no-beacon] [-d | --daemon]\n\t\t[-h | --help]\n\n");
printf("Usage: socketcand [-v | --verbose] [-i interfaces | --interfaces interfaces]\n\t\t[-p port | --port port] [-q | --quick-ack]\n\t\t[-l interface | --listen interface] [-u name | --afuxname name]\n\t\t[-n | --no-beacon] [-d | --daemon] [-h | --help]\n\n");
printf("Options:\n");
printf("\t-v (activates verbose output to STDOUT)\n");
printf("\t-i <interfaces> (comma separated list of SocketCAN interfaces the daemon\n\t\tshall provide access to e.g. '-i can0,vcan1' - default: %s)\n", DEFAULT_BUSNAME);
printf("\t-p <port> (changes the default port '%d' the daemon is listening at)\n", PORT);
printf("\t-q (enable TCP_QUICKACK socket option)\n");
printf("\t-l <interface> (changes the default network interface the daemon will\n\t\tbind to - default: %s)\n", DEFAULT_INTERFACE);
printf("\t-u <name> (the AF_UNIX socket path - abstract name when leading '/' is missing)\n\t\t(N.B. the AF_UNIX binding will supersede the port/interface settings)\n");
printf("\t-n (deactivates the discovery beacon)\n");
Expand Down
1 change: 1 addition & 0 deletions socketcand.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void state_bcm();
void state_raw();
void state_isotp();
void state_control();
void tcp_quickack();

extern int client_socket;
extern char **interface_names;
Expand Down
7 changes: 6 additions & 1 deletion state_bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ void state_bcm() {

snprintf(rxmsg + strlen(rxmsg), RXLEN - strlen(rxmsg), " >");
send(client_socket, rxmsg, strlen(rxmsg), 0);
tcp_quickack(client_socket);
}
} else {
if(msg.msg_head.can_id & CAN_EFF_FLAG) {
Expand All @@ -129,6 +130,7 @@ void state_bcm() {

snprintf(rxmsg + strlen(rxmsg), RXLEN - strlen(rxmsg), " >");
send(client_socket, rxmsg, strlen(rxmsg), 0);
tcp_quickack(client_socket);
}
}

Expand All @@ -152,11 +154,13 @@ void state_bcm() {
close(sc);
strcpy(buf, "< ok >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

if(!strcmp("< echo >", buf)) {
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

Expand Down Expand Up @@ -438,7 +442,7 @@ void state_bcm() {

msg.msg_head.opcode = RX_DELETE;
msg.frame.can_id = msg.msg_head.can_id;

if (!ioctl(sc, SIOCGIFINDEX, &ifr)) {
caddr.can_ifindex = ifr.ifr_ifindex;
sendto(sc, &msg, sizeof(msg), 0,
Expand All @@ -448,6 +452,7 @@ void state_bcm() {
PRINT_ERROR("unknown command '%s'.\n", buf)
strcpy(buf, "< error unknown command >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
}
}
}
3 changes: 3 additions & 0 deletions state_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ void state_control() {
pthread_cancel(statistics_thread);
strcpy(buf, "< ok >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

if(!strcmp("< echo >", buf)) {
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

Expand All @@ -63,5 +65,6 @@ void state_control() {
PRINT_ERROR("unknown command '%s'.\n", buf)
strcpy(buf, "< error unknown command >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
}
}
10 changes: 8 additions & 2 deletions state_isotp.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void state_isotp() {
unsigned char isobuf[ISOTPLEN+1]; /* binary buffer for isotp socket */
unsigned char tmp;
fd_set readfds;

while(previous_state != STATE_ISOTP) {

ret = receive_command(client_socket, buf);
Expand All @@ -55,11 +55,13 @@ void state_isotp() {
previous_state = STATE_ISOTP;
strcpy(buf, "< ok >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

if(!strcmp("< echo >", buf)) {
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
continue;
}

Expand Down Expand Up @@ -135,7 +137,7 @@ void state_isotp() {
state = STATE_SHUTDOWN;
return;
}

/* ok we made it and have a proper isotp socket open */
previous_state = STATE_ISOTP;
}
Expand Down Expand Up @@ -183,6 +185,7 @@ void state_isotp() {

sprintf(rxmsg + strlen(rxmsg), " >");
send(client_socket, rxmsg, strlen(rxmsg), 0);
tcp_quickack(client_socket);
}
}

Expand All @@ -198,11 +201,13 @@ void state_isotp() {
close(si);
strcpy(buf, "< ok >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

if(!strcmp("< echo >", buf)) {
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

Expand Down Expand Up @@ -241,6 +246,7 @@ void state_isotp() {
PRINT_ERROR("unknown command '%s'.\n", buf)
strcpy(buf, "< error unknown command >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
}
}
}
6 changes: 6 additions & 0 deletions state_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ void state_raw() {
canid_t class = frame.can_id & CAN_EFF_MASK;
ret = sprintf(buf, "< error %03X %ld.%06ld >", class, tv.tv_sec, tv.tv_usec);
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
} else if(frame.can_id & CAN_RTR_FLAG) {
/* TODO implement */
} else {
Expand All @@ -133,6 +134,7 @@ void state_raw() {
}
sprintf(buf+ret, " >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
}
}
}
Expand All @@ -146,11 +148,13 @@ void state_raw() {
close(raw_socket);
strcpy(buf, "< ok >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

if(!strcmp("< echo >", buf)) {
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
return;
}

Expand Down Expand Up @@ -191,13 +195,15 @@ void state_raw() {
PRINT_ERROR("unknown command '%s'\n", buf);
strcpy(buf, "< error unknown command >");
send(client_socket, buf, strlen(buf), 0);
tcp_quickack(client_socket);
}
} else {
state = STATE_SHUTDOWN;
return;
}
} else {
ret = read(client_socket, &buf, 0);
tcp_quickack(client_socket);
if(ret==-1) {
state = STATE_SHUTDOWN;
return;
Expand Down
1 change: 1 addition & 0 deletions statistics.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ void *statistics_loop(void *ptr) {

/* no lock needed here because POSIX send is thread-safe and does locking itself */
send( client_socket, buffer, strlen(buffer), 0 );
tcp_quickack(client_socket);

last_fired.tv_sec = current_time.tv_sec;
last_fired.tv_usec = current_time.tv_usec;
Expand Down