diff --git a/doc/sample.config b/doc/sample.config index 5deed8d9..3d50d337 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -173,6 +173,10 @@ ping-leases = false # Setting it higher will improve throughput. output-buffer = 10 +# Set the protocol-defined priority (SO_PRIORITY) for packets to +# be sent. This can be set per user/group or globally. +#net-priority = 3 + route = 192.168.1.0/255.255.255.0 #route = 192.168.5.0/255.255.255.0 diff --git a/src/Makefile.am b/src/Makefile.am index 5e928a46..9131049c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,7 +38,7 @@ ocserv-args.h: ocserv-args.c ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \ ipc.h cookies.c worker-tun.c main-misc.c \ - main-config.c ip-lease.c ip-lease.h \ + group-config.c ip-lease.c ip-lease.h \ vpn.h cookies.h tlslib.h log.c tun.c tun.h \ config.c pam.c pam.h worker-resume.c worker.h main-resume.c main.h \ worker-extras.c main-auth.h html.c html.h \ diff --git a/src/config.c b/src/config.c index 904214a3..bfb85cee 100644 --- a/src/config.c +++ b/src/config.c @@ -79,6 +79,7 @@ static struct cfg_options available_options[] = { { .name = "tls-priorities", .type = OPTION_STRING, .mandatory = 0 }, { .name = "chroot-dir", .type = OPTION_STRING, .mandatory = 0 }, { .name = "mtu", .type = OPTION_NUMERIC, .mandatory = 0 }, + { .name = "net-priority", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "output-buffer", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "cookie-validity", .type = OPTION_NUMERIC, .mandatory = 1 }, { .name = "auth-timeout", .type = OPTION_NUMERIC, .mandatory = 0 }, @@ -317,6 +318,7 @@ unsigned prefix = 0; READ_STRING("chroot-dir", config->chroot_dir); READ_NUMERIC("mtu", config->default_mtu); + READ_NUMERIC("net-priority", config->net_priority); READ_NUMERIC("output-buffer", config->output_buffer); READ_NUMERIC("rx-data-per-sec", config->rx_per_sec); diff --git a/src/main-config.c b/src/group-config.c similarity index 95% rename from src/main-config.c rename to src/group-config.c index 960595b3..9cfe6960 100644 --- a/src/main-config.c +++ b/src/group-config.c @@ -53,6 +53,7 @@ static struct cfg_options available_options[] = { { .name = "ipv6-netmask", .type = OPTION_STRING }, { .name = "rx-data-per-sec", .type = OPTION_NUMERIC, }, { .name = "tx-data-per-sec", .type = OPTION_NUMERIC, }, + { .name = "net-priority", .type = OPTION_NUMERIC, }, }; #define READ_RAW_MULTI_LINE(name, s_name, num) \ @@ -148,6 +149,11 @@ unsigned prefix = 0; READ_RAW_NUMERIC("tx-data-per-sec", config->tx_per_sec); config->rx_per_sec /= 1000; /* in kb */ config->tx_per_sec /= 1000; /* in kb */ + + /* net-priority will contain the actual priority + 1, + * to allow having zero as uninitialized. */ + READ_RAW_NUMERIC("net-priority", config->net_priority); + config->net_priority++; optionUnloadNested(pov); diff --git a/src/main-auth.c b/src/main-auth.c index 72f4b0aa..ef60f451 100644 --- a/src/main-auth.c +++ b/src/main-auth.c @@ -86,7 +86,7 @@ static int send_value_length(main_server_st* s, struct proc_st* proc, const void } static -int serialize_additional_data(main_server_st* s, struct proc_st* proc) +int serialize_additional_config(main_server_st* s, struct proc_st* proc) { int ret; unsigned i; @@ -149,6 +149,11 @@ str_st buffer; if (ret < 0) goto cleanup; + t = proc->config.net_priority; + ret = str_append_data(&buffer, &t, sizeof(t)); + if (ret < 0) + goto cleanup; + /* routes */ len = proc->config.routes_size; ret = str_append_data(&buffer, &len, 1); @@ -244,7 +249,7 @@ int send_auth_reply(main_server_st* s, struct proc_st* proc, mslog(s, proc, LOG_ERR, "auth_reply: write: %s", strerror(e)); } - ret = serialize_additional_data(s, proc); + ret = serialize_additional_config(s, proc); if (ret < 0) return ret; } diff --git a/src/main-misc.c b/src/main-misc.c index 220d9e08..ae55a512 100644 --- a/src/main-misc.c +++ b/src/main-misc.c @@ -247,6 +247,10 @@ unsigned i; proc->config.tx_per_sec = cfg.tx_per_sec; } + if (proc->config.net_priority == 0) { + proc->config.net_priority = cfg.net_priority; + } + del_additional_config(&cfg); } else diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 4ddb2f8f..170bc67b 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -271,6 +271,10 @@ ping-leases = false # Setting it higher will improve throughput. output-buffer = 10 +# Set the protocol-defined priority (SO_PRIORITY) for packets to +# be sent. This can be set per user/group or globally. +#net-priority = 3 + # Routes to be forwarded to the client. If you need the # client to forward routes to the server, you may use the connect # and disconnect scripts. diff --git a/src/vpn.h b/src/vpn.h index 17ddb4db..4b0060b2 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -101,6 +101,8 @@ struct group_cfg_st { size_t rx_per_sec; size_t tx_per_sec; + + unsigned net_priority; }; struct vpn_st { @@ -165,6 +167,7 @@ struct cfg_st { size_t rx_per_sec; size_t tx_per_sec; + unsigned net_priority; unsigned output_buffer; unsigned default_mtu; diff --git a/src/worker-auth.c b/src/worker-auth.c index e593b8a8..b80fd49c 100644 --- a/src/worker-auth.c +++ b/src/worker-auth.c @@ -285,7 +285,7 @@ uint16_t len; } static -int deserialize_additional_data(worker_st* ws) +int deserialize_additional_config(worker_st* ws) { int ret; unsigned i; @@ -347,6 +347,12 @@ uint32_t t; ws->tx_per_sec = t; + ret = str_read_data(&b, &t, sizeof(t)); + if (ret < 0) + goto cleanup; + + ws->net_priority = t; + ws->routes_size = b.data[0]; b.length--; b.data++; @@ -443,7 +449,7 @@ static int recv_auth_reply(worker_st *ws, struct cmd_auth_reply_msg_st* mresp) /* Read any additional data */ - ret = deserialize_additional_data(ws); + ret = deserialize_additional_config(ws); if (ret < 0) { oclog(ws, LOG_ERR, "recv_auth_reply: deserialize failed"); return ERR_AUTH_FAIL; diff --git a/src/worker-vpn.c b/src/worker-vpn.c index a1312b91..eb370e44 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -791,6 +791,7 @@ unsigned tls_pending, dtls_pending = 0, i; time_t udp_recv_time = 0, now; struct timespec tnow; unsigned mtu_overhead = 0; +int sndbuf; socklen_t sl; bandwidth_st b_tx; bandwidth_st b_rx; @@ -850,6 +851,14 @@ bandwidth_st b_rx; alarm(0); http_req_deinit(ws); + /* set defaults */ + if (ws->rx_per_sec == 0) + ws->rx_per_sec = ws->config->rx_per_sec; + if (ws->tx_per_sec == 0) + ws->tx_per_sec = ws->config->tx_per_sec; + if (ws->net_priority == 0) + ws->net_priority = ws->config->net_priority; + tls_cork(ws->session); ret = tls_puts(ws->session, "HTTP/1.1 200 CONNECTED\r\n"); SEND_ERR(ret); @@ -915,7 +924,6 @@ bandwidth_st b_rx; } } - for (i=0;ino_ipv6 != 0 && strchr(vinfo.routes[i], ':') != 0) continue; @@ -983,8 +991,22 @@ bandwidth_st b_rx; ws->conn_mtu = MIN(ws->conn_mtu, max-mtu_overhead); } + /* set TCP socket options */ + if (ws->config->output_buffer > 0) { + sndbuf = ws->conn_mtu * ws->config->output_buffer; + ret = setsockopt( ws->conn_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); + if (ret == -1) + oclog(ws, LOG_DEBUG, "setsockopt(TCP, SO_SNDBUF) to %u, failed.", sndbuf); + } + + if (ws->net_priority != 0) { + l = ws->net_priority - 1; + ret = setsockopt( ws->conn_fd, SOL_SOCKET, SO_PRIORITY, &l, sizeof(l)); + if (ret == -1) + oclog(ws, LOG_DEBUG, "setsockopt(TCP, SO_PRIORITY) to %d, failed.", l); + } + if (ws->udp_state != UP_DISABLED) { - int sndbuf; p = (char*)ws->buffer; for (i=0;isession_id);i++) { @@ -1032,6 +1054,15 @@ bandwidth_st b_rx; if (ws->config->output_buffer > 0) { sndbuf = ws->conn_mtu * ws->config->output_buffer; setsockopt( ws->udp_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); + if (ret == -1) + oclog(ws, LOG_DEBUG, "setsockopt(UDP, SO_SNDBUF) to %u, failed.", sndbuf); + } + + if (ws->net_priority != 0) { + l = ws->net_priority - 1; + ret = setsockopt( ws->udp_fd, SOL_SOCKET, SO_PRIORITY, &l, sizeof(l)); + if (ret == -1) + oclog(ws, LOG_DEBUG, "setsockopt(UDP, SO_PRIORITY) to %d, failed.", l); } } else dtls_mtu = 0; @@ -1071,11 +1102,6 @@ bandwidth_st b_rx; gettime(&tnow); ws->last_msg_tcp = ws->last_msg_udp = tnow.tv_sec; - if (ws->rx_per_sec == 0) - ws->rx_per_sec = ws->config->rx_per_sec; - if (ws->tx_per_sec == 0) - ws->tx_per_sec = ws->config->tx_per_sec; - bandwidth_init(&b_rx, ws->rx_per_sec); bandwidth_init(&b_tx, ws->tx_per_sec); diff --git a/src/worker.h b/src/worker.h index 89de80ac..b58a8d06 100644 --- a/src/worker.h +++ b/src/worker.h @@ -151,6 +151,7 @@ typedef struct worker_st { size_t rx_per_sec; size_t tx_per_sec; + unsigned net_priority; struct http_req_st req; } worker_st;