config available ports, iana assigned ports list.

git-svn-id: file:///svn/unbound/trunk@1025 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-04-09 15:07:37 +00:00
parent 7eeb7cc78c
commit f0cf79146c
12 changed files with 4162 additions and 746 deletions

View file

@ -108,6 +108,9 @@ checkrlimits(struct config_file* cfg)
size_t total = numthread * perthread + misc;
size_t avail;
struct rlimit rlim;
verbose(VERB_ALGO, "%d ports available in config",
cfg_scan_ports(cfg->outgoing_avail_ports, 65536));
if(getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
log_warn("getrlimit: %s", strerror(errno));
return;

View file

@ -4,6 +4,9 @@
libev-3.2 is a little faster than libevent-1.4.3-stable (about 5%).
- unused commpoints not listed in epoll list.
- statistics-cumulative option so that the values are not reset.
- config creates array of available ports, 61841 available,
it excludes <1024 and iana assigned numbers.
config statements to modify the available port numbers.
8 April 2008: Wouter
- unbound tries to set the ulimit fds when started as server.

View file

@ -58,6 +58,14 @@ server:
# spoof attacks, as it gets harder to guess which port is used.
# But also takes more system resources (for open sockets).
# outgoing-range: 256
# permit unbound to use this port number or port range for
# making outgoing queries, using an outgoing interface.
# outgoing-port-permit: 32768
# deny unbound the use this of port number or port range for
# making outgoing queries, using an outgoing interface.
# outgoing-port-avoid: "3200-3208"
# number of outgoing simultaneous tcp buffers to hold per thread.
# outgoing-num-tcp: 10

View file

@ -132,6 +132,19 @@ query interface. Must be at least 1. Default is 256.
Larger numbers give more protection against spoofing attempts, but need
extra resources from the operating system.
.TP
.B outgoing\-port\-permit: \fI<port number or range>
Permit unbound to open this port or range of ports for use to send queries.
Make sure these ports are not needed by other daemons. By default only
ports above 1024 that have not been assigned by IANA are used.
Give a port number or a range of the form "low-high", without spaces.
.TP
.B outgoing\-port\-avoid: \fI<port number or range>
Do not permit unbound to open this port or range of ports for use to send
queries. Use this to make sure unbound does not grab a port that another
daemon needs. The port is avoided on all outgoing interfaces, both IP4 and IP6.
By default only ports above 1024 that have not been assigned by IANA are used.
Give a port number or a range of the form "low-high", without spaces.
.TP
.B outgoing\-num\-tcp: \fI<number>
Number of outgoing TCP buffers to allocate per thread. Default is 10. If set
to 0, or if do_tcp is "no", no TCP queries to authoritative servers are done.

View file

@ -61,6 +61,9 @@ int ub_c_wrap(void);
/** print error with file and line number */
void ub_c_error(const char *message);
/** init ports possible for use */
static void init_outgoing_availports(int* array, int num);
struct config_file*
config_create()
{
@ -96,6 +99,9 @@ config_create()
cfg->infra_cache_slabs = 4;
cfg->infra_cache_numhosts = 10000;
cfg->infra_cache_lame_size = 10240; /* easily 40 or more entries */
if(!(cfg->outgoing_avail_ports = (int*)calloc(65536, sizeof(int))))
goto error_exit;
init_outgoing_availports(cfg->outgoing_avail_ports, 65536);
if(!(cfg->username = strdup("unbound"))) goto error_exit;
if(!(cfg->chrootdir = strdup(CHROOT_DIR))) goto error_exit;
if(!(cfg->directory = strdup(RUN_DIR))) goto error_exit;
@ -434,6 +440,7 @@ config_delete(struct config_file* cfg)
free(cfg->identity);
free(cfg->version);
free(cfg->module_conf);
free(cfg->outgoing_avail_ports);
config_delstrlist(cfg->trust_anchor_file_list);
config_delstrlist(cfg->trusted_keys_file_list);
config_delstrlist(cfg->trust_anchor_list);
@ -445,6 +452,80 @@ config_delete(struct config_file* cfg)
free(cfg);
}
static void
init_outgoing_availports(int* a, int num)
{
/* generated with
grep "/udp" /etc/services | awk '{print $2;}' | sed -e 's?/udp??' | sort -n | grep -v 0 | sed -e 's/^\(.*\)$/\1,/' > util/iana_ports.inc
*/
const int iana_assigned[] = {
#include "util/iana_ports.inc"
0 }; /* trailing 0 to put behind trailing comma */
int i;
/* do not use <1024, that could be trouble with the system, privs */
for(i=1024; i<num; i++) {
a[i] = i;
}
/* pick out all the IANA assigned ports */
for(i=0; iana_assigned[i]; i++) {
if(iana_assigned[i] < num)
a[iana_assigned[i]] = 0;
}
}
int
cfg_mark_ports(const char* str, int allow, int* avail, int num)
{
char* mid = strchr(str, '-');
if(!mid) {
int port = atoi(str);
if(port == 0 && strcmp(str, "0") != 0) {
log_err("cannot parse port number '%s'", str);
return 0;
}
if(port < num)
avail[port] = (allow?port:0);
} else {
int i, low, high = atoi(mid+1);
char buf[16];
if(high == 0 && strcmp(mid+1, "0") != 0) {
log_err("cannot parse port number '%s'", mid+1);
return 0;
}
if( (int)(mid-str)+1 >= (int)sizeof(buf) ) {
log_err("cannot parse port number '%s'", str);
return 0;
}
if(mid > str)
memcpy(buf, str, (size_t)(mid-str));
buf[mid-str] = 0;
low = atoi(buf);
if(low == 0 && strcmp(buf, "0") != 0) {
log_err("cannot parse port number '%s'", buf);
return 0;
}
for(i=low; i<=high; i++) {
if(i < num)
avail[i] = (allow?i:0);
}
return 1;
}
return 1;
}
int
cfg_scan_ports(int* avail, int num)
{
int i;
int count = 0;
for(i=0; i<num; i++) {
if(avail[i])
count++;
}
return count;
}
/** print error with file and line number */
void ub_c_error_va_list(const char *fmt, va_list args)
{

View file

@ -80,6 +80,8 @@ struct config_file {
size_t outgoing_num_tcp;
/** number of incoming tcp buffers per (per thread) */
size_t incoming_num_tcp;
/** allowed udp port numbers, array with 0 if not allowed */
int* outgoing_avail_ports;
/** number of bytes buffer size for DNS messages */
size_t msg_buffer_size;
@ -353,6 +355,25 @@ int cfg_count_numbers(const char* str);
*/
int cfg_parse_memsize(const char* str, size_t* res);
/**
* Mark "number" or "low-high" as available or not in ports array.
* @param str: string in input
* @param allow: give true if this range is permitted.
* @param avail: the array from cfg.
* @param num: size of the array (65536).
* @return: true if parsed correctly, or 0 on a parse error (and an error
* is logged).
*/
int cfg_mark_ports(const char* str, int allow, int* avail, int num);
/**
* Scan ports available
* @param avail: the array from cfg.
* @param num: size of the array (65536).
* @return the number of ports available for use.
*/
int cfg_scan_ports(int* avail, int num);
/**
* Used during options parsing
*/

File diff suppressed because it is too large Load diff

View file

@ -105,6 +105,8 @@ verbosity{COLON} { YDOUT; return VAR_VERBOSITY;}
port{COLON} { YDOUT; return VAR_PORT;}
outgoing-port{COLON} { YDOUT; return VAR_OUTGOING_PORT;}
outgoing-range{COLON} { YDOUT; return VAR_OUTGOING_RANGE;}
outgoing-port-permit{COLON} { YDOUT; return VAR_OUTGOING_PORT_PERMIT;}
outgoing-port-avoid{COLON} { YDOUT; return VAR_OUTGOING_PORT_AVOID;}
outgoing-num-tcp{COLON} { YDOUT; return VAR_OUTGOING_NUM_TCP;}
incoming-num-tcp{COLON} { YDOUT; return VAR_INCOMING_NUM_TCP;}
do-ip4{COLON} { YDOUT; return VAR_DO_IP4;}

File diff suppressed because it is too large Load diff

View file

@ -116,7 +116,9 @@
VAR_STATISTICS_INTERVAL = 332,
VAR_DO_DAEMONIZE = 333,
VAR_USE_CAPS_FOR_ID = 334,
VAR_STATISTICS_CUMULATIVE = 335
VAR_STATISTICS_CUMULATIVE = 335,
VAR_OUTGOING_PORT_PERMIT = 336,
VAR_OUTGOING_PORT_AVOID = 337
};
#endif
/* Tokens. */
@ -198,6 +200,8 @@
#define VAR_DO_DAEMONIZE 333
#define VAR_USE_CAPS_FOR_ID 334
#define VAR_STATISTICS_CUMULATIVE 335
#define VAR_OUTGOING_PORT_PERMIT 336
#define VAR_OUTGOING_PORT_AVOID 337
@ -209,7 +213,7 @@ typedef union YYSTYPE
char* str;
}
/* Line 1489 of yacc.c. */
#line 213 "util/configparser.h"
#line 217 "util/configparser.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1

View file

@ -89,7 +89,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_CACHE_MAX_TTL VAR_HARDEN_DNNSEC_STRIPPED VAR_ACCESS_CONTROL
%token VAR_LOCAL_ZONE VAR_LOCAL_DATA VAR_INTERFACE_AUTOMATIC
%token VAR_STATISTICS_INTERVAL VAR_DO_DAEMONIZE VAR_USE_CAPS_FOR_ID
%token VAR_STATISTICS_CUMULATIVE
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
%token VAR_OUTGOING_PORT_AVOID
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -130,7 +131,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_harden_dnssec_stripped | server_access_control |
server_local_zone | server_local_data | server_interface_automatic |
server_statistics_interval | server_do_daemonize |
server_use_caps_for_id | server_statistics_cumulative
server_use_caps_for_id | server_statistics_cumulative |
server_outgoing_port_permit | server_outgoing_port_avoid
;
stubstart: VAR_STUB_ZONE
{
@ -257,6 +259,24 @@ server_outgoing_range: VAR_OUTGOING_RANGE STRING
free($2);
}
;
server_outgoing_port_permit: VAR_OUTGOING_PORT_PERMIT STRING
{
OUTYY(("P(server_outgoing_port_permit:%s)\n", $2));
if(!cfg_mark_ports($2, 1,
cfg_parser->cfg->outgoing_avail_ports, 65536))
yyerror("port number or range (\"low-high\") expected");
free($2);
}
;
server_outgoing_port_avoid: VAR_OUTGOING_PORT_AVOID STRING
{
OUTYY(("P(server_outgoing_port_avoid:%s)\n", $2));
if(!cfg_mark_ports($2, 0,
cfg_parser->cfg->outgoing_avail_ports, 65536))
yyerror("port number or range (\"low-high\") expected");
free($2);
}
;
server_outgoing_num_tcp: VAR_OUTGOING_NUM_TCP STRING
{
OUTYY(("P(server_outgoing_num_tcp:%s)\n", $2));

3209
util/iana_ports.inc Normal file

File diff suppressed because it is too large Load diff