Skip to content
Browse files

Merge remote-tracking branch 'tcprelay/master'

Conflicts:
	Makefile
	main.c
	parse_argv.c
  • Loading branch information...
2 parents 9ac6624 + b8648bf commit 379e6fd2aa3f4777d170051b864b0b878d32e969 @vi committed Nov 10, 2011
Showing with 142 additions and 102 deletions.
  1. +2 −2 Makefile
  2. +4 −1 bump_quotas.c
  3. +3 −1 close_fd.c
  4. +3 −2 epoll_update.c
  5. +2 −1 listen_socket_and_setup_epoll.c
  6. +6 −88 main.c
  7. +103 −0 main.h
  8. +2 −1 parse_argv.c
  9. +2 −1 process_accept.c
  10. +5 −0 process_debt.c
  11. +2 −1 process_read.c
  12. +5 −3 process_stdin.c
  13. +3 −1 update_rates.c
View
4 Makefile
@@ -1,7 +1,7 @@
all: tcplim
-tcplim: *.c VERSION
- gcc -O2 -g3 main.c -o tcplim
+tcplim: *.c *.h VERSION
+ gcc -O2 -g3 *.c -o tcplim
githead=$(wildcard .git/HEAD)
View
5 bump_quotas.c
@@ -1,3 +1,6 @@
+#include <limits.h>
+#include "main.h"
+
int cmp_fds(const void* en1, const void* en2) {
int e1 = *(const int*)en1, e2 = *(const int*)en2;
if(e1==e2) return 0;
@@ -10,7 +13,7 @@ int cmp_fds(const void* en1, const void* en2) {
return 0;
}
-static void bump_quotas(int milliseconds) {
+void bump_quotas(int milliseconds) {
quotas_are_full = 1;
dpf("Bumping quotas for %d milliseconds\n", milliseconds);
int fd,i;
View
4 close_fd.c
@@ -1,4 +1,6 @@
-static void close_fd(int fd) {
+#include "main.h"
+
+void close_fd(int fd) {
dpf("Closing requested for %d and %d\n", fd, fdinfo[fd].peerfd);
if(fdinfo[fd].status==0 || fdinfo[fd].peerfd==0) {
fprintf(stderr, "%d is not valid fd to close\n", fd);
View
5 epoll_update.c
@@ -1,13 +1,14 @@
+#include "main.h"
/* These are debug messages */
-static const char* __attribute__((unused)) epoll_update_msgs[] = {
+const char* __attribute__((unused)) epoll_update_msgs[] = {
" setting up %d to listen only for error events\n",
" setting up %d to listen for read events\n",
" setting up %d to listen for write events\n",
" setting up %d to listen for read and write events\n"};
-static void epoll_update(int fd) {
+void epoll_update(int fd) {
struct epoll_event ev;
memset(&ev, 0, sizeof ev);
ev.events = EPOLLONESHOT;
View
3 listen_socket_and_setup_epoll.c
@@ -1,5 +1,6 @@
+#include "main.h"
-static void listen_socket_and_setup_epoll() {
+void listen_socket_and_setup_epoll() {
/* Open the server side socket */
ss = socket(PF_INET, SOCK_STREAM, 0);
if (ss == -1) {
View
94 main.c
@@ -10,75 +10,14 @@
* It also supports retrieving destination address with SO_ORIGINAL_DST
*/
-#include <stdio.h>
-#include <sys/epoll.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <stdarg.h>
-
-#define MAXFD 1024 /* Not checked for overflow anywhere */
-#define BUFSIZE 65536
-#define MAX_EPOLL_EVENTS_AT_ONCE 1024 /* even 1 should work more-or-less fine */
-
-static int debug_output;
-
-void dpf(const char *fmt, ...) {
- if (!debug_output) {
- return;
- }
+#include "main.h"
- va_list argp;
- va_start(argp, fmt);
- vfprintf(stderr, fmt, argp);
- va_end(argp);
-}
+struct fdinfo_t fdinfo[MAXFD] = { [0 ... MAXFD - 1] = {0, 0, 0}};
-struct {
- int peerfd; // where we connected by client's request (and vice versa). You'll see fdinfo[fd].peerfd frequently in the code.
- char writeready; // epoll said that we can write here
- char readready; // epoll said that we can read from here
- char we_should_epoll_for_reads;
- char we_should_epoll_for_writes;
- char status;
- /*
- States:
- | - bidirectional connected peer
- s - we can only send (half-shutdown)
- r - we can only recv (half-shutdown)
- . - closed
- */
- char group;
- /*
- Groups:
- c - incoming connection
- d - outgoing connection
- */
- struct sockaddr_in address;
- char* buff; // "inbox", allocated only in case of a short write to this socket.
- int debt; // length of buff.
- long long total_read;
-
- long long total_read_last;
- int rate;
-
- int current_quota;
- int speed_limit;
- int nice; /* less == more priority. Negative == exempt from total quota */
- struct timeval last_quota_bump_time; /* We sort first by nice, then by last_access_time */
-
-} static fdinfo[MAXFD] = { [0 ... MAXFD - 1] = {0, 0, 0}};
-
-
-static int kdpfd; /* epoll fd */
-static int ss; /* server socket */
+int debug_output;
+int kdpfd; /* epoll fd */
+int ss; /* server socket */
const char *bind_ip;
int bind_port;
@@ -98,28 +37,6 @@ int quotas_are_full; /* if all quota buffers are not drained, we can epoll_wait
struct timeval time_last;
-static void parse_argv(int argc, char* argv[]);
-static void process_read(int fd); // we are both able to read from fd and write to fdinfo[fd].peerfd
-static void process_debt(int fd); // previous process_read to peer fd had problems (short/missing write to this fd). Now we can finish it.
-static void process_accept(int ss); // new client connects. Need to connect to the peer, set up epoll, setup fdinfo.
-static void listen_socket_and_setup_epoll(); // setup main socket to listen (and add it to epoll)
-static void close_fd(int fd); // close both fd and peer fd. Clean up debt buffers and fdinfo states.
-static void epoll_update(int fd); // call epoll_ctl for this fd accroding to we_should_epoll_for_* fields.
-static void print_connection(int fd, const char* prologue, const char* epilogue);
-static void process_stdin();
-static void bump_quotas(int milliseconds);
-static void update_rates(int milliseconds);
-#include "process_read.c"
-#include "process_debt.c"
-#include "process_accept.c"
-#include "parse_argv.c"
-#include "listen_socket_and_setup_epoll.c"
-#include "close_fd.c"
-#include "epoll_update.c"
-#include "process_stdin.c"
-#include "bump_quotas.c"
-#include "update_rates.c"
-
int main(int argc, char *argv[])
{
@@ -241,3 +158,4 @@ int main(int argc, char *argv[])
fprintf(stderr, "Probably abnormal termination\n");
}
+
View
103 main.h
@@ -0,0 +1,103 @@
+#ifndef MAIN_H
+#define MAIN_H
+
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <stdarg.h>
+
+#define MAXFD 1024 /* Not checked for overflow anywhere */
+#define BUFSIZE 65536
+#define MAX_EPOLL_EVENTS_AT_ONCE 1024 /* even 1 should work more-or-less fine */
+
+extern int debug_output;
+
+static inline void dpf(const char *fmt, ...) {
+ if (!debug_output) {
+ return;
+ }
+
+ va_list argp;
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+}
+
+
+extern struct fdinfo_t {
+ int peerfd; // where we connected by client's request (and vice versa). You'll see fdinfo[fd].peerfd frequently in the code.
+ char writeready; // epoll said that we can write here
+ char readready; // epoll said that we can read from here
+ char we_should_epoll_for_reads;
+ char we_should_epoll_for_writes;
+ char status;
+ /*
+ States:
+ | - bidirectional connected peer
+ s - we can only send (half-shutdown)
+ r - we can only recv (half-shutdown)
+ . - closed
+ */
+ char group;
+ /*
+ Groups:
+ c - incoming connection
+ d - outgoing connection
+ */
+ struct sockaddr_in address;
+ char* buff; // "inbox", allocated only in case of a short write to this socket.
+ int debt; // length of buff.
+ long long total_read;
+
+ long long total_read_last;
+ int rate;
+
+ int current_quota;
+ int speed_limit;
+ int nice; /* less == more priority. Negative == exempt from total quota */
+ struct timeval last_quota_bump_time; /* We sort first by nice, then by last_access_time */
+
+} fdinfo[MAXFD];
+
+
+extern int kdpfd; /* epoll fd */
+extern int ss; /* server socket */
+
+extern const char *bind_ip;
+extern int bind_port;
+extern const char *connect_ip;
+extern int connect_port;
+
+extern int need_address_redirection;
+extern int need_port_redirection;
+
+extern int total_upload_limit;
+extern int total_download_limit;
+extern int fd_upload_limit;
+extern int fd_download_limit;
+extern int timetick;
+
+int quotas_are_full; /* if all quota buffers are not drained, we can epoll_wait without a timeout */
+struct timeval time_last;
+
+void parse_argv(int argc, char* argv[]);
+void process_read(int fd); // we are both able to read from fd and write to fdinfo[fd].peerfd
+void process_debt(int fd); // previous process_read to peer fd had problems (short/missing write to this fd). Now we can finish it.
+void process_accept(int ss); // new client connects. Need to connect to the peer, set up epoll, setup fdinfo.
+void listen_socket_and_setup_epoll(); // setup main socket to listen (and add it to epoll)
+void close_fd(int fd); // close both fd and peer fd. Clean up debt buffers and fdinfo states.
+void epoll_update(int fd); // call epoll_ctl for this fd accroding to we_should_epoll_for_* fields.
+void print_connection(int fd, const char* prologue, const char* epilogue);
+void process_stdin();
+void bump_quotas(int milliseconds);
+void update_rates(int milliseconds);
+
+#endif // MAIN_H
View
3 parse_argv.c
@@ -1,7 +1,8 @@
#include <limits.h>
#include "VERSION"
+#include "main.h"
-static void parse_argv(int argc, char* argv[]) {
+void parse_argv(int argc, char* argv[]) {
if (getenv("DEBUG")) {
debug_output = 1;
} else {
View
3 process_accept.c
@@ -1,5 +1,6 @@
+#include "main.h"
-static void process_accept(int ss) {
+void process_accept(int ss) {
/* Accepting the client socket */
struct sockaddr_in sa, da;
struct epoll_event ev;
View
5 process_debt.c
@@ -1,3 +1,4 @@
+#include "main.h"
/* TODO: too many common code with process_read */
@@ -40,6 +41,10 @@ void process_debt(int fd) {
free(fdinfo[fd].buff);
fdinfo[fd].buff = b;
fdinfo[fd].debt = l;
+
+ fdinfo[fd].we_should_epoll_for_writes=1;
+ epoll_update(fd);
+
dpf(" re-stored debt %d for %d\n", l, fd);
} else {
/* Now the debt is fulfilled */
View
3 process_read.c
@@ -1,5 +1,6 @@
+#include "main.h"
-static void process_read(int fd) {
+void process_read(int fd) {
dpf("Selecting %d for reading. Peer is %d.\n", fd, fdinfo[fd].peerfd);
char buf[BUFSIZE];
ssize_t ret, ret2;
View
8 process_stdin.c
@@ -1,4 +1,6 @@
-static void print_connection(int fd, const char* prologue, const char* epilogue) {
+#include "main.h"
+
+void print_connection(int fd, const char* prologue, const char* epilogue) {
int peerfd = fdinfo[fd].peerfd;
printf("%s%s:%d -> ",
@@ -32,7 +34,7 @@ static void print_connection(int fd, const char* prologue, const char* epilogue)
printf("%s", epilogue);
}
-static void list_connections() {
+void list_connections() {
int fd;
for(fd=0; fd<MAXFD; ++fd) {
if(fdinfo[fd].status == 0 || fdinfo[fd].status == '.') {
@@ -46,7 +48,7 @@ static void list_connections() {
}
}
-static void process_stdin() {
+void process_stdin() {
dpf("processing stdin\n");
char cmd[256]={0};
char arg[256]={0};
View
4 update_rates.c
@@ -1,5 +1,7 @@
+#include "main.h"
-static void update_rates(int milliseconds) {
+
+void update_rates(int milliseconds) {
int fd;
for (fd=0; fd<MAXFD; ++fd) {
fdinfo[fd].rate = (fdinfo[fd].total_read - fdinfo[fd].total_read_last) * 1000LL / milliseconds;

0 comments on commit 379e6fd

Please sign in to comment.
Something went wrong with that request. Please try again.