diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | doc/uanytun.8 | 55 | ||||
-rw-r--r-- | doc/uanytun.8.txt | 50 | ||||
-rw-r--r-- | etc/uanytun/rail-client/config | 91 | ||||
-rw-r--r-- | etc/uanytun/rail-server/config | 91 | ||||
-rw-r--r-- | src/options.c | 8 | ||||
-rw-r--r-- | src/options.h | 1 | ||||
-rw-r--r-- | src/uanytun.c | 11 | ||||
-rw-r--r-- | src/udp.c | 111 | ||||
-rw-r--r-- | src/udp.h | 3 |
10 files changed, 395 insertions, 29 deletions
@@ -1,5 +1,6 @@ -2016.?.? -- Version 0.?.? +201?.??.?? -- Version 0.?.? +* added RAIL mode * moved to GIT 2014.06.21 -- Version 0.3.5 diff --git a/doc/uanytun.8 b/doc/uanytun.8 index 977f3e9..7881569 100644 --- a/doc/uanytun.8 +++ b/doc/uanytun.8 @@ -42,9 +42,10 @@ uanytun \- micro anycast tunneling daemon [ \fB\-L|\-\-log\fR <target>:<level>[,<param1>[,<param2>[\&.\&.]]] ] [ \fB\-U|\-\-debug\fR ] [ \fB\-i|\-\-interface\fR <ip\-address> ] - [ \fB\-p|\-\-port\fR <port> ] + [ \fB\-p|\-\-port\fR <port>[:<port>] ] + [ \fB\-Y|\-\-rail\-mode\fR ] [ \fB\-r|\-\-remote\-host\fR <hostname|ip> ] - [ \fB\-o|\-\-remote\-port\fR <port> ] + [ \fB\-o|\-\-remote\-port\fR <port>[:<port>] ] [ \fB\-4|\-\-ipv4\-only\fR ] [ \fB\-6|\-\-ipv6\-only\fR ] [ \fB\-d|\-\-dev\fR <name> ] @@ -148,9 +149,22 @@ to run in debug mode\&. It implicits This IP address is used as the sender address for outgoing packets\&. The default is to not use a special inteface and just bind on all interfaces\&. .RE .PP -\fB\-p, \-\-port \fR\fB\fI<port>\fR\fR +\fB\-p, \-\-port \fR\fB\fI<port>[:<port>]\fR\fR .RS 4 -The local UDP port that is used to send and receive the payload data\&. The two tunnel endpoints can use different ports\&. default: 4444 +The local UDP port that is used to send and receive the payload data\&. The two tunnel endpoints can use different ports\&. The default port is 4444\&. In +\fBRAIL\fR +mode you must specify a port range\&. See section +\fBRAIL\fR +below to find out what this is\&. +.RE +.PP +\fB\-Y, \-\-rail\-mode\fR +.RS 4 +This option instructs +\fBuAnytun\fR +to run in RAIL mode\&. See section +\fBRAIL\fR +below to find out what this is\&. .RE .PP \fB\-r, \-\-remote\-host \fR\fB\fI<hostname|ip>\fR\fR @@ -158,9 +172,12 @@ The local UDP port that is used to send and receive the payload data\&. The two This option can be used to specify the remote tunnel endpoint\&. In case of anycast tunnel endpoints, the anycast IP address has to be used\&. If you do not specify an address, it is automatically determined after receiving the first data packet\&. .RE .PP -\fB\-o, \-\-remote\-port \fR\fB\fI<port>\fR\fR +\fB\-o, \-\-remote\-port \fR\fB\fI<port>[:<port>]\fR\fR .RS 4 -The UDP port used for payload data by the remote host (specified with \-p on the remote host)\&. If you do not specify a port, it is automatically determined after receiving the first data packet\&. +The UDP port used for payload data by the remote host (specified with \-p on the remote host)\&. If you do not specify a port, it is automatically determined after receiving the first data packet\&. When RAIL mode is enabled the port range must be of the same length as the range defined with +\fB\-p, \-\-port\fR\&. See section +\fBRAIL\fR +below for more information about this mode\&. .RE .PP \fB\-4, \-\-ipv4\-only\fR @@ -368,6 +385,9 @@ The number of bytes to use for the auth tag\&. This value defaults to 10 bytes u \fInull\fR auth algo is used in which case it defaults to 0\&. .RE +.SH "RAIL" +.sp +\fBRAIL\fR stands for Redundant Array of Inexpensive Links\&. Like RAID spreads the blocks of a disk volume over multiple physical disks, \fBRAIL\fR will spread the UDP packets over multiple physical links\&. More precisly for each packet \fBuAnytun\fR reads, from the TUN/TAP device, it will send out multiple UDP packets\&. All of those to the same host but with different destination ports\&. Using policy\-based routing mechanisms these packets can now be seperated and sent out on several interfaces\&. The server\-side will then pick the first of the packets that arrive and discards all others\&. For this to work the size of the sequence window (\fB\-w\fR) must not be set to 0\&. As soon as the server\-side learns the remote endpoints of all or some of the links it will as well send multiple UDP packets for each payload packet\&. .SH "EXAMPLES" .SS "P2P Setup between two unicast enpoints:" .sp @@ -415,6 +435,29 @@ uanytun \-r anycast\&.anytun\&.org \-d anytun0 \-t tun \-n 192\&.0\&.2\&.2/30 \- .sp As \fBuAnytun\fR can\(cqt work as an anycast endpoint it can\(cqt be used for this purpose\&. You have to use \fBAnytun\fR for that job\&. .RE +.SS "Rail Setup for 3 links:" +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBClient:\fR +.RS 4 +.sp +uanytun \-t tun \-n 192\&.168\&.42\&.2/30 \-c aes\-ctr\-256 \-k aes\-ctr\-256 \-E rail_MODE_is_VERY_cool \-e client \-w 64 \-Y \-p 1233:1235 \-r rail\&.example\&.com \-o 4440:4442 +.RE +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBServer:\fR +.RS 4 +.sp +uanytun \-t tun \-n 192\&.168\&.42\&.1/30 \-c aes\-ctr\-256 \-k aes\-ctr\-256 \-E rail_MODE_is_VERY_cool \-e server \-w 64 \-Y \-p 4440:4442 +.RE .SH "BUGS" .sp Most likely there are some bugs in \fBuAnytun\fR\&. If you find a bug, please let the developers know at uanytun@anytun\&.org\&. Of course, patches are preferred\&. diff --git a/doc/uanytun.8.txt b/doc/uanytun.8.txt index ed978d4..5a507ca 100644 --- a/doc/uanytun.8.txt +++ b/doc/uanytun.8.txt @@ -21,9 +21,10 @@ uanytun [ -L|--log <target>:<level>[,<param1>[,<param2>[..]]] ] [ -U|--debug ] [ -i|--interface <ip-address> ] - [ -p|--port <port> ] + [ -p|--port <port>[:<port>] ] + [ -Y|--rail-mode ] [ -r|--remote-host <hostname|ip> ] - [ -o|--remote-port <port> ] + [ -o|--remote-port <port>[:<port>] ] [ -4|--ipv4-only ] [ -6|--ipv6-only ] [ -d|--dev <name> ] @@ -110,10 +111,16 @@ passed to the daemon: packets. The default is to not use a special inteface and just bind on all interfaces. -*-p, --port '<port>'*:: +*-p, --port '<port>[:<port>]'*:: The local UDP port that is used to send and receive the payload data. The two tunnel endpoints can use different - ports. default: 4444 + ports. The default port is 4444. + In *RAIL* mode you must specify a port range. See section + *RAIL* below to find out what this is. + +*-Y, --rail-mode*:: + This option instructs *uAnytun* to run in RAIL mode. See section + *RAIL* below to find out what this is. *-r, --remote-host '<hostname|ip>'*:: This option can be used to specify the remote tunnel @@ -122,11 +129,14 @@ passed to the daemon: an address, it is automatically determined after receiving the first data packet. -*-o, --remote-port '<port>'*:: +*-o, --remote-port '<port>[:<port>]'*:: The UDP port used for payload data by the remote host (specified with -p on the remote host). If you do not specify a port, it is automatically determined after receiving the first data packet. + When RAIL mode is enabled the port range must be of the same length + as the range defined with *-p, --port*. + See section *RAIL* below for more information about this mode. *-4, --ipv4-only*:: Resolv to IPv4 addresses only. The default is to resolv both @@ -248,6 +258,21 @@ passed to the daemon: unless the 'null' auth algo is used in which case it defaults to 0. +RAIL +---- + +*RAIL* stands for Redundant Array of Inexpensive Links. Like RAID spreads +the blocks of a disk volume over multiple physical disks, *RAIL* will spread the +UDP packets over multiple physical links. More precisly for each packet *uAnytun* +reads, from the TUN/TAP device, it will send out multiple UDP packets. All of those to +the same host but with different destination ports. Using policy-based routing mechanisms +these packets can now be seperated and sent out on several interfaces. +The server-side will then pick the first of the packets that arrive and discards all others. +For this to work the size of the sequence window (*-w*) must not be set to 0. +As soon as the server-side learns the remote endpoints of all or some of the links it will +as well send multiple UDP packets for each payload packet. + + EXAMPLES -------- @@ -280,6 +305,21 @@ As *uAnytun* can't work as an anycast endpoint it can't be used for this purpose have to use *Anytun* for that job. +Rail Setup for 3 links: +~~~~~~~~~~~~~~~~~~~~~~~ + +Client: +^^^^^^^ + +uanytun -t tun -n 192.168.42.2/30 -c aes-ctr-256 -k aes-ctr-256 -E rail_MODE_is_VERY_cool + -e client -w 64 -Y -p 1233:1235 -r rail.example.com -o 4440:4442 + +Server: +^^^^^^^ +uanytun -t tun -n 192.168.42.1/30 -c aes-ctr-256 -k aes-ctr-256 -E rail_MODE_is_VERY_cool + -e server -w 64 -Y -p 4440:4442 + + BUGS ---- diff --git a/etc/uanytun/rail-client/config b/etc/uanytun/rail-client/config new file mode 100644 index 0000000..3671eee --- /dev/null +++ b/etc/uanytun/rail-client/config @@ -0,0 +1,91 @@ +############################# +## Main options # +############################# + +role client + +## device type tun = ip/ipv6, tap = ethernet +type tun + +## Automaticaly configure the interface +## the address hast to be supplied in CIDR notation +ifconfig 192.168.42.2/30 + +## payload encryption algorithm +#cipher null +#cipher aes-ctr-128 +#cipher aes-ctr-192 +#cipher aes-ctr-256 +cipher aes-ctr + +## message authentication algorithm +#auth-algo null +auth-algo sha1 + +##message auth tag length +#auth-tag-length 10 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase RAID_is_nice_but_RAIL_is_cooler + +## local ip address to bind to (for tunnel data) +## (if you run an anycast cluster this has to be the anycast ip address) +#interface <ip-address> + +## local port to bind to (for tunnel data) +## the number of ports here must be at least as high as the number of +## remote ports - so in this case up to 5 links may be used +port 8880:8884 + +## The remote host and port (for RAIL a port range is needed) +remote-host rail.example.com +remote-port 8880:8884 + +## enable RAIL mode +rail-mode + +############################# +## Debug options # +############################# + +## don't run in background +#nodaemonize + +## additional log to standard output with a level of 5 +#log stdout:5 + + +############################# +## Expert options # +############################# + +## log to syslog with a level of 3 +log syslog:3,uanytun-rail-client,daemon + +## change user and group after init +#username uanytun +#groupname uanytun + +## chroot to users home directory +#chroot /var/run/uanytun + +## key derivation pseudo random function +#kd-prf null +#kd-prf aes-ctr +#kd-prf aes-ctr-128 +#kd-prf aes-ctr-192 +#kd-prf aes-ctr-256 + +## Device name +dev rail0 + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 0123456789ABCDEF0123456789ABCDEF +#salt 0123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This is needed for RAIL to work +window-size 100 diff --git a/etc/uanytun/rail-server/config b/etc/uanytun/rail-server/config new file mode 100644 index 0000000..0f34557 --- /dev/null +++ b/etc/uanytun/rail-server/config @@ -0,0 +1,91 @@ +############################# +## Main options # +############################# + +role server + +## device type tun = ip/ipv6, tap = ethernet +type tun + +## Automaticaly configure the interface +## the address hast to be supplied in CIDR notation +ifconfig 192.168.42.1/30 + +## payload encryption algorithm +#cipher null +#cipher aes-ctr-128 +#cipher aes-ctr-192 +#cipher aes-ctr-256 +cipher aes-ctr + +## message authentication algorithm +#auth-algo null +auth-algo sha1 + +##message auth tag length +#auth-tag-length 10 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase RAID_is_nice_but_RAIL_is_cooler + +## local ip address to bind to (for tunnel data) +## (if you run an anycast cluster this has to be the anycast ip address) +#interface <ip-address> + +## local port to bind to (for tunnel data) +## the number of ports here must be at least as high as the number of +## remote ports defined at the client configuration (in this case 5) +port 8880:8884 + +## The remote host and port will be learned from the first messages +#remote-host client.unknown +#remote-port 8880:8884 + +## enable RAIL mode +rail-mode + +############################# +## Debug options # +############################# + +## don't run in background +#nodaemonize + +## additional log to standard output with a level of 5 +#log stdout:5 + + +############################# +## Expert options # +############################# + +## log to syslog with a level of 3 +log syslog:3,uanytun-rail-server,daemon + +## change user and group after init +#username uanytun +#groupname uanytun + +## chroot to users home directory +#chroot /var/run/uanytun + +## key derivation pseudo random function +#kd-prf null +#kd-prf aes-ctr +#kd-prf aes-ctr-128 +#kd-prf aes-ctr-192 +#kd-prf aes-ctr-256 + +## Device name +dev rail0 + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 0123456789ABCDEF0123456789ABCDEF +#salt 0123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This is needed for RAIL to work +window-size 100 diff --git a/src/options.c b/src/options.c index c3038bb..015a9a5 100644 --- a/src/options.c +++ b/src/options.c @@ -260,6 +260,7 @@ int options_parse(options_t* opt, int argc, char* argv[]) PARSE_INT_PARAM("-s","--sender-id", opt->sender_id_) PARSE_STRING_LIST("-L","--log", opt->log_targets_) PARSE_BOOL_PARAM("-U", "--debug", opt->debug_) + PARSE_BOOL_PARAM("-Y", "--rail-mode", opt->rail_mode_) PARSE_STRING_PARAM("-r","--remote-host", opt->remote_addr_) PARSE_STRING_PARAM("-o","--remote-port", opt->remote_port_) PARSE_BOOL_PARAM("-4","--ipv4-only", ipv4_only) @@ -361,6 +362,7 @@ void options_default(options_t* opt) opt->local_addr_ = NULL; opt->local_port_ = strdup("4444"); opt->sender_id_ = 0; + opt->rail_mode_ = 0; opt->remote_addr_ = NULL; opt->remote_port_ = strdup("4444"); opt->resolv_addr_type_ = ANY; @@ -447,14 +449,15 @@ void options_print_usage() printf(" [-C|--chroot] <path> chroot to this directory\n"); printf(" [-P|--write-pid] <path> write pid to this file\n"); printf(" [-i|--interface] <ip-address> local ip address to bind to\n"); - printf(" [-p|--port] <port> local port to bind to\n"); + printf(" [-p|--port] <port>[:<port>] local port to bind to (use port:port for range - RAIL)\n"); printf(" [-s|--sender-id ] <sender id> the sender id to use\n"); printf(" [-L|--log] <target>:<level>[,<param1>[,<param2>..]]\n"); printf(" add a log target, can be invoked several times\n"); printf(" [-U|--debug] don't daemonize and log to stdout with maximum log level\n"); + printf(" [-Y|--rail-mode] enable RAIL mode\n"); printf(" [-r|--remote-host] <hostname|ip> remote host\n"); - printf(" [-o|--remote-port] <port> remote port\n"); + printf(" [-o|--remote-port] <port>[:<port>] remote port (use port:port for range - RAIL)\n"); printf(" [-4|--ipv4-only] always resolv IPv4 addresses\n"); printf(" [-6|--ipv6-only] always resolv IPv6 addresses\n"); printf(" [-d|--dev] <name> device name\n"); @@ -507,6 +510,7 @@ void options_print(options_t* opt) printf("local_addr: '%s'\n", opt->local_addr_); printf("local_port: '%s'\n", opt->local_port_); printf("sender_id: %d\n", opt->sender_id_); + printf("rail-mode: %s\n", !opt->rail_mode_ ? "false" : "true"); printf("remote_addr: '%s'\n", opt->remote_addr_); printf("remote_port: '%s'\n", opt->remote_port_); printf("resolv_addr_type: "); diff --git a/src/options.h b/src/options.h index 8f3593f..fa4d554 100644 --- a/src/options.h +++ b/src/options.h @@ -75,6 +75,7 @@ struct options_struct { char* local_addr_; char* local_port_; sender_id_t sender_id_; + int rail_mode_; char* remote_addr_; char* remote_port_; resolv_addr_type_t resolv_addr_type_; diff --git a/src/uanytun.c b/src/uanytun.c index da90eda..c5d6291 100644 --- a/src/uanytun.c +++ b/src/uanytun.c @@ -188,16 +188,21 @@ int process_sock_data(tun_device_t* dev, int fd, udp_t* sock, options_t* opt, pl } #endif + if(sock->rail_mode_) + udp_update_remote(sock, fd, &remote); + int result = seq_win_check_and_add(seq_win, encrypted_packet_get_sender_id(encrypted_packet), encrypted_packet_get_seq_nr(encrypted_packet)); if(result > 0) { - log_printf(WARNING, "detected replay attack, discarding packet"); + if(!(sock->rail_mode_)) + log_printf(WARNING, "detected replay attack, discarding packet"); return 0; } else if(result < 0) { log_printf(ERROR, "memory error at sequence window"); return -2; } - udp_update_remote(sock, fd, &remote); + if(!sock->rail_mode_) + udp_update_remote(sock, fd, &remote); if(encrypted_packet_get_payload_length(encrypted_packet) <= plain_packet_get_header_length()) { log_printf(WARNING, "ignoring packet with zero length payload"); @@ -390,7 +395,7 @@ int main(int argc, char* argv[]) udp_t sock; - ret = udp_init(&sock, opt.local_addr_, opt.local_port_, opt.resolv_addr_type_); + ret = udp_init(&sock, opt.local_addr_, opt.local_port_, opt.resolv_addr_type_, opt.rail_mode_); if(ret) { log_printf(ERROR, "error on udp_init, exitting"); tun_close(&dev); @@ -161,18 +161,53 @@ static int udp_resolv_local(udp_t* sock, const char* local_addr, const char* por return 0; } -int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type) +static int udp_split_port_range(const char* port, const char* colon, u_int32_t* low, u_int32_t* high) +{ + *low = atoi(port); + *high = atoi(colon+1); + if(*low < 1 || *low > 65535 || *high < 1 || *high > 65535 || *high < *low) { + log_printf(ERROR, "illegal port range"); + return -1; + } + return 0; +} + +int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type, int rail_mode) { if(!sock || !port) return -1; sock->socks_ = NULL; sock->active_sock_ = NULL; + sock->rail_mode_ = rail_mode; unsigned int idx = 0; - int ret = udp_resolv_local(sock, local_addr, port, resolv_type, &idx); - if(ret) - return ret; + const char* colon = strchr(port, ':'); + if(!colon) { + int ret = udp_resolv_local(sock, local_addr, port, resolv_type, &idx); + if(ret) + return ret; + } else { + if(!rail_mode) + log_printf(WARNING, "A port range has been defined - enabling RAIL mode"); + sock->rail_mode_ = 1; + + u_int32_t port_num, port_end; + if(udp_split_port_range(port, colon, &port_num, &port_end)) + return -1; + do { + char port_str[10]; + snprintf(port_str, sizeof(port_str), "%d", port_num); + int ret = udp_resolv_local(sock, local_addr, port_str, resolv_type, &idx); + if(ret) + return ret; + + port_num++; + } while(port_num <= port_end); + } + + if(sock->rail_mode_) + log_printf(NOTICE, "RAIL mode enabled"); return 0; } @@ -193,7 +228,7 @@ int udp_fill_fd_set(udp_t* sock, fd_set* set) int udp_has_remote(udp_t* sock) { - if(!sock->active_sock_ || !sock->active_sock_->remote_end_set_) + if(!sock->rail_mode_ && (!sock->active_sock_ || !sock->active_sock_->remote_end_set_)) return 0; udp_socket_t* s = sock->socks_; @@ -206,13 +241,10 @@ int udp_has_remote(udp_t* sock) return 0; } -int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type) +static int udp_resolv_remote__(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type) { struct addrinfo hints, *res; - if(!sock || !remote_addr || !port) - return -1; - res = NULL; memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_DGRAM; @@ -268,6 +300,36 @@ int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, re return 0; } +int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type) +{ + if(!sock || !remote_addr || !port) + return -1; + + const char* colon = strchr(port, ':'); + if(!colon) { + return udp_resolv_remote__(sock, remote_addr, port, resolv_type); + } else { + if(!sock->rail_mode_) + log_printf(WARNING, "A port range has been defined - enabling RAIL mode"); + sock->rail_mode_ = 1; + + u_int32_t port_num, port_end; + if(udp_split_port_range(port, colon, &port_num, &port_end)) + return -1; + do { + char port_str[10]; + snprintf(port_str, sizeof(port_str), "%d", port_num); + int ret = udp_resolv_remote__(sock, remote_addr, port_str, resolv_type); + if(ret) + return ret; + + port_num++; + } while(port_num <= port_end); + } + + return 0; +} + void udp_update_remote(udp_t* sock, int fd, udp_endpoint_t* remote) { if(!sock) @@ -351,10 +413,37 @@ int udp_read(udp_t* sock, int fd, u_int8_t* buf, u_int32_t len, udp_endpoint_t* } -int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len) +static int udp_write_active_sock(udp_t* sock, u_int8_t* buf, u_int32_t len) { - if(!sock || !buf || !sock->active_sock_ || !sock->active_sock_->remote_end_set_) + if(!sock->active_sock_ || !sock->active_sock_->remote_end_set_) return 0; return sendto(sock->active_sock_->fd_, buf, len, 0, (struct sockaddr *)&(sock->active_sock_->remote_end_.addr_), sock->active_sock_->remote_end_.len_); } + +static int udp_write_rail(udp_t* sock, u_int8_t* buf, u_int32_t len) +{ + int i=0; + + udp_socket_t* s = sock->socks_; + while(s) { + if(s->remote_end_set_) { + sendto(s->fd_, buf, len, 0, (struct sockaddr *)&(s->remote_end_.addr_), s->remote_end_.len_); + i++; + } + s = s->next_; + } + + return len; +} + +int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len) +{ + if(!sock || !buf) + return 0; + + if(sock->rail_mode_) + return udp_write_rail(sock, buf, len); + + return udp_write_active_sock(sock, buf, len); +} @@ -72,10 +72,11 @@ typedef struct udp_socket_struct udp_socket_t; struct udp_struct { udp_socket_t* socks_; udp_socket_t* active_sock_; + int rail_mode_; }; typedef struct udp_struct udp_t; -int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type); +int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type, int rail_mode); int udp_fill_fd_set(udp_t* sock, fd_set* set); int udp_has_remote(udp_t* sock); int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type); |