summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ouroboros/ipcp.h3
-rw-r--r--src/ipcpd/ipcp.c3
-rw-r--r--src/ipcpd/udp/main.c226
-rw-r--r--src/lib/ipcp_config.proto7
-rw-r--r--src/lib/irm.c6
-rw-r--r--src/tools/irm/irm_ipcp_bootstrap.c20
6 files changed, 85 insertions, 180 deletions
diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h
index 29ca42fc..53b166da 100644
--- a/include/ouroboros/ipcp.h
+++ b/include/ouroboros/ipcp.h
@@ -91,8 +91,7 @@ struct ipcp_config {
/* UDP */
uint32_t ip_addr;
uint32_t dns_addr;
- uint16_t clt_port;
- uint16_t srv_port;
+ uint16_t port;
/* Ethernet */
char * dev;
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index 7be946dc..838ecda0 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -252,8 +252,7 @@ static void * mainloop(void * o)
case IPCP_UDP:
conf.ip_addr = conf_msg->ip_addr;
conf.dns_addr = conf_msg->dns_addr;
- conf.clt_port = conf_msg->clt_port;
- conf.srv_port = conf_msg->srv_port;
+ conf.port = conf_msg->port;
conf.layer_info.dir_hash_algo = HASH_MD5;
layer_info.dir_hash_algo = HASH_MD5;
break;
diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/main.c
index dba831ff..4314b330 100644
--- a/src/ipcpd/udp/main.c
+++ b/src/ipcpd/udp/main.c
@@ -67,10 +67,8 @@
#define DNS_TTL 86400
#define FD_UPDATE_TIMEOUT 100 /* microseconds */
-#define SERV_PORT udp_data.s_saddr.sin_port;
-#define SERV_SADDR ((struct sockaddr *) &udp_data.s_saddr)
-#define CLNT_SADDR ((struct sockaddr *) &udp_data.c_saddr)
-#define SERV_SADDR_SIZE (sizeof(udp_data.s_saddr))
+#define SADDR ((struct sockaddr *) &udp_data.s_saddr)
+#define SADDR_SIZE (sizeof(udp_data.s_saddr))
#define LOCAL_IP (udp_data.s_saddr.sin_addr.s_addr)
#define MGMT_EID 0
@@ -106,20 +104,17 @@ struct mgmt_frame {
/* UDP flow */
struct uf {
- int d_eid;
- /* IP details are stored through connect(). */
- int skfd;
+ int d_eid;
+ struct sockaddr_in r_saddr;
};
struct {
struct shim_data * shim_data;
uint32_t dns_addr;
- /* server socket */
+
struct sockaddr_in s_saddr;
int s_fd;
- /* client port */
- int clt_port;
fset_t * np1_flows;
struct uf fd_to_uf[SYS_MAX_FLOWS];
@@ -148,10 +143,8 @@ static int udp_data_init(void)
if (pthread_mutex_init(&udp_data.mgmt_lock, NULL))
goto fail_mgmt_lock;
- for (i = 0; i < SYS_MAX_FLOWS; ++i) {
- udp_data.fd_to_uf[i].skfd = -1;
+ for (i = 0; i < SYS_MAX_FLOWS; ++i)
udp_data.fd_to_uf[i].d_eid = -1;
- }
udp_data.np1_flows = fset_create();
if (udp_data.np1_flows == NULL)
@@ -187,12 +180,12 @@ static void udp_data_fini(void)
pthread_mutex_destroy(&udp_data.mgmt_lock);
}
-static int ipcp_udp_port_alloc(int skfd,
- uint32_t s_eid,
- const uint8_t * dst,
- qosspec_t qs,
- const void * data,
- size_t dlen)
+static int ipcp_udp_port_alloc(const struct sockaddr_in * r_saddr,
+ uint32_t s_eid,
+ const uint8_t * dst,
+ qosspec_t qs,
+ const void * data,
+ size_t dlen)
{
uint8_t * buf;
struct mgmt_msg * msg;
@@ -222,7 +215,9 @@ static int ipcp_udp_port_alloc(int skfd,
memcpy(msg + 1, dst, ipcp_dir_hash_len());
memcpy(buf + len, data, dlen);
- if (write(skfd, msg, len + dlen) < 0) {
+ if (sendto(udp_data.s_fd, msg, len + dlen,
+ MSG_CONFIRM,
+ (const struct sockaddr *) r_saddr, sizeof(*r_saddr)) < 0) {
free(buf);
return -1;
}
@@ -232,14 +227,14 @@ static int ipcp_udp_port_alloc(int skfd,
return 0;
}
-static int ipcp_udp_port_alloc_resp(int skfd,
- uint32_t s_eid,
- uint32_t d_eid,
- int8_t response,
- const void * data,
- size_t len)
+static int ipcp_udp_port_alloc_resp(const struct sockaddr_in * r_saddr,
+ uint32_t s_eid,
+ uint32_t d_eid,
+ int8_t response,
+ const void * data,
+ size_t len)
{
- struct mgmt_msg * msg;
+ struct mgmt_msg * msg;
msg = malloc(sizeof(*msg) + len);
if (msg == NULL)
@@ -253,7 +248,9 @@ static int ipcp_udp_port_alloc_resp(int skfd,
memcpy(msg + 1, data, len);
- if (write(skfd, msg, sizeof(*msg) + len) < 0) {
+ if (sendto(udp_data.s_fd, msg, sizeof(*msg) + len,
+ MSG_CONFIRM,
+ (const struct sockaddr *) r_saddr, sizeof(*r_saddr)) < 0 ) {
free(msg);
return -1;
}
@@ -270,26 +267,9 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,
const void * data,
size_t len)
{
- struct timespec ts = {0, FD_UPDATE_TIMEOUT * 1000};
- struct timespec abstime;
- int skfd;
- int fd;
-
- skfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (skfd < 0) {
- log_err("Could not create UDP socket.");
- return -1;
- }
-
- /* Remote listens on server port. Mod of c_saddr allowed. */
- c_saddr->sin_port = udp_data.s_saddr.sin_port;
-
- /* Connect stores the remote address in the file descriptor. */
- if (connect(skfd, (struct sockaddr *) c_saddr, sizeof(*c_saddr)) < 0) {
- log_err("Could not connect to remote UDP client.");
- close(skfd);
- return -1;
- }
+ struct timespec ts = {0, FD_UPDATE_TIMEOUT * 1000};
+ struct timespec abstime;
+ int fd;
clock_gettime(PTHREAD_COND_CLOCK, &abstime);
@@ -304,7 +284,6 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,
if (ipcp_get_state() != IPCP_OPERATIONAL) {
log_dbg("Won't allocate over non-operational IPCP.");
pthread_mutex_unlock(&ipcpi.alloc_lock);
- close(skfd);
return -1;
}
@@ -313,14 +292,13 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,
if (fd < 0) {
pthread_mutex_unlock(&ipcpi.alloc_lock);
log_err("Could not get new flow from IRMd.");
- close(skfd);
return -1;
}
pthread_rwlock_wrlock(&udp_data.flows_lock);
- udp_data.fd_to_uf[fd].skfd = skfd;
- udp_data.fd_to_uf[fd].d_eid = d_eid;
+ udp_data.fd_to_uf[fd].r_saddr = *c_saddr;
+ udp_data.fd_to_uf[fd].d_eid = d_eid;
pthread_rwlock_unlock(&udp_data.flows_lock);
@@ -335,44 +313,27 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,
return 0;
}
-static int ipcp_udp_port_alloc_reply(uint32_t s_eid,
- uint32_t d_eid,
- int8_t response,
- const void * data,
- size_t len)
+static int ipcp_udp_port_alloc_reply(const struct sockaddr_in * saddr,
+ uint32_t s_eid,
+ uint32_t d_eid,
+ int8_t response,
+ const void * data,
+ size_t len)
{
- struct sockaddr_in t_saddr;
- socklen_t t_saddr_len;
- int ret = 0;
- int skfd = -1;
-
- t_saddr_len = sizeof(t_saddr);
-
pthread_rwlock_wrlock(&udp_data.flows_lock);
- skfd = udp_data.fd_to_uf[s_eid].skfd;
- if (skfd < 0) {
+ if (memcmp(&udp_data.fd_to_uf[s_eid].r_saddr, saddr, sizeof(*saddr))) {
pthread_rwlock_unlock(&udp_data.flows_lock);
- log_err("Got reply for unknown UDP eid: %u.", s_eid);
+ log_warn("Flow allocation reply for %u from wrong source.",
+ s_eid);
return -1;
}
- udp_data.fd_to_uf[s_eid].d_eid = d_eid;
+ if (response == 0)
+ udp_data.fd_to_uf[s_eid].d_eid = d_eid;
pthread_rwlock_unlock(&udp_data.flows_lock);
- if (getpeername(skfd, (struct sockaddr *) &t_saddr, &t_saddr_len) < 0) {
- log_dbg("Flow with fd %d has no peer.", s_eid);
- close(skfd);
- return -1;
- }
-
- if (connect(skfd, (struct sockaddr *) &t_saddr, sizeof(t_saddr)) < 0) {
- log_dbg("Could not connect flow to remote.");
- close(skfd);
- return -1;
- }
-
if (ipcp_flow_alloc_reply(s_eid, response, data, len) < 0) {
log_dbg("Failed to reply to flow allocation.");
return -1;
@@ -381,7 +342,7 @@ static int ipcp_udp_port_alloc_reply(uint32_t s_eid,
log_dbg("Flow allocation completed on eids (%d, %d).",
s_eid, d_eid);
- return ret;
+ return 0;
}
static int ipcp_udp_mgmt_frame(const uint8_t * buf,
@@ -416,7 +377,8 @@ static int ipcp_udp_mgmt_frame(const uint8_t * buf,
case FLOW_REPLY:
assert(len >= sizeof(*msg));
- return ipcp_udp_port_alloc_reply(ntoh32(msg->s_eid),
+ return ipcp_udp_port_alloc_reply(&c_saddr,
+ ntoh32(msg->s_eid),
ntoh32(msg->d_eid),
msg->response,
buf + sizeof(*msg),
@@ -543,8 +505,9 @@ static void * ipcp_udp_packet_writer(void * o)
pthread_cleanup_push(cleanup_writer, fq);
while (true) {
- int fd;
- int eid;
+ struct sockaddr_in saddr;
+ int eid;
+ int fd;
fevent(udp_data.np1_flows, fq, NULL);
while ((fd = fqueue_next(fq)) >= 0) {
struct shm_du_buff * sdb;
@@ -576,7 +539,7 @@ static void * ipcp_udp_packet_writer(void * o)
pthread_rwlock_rdlock(&udp_data.flows_lock);
eid = hton32(udp_data.fd_to_uf[fd].d_eid);
- fd = udp_data.fd_to_uf[fd].skfd;
+ saddr = udp_data.fd_to_uf[fd].r_saddr;
pthread_rwlock_unlock(&udp_data.flows_lock);
@@ -585,7 +548,10 @@ static void * ipcp_udp_packet_writer(void * o)
pthread_cleanup_push((void (*)(void *))
ipcp_sdb_release, (void *) sdb);
- if (write(fd, buf, len + OUR_HEADER_LEN) < 0)
+ if (sendto(udp_data.s_fd, buf, len + OUR_HEADER_LEN,
+ MSG_CONFIRM,
+ (const struct sockaddr *) &saddr,
+ sizeof(saddr)) < 0)
log_err("Failed to send packet.");
pthread_cleanup_pop(true);
@@ -633,22 +599,17 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
goto fail_socket;
}
- if (setsockopt(udp_data.s_fd, SOL_SOCKET, SO_REUSEADDR,
- &i, sizeof(i)) < 0)
- log_warn("Failed to set SO_REUSEADDR.");
-
memset((char *) &udp_data.s_saddr, 0, sizeof(udp_data.s_saddr));
udp_data.s_saddr.sin_family = AF_INET;
udp_data.s_saddr.sin_addr.s_addr = conf->ip_addr;
- udp_data.s_saddr.sin_port = htons(conf->srv_port);
+ udp_data.s_saddr.sin_port = htons(conf->port);
- if (bind(udp_data.s_fd, SERV_SADDR, SERV_SADDR_SIZE) < 0) {
+ if (bind(udp_data.s_fd, SADDR, SADDR_SIZE) < 0) {
log_err("Couldn't bind to %s.", ipstr);
goto fail_bind;
}
udp_data.dns_addr = conf->dns_addr;
- udp_data.clt_port = htons(conf->clt_port);
ipcp_set_state(IPCP_OPERATIONAL);
@@ -674,12 +635,11 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
}
}
- sprintf(portstr, "%d", conf->clt_port);
+ sprintf(portstr, "%d", conf->port);
log_dbg("Bootstrapped IPCP over UDP with pid %d.", getpid());
log_dbg("Bound to IP address %s.", ipstr);
- log_dbg("Client port is %s.", conf->clt_port == 0 ? "random" : portstr);
- log_dbg("Server port is %u.", conf->srv_port);
+ log_dbg("Using port %u.", conf->port);
log_dbg("DNS server address is %s.", dnsstr);
return 0;
@@ -997,13 +957,8 @@ static int ipcp_udp_flow_alloc(int fd,
size_t len)
{
struct sockaddr_in r_saddr; /* Server address */
- struct sockaddr_in c_saddr; /* Client address */
- socklen_t c_saddr_len;
- int skfd;
uint32_t ip_addr = 0;
- char ip_str[INET_ADDRSTRLEN];
-
- c_saddr_len = sizeof(c_saddr);
+ char ipstr[INET_ADDRSTRLEN];
log_dbg("Allocating flow to " HASH_FMT ".", HASH_VAL(dst));
@@ -1011,70 +966,36 @@ static int ipcp_udp_flow_alloc(int fd,
assert(dst);
- skfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (skfd < 0) {
- log_err("Could not create socket.");
- return -1;
- }
-
- /* This socket is for the flow. */
- memset((char *) &c_saddr, 0, sizeof(c_saddr));
- c_saddr.sin_family = AF_INET;
- c_saddr.sin_addr.s_addr = LOCAL_IP;
- c_saddr.sin_port = udp_data.clt_port;
-
- if (bind(skfd, (struct sockaddr *) &c_saddr, sizeof(c_saddr)) < 0) {
- log_dbg("Could not bind socket to client address.");
- close(skfd);
- return -1;
- }
-
- if (getsockname(skfd, (struct sockaddr *) &c_saddr, &c_saddr_len) < 0) {
- log_err("Could not get address from fd.");
- close(skfd);
- return -1;
- }
-
if (!shim_data_dir_has(udp_data.shim_data, dst)) {
log_dbg("Could not resolve destination.");
- close(skfd);
return -1;
}
ip_addr = (uint32_t) shim_data_dir_get_addr(udp_data.shim_data, dst);
- inet_ntop(AF_INET, &ip_addr, ip_str, INET_ADDRSTRLEN);
- log_dbg("Destination UDP ipcp resolved at %s.", ip_str);
+ inet_ntop(AF_INET, &ip_addr, ipstr, INET_ADDRSTRLEN);
+ log_dbg("Destination UDP ipcp resolved at %s.", ipstr);
- /* Connect to server and store the remote IP address in the skfd. */
memset((char *) &r_saddr, 0, sizeof(r_saddr));
r_saddr.sin_family = AF_INET;
r_saddr.sin_addr.s_addr = ip_addr;
r_saddr.sin_port = udp_data.s_saddr.sin_port;
- if (connect(skfd, (struct sockaddr *) &r_saddr, sizeof(r_saddr)) < 0) {
- log_dbg("Could not connect socket to remote.");
- close(skfd);
- return -1;
- }
-
- if (ipcp_udp_port_alloc(skfd, fd, dst, qs, data, len) < 0) {
+ if (ipcp_udp_port_alloc(&r_saddr, fd, dst, qs, data, len) < 0) {
log_err("Could not allocate port.");
- close(skfd);
return -1;
}
pthread_rwlock_wrlock(&udp_data.flows_lock);
- udp_data.fd_to_uf[fd].d_eid = -1;
- udp_data.fd_to_uf[fd].skfd = skfd;
+ udp_data.fd_to_uf[fd].d_eid = -1;
+ udp_data.fd_to_uf[fd].r_saddr = r_saddr;
pthread_rwlock_unlock(&udp_data.flows_lock);
fset_add(udp_data.np1_flows, fd);
- log_dbg("Flow pending on fd %d, UDP src port %d, dst port %d.",
- fd, ntohs(c_saddr.sin_port), ntohs(r_saddr.sin_port));
+ log_dbg("Flow to %s pending on fd %d.", ipstr, fd);
return 0;
}
@@ -1084,10 +1005,10 @@ static int ipcp_udp_flow_alloc_resp(int fd,
const void * data,
size_t len)
{
- struct timespec ts = {0, FD_UPDATE_TIMEOUT * 1000};
- struct timespec abstime;
- int skfd;
- int d_eid;
+ struct timespec ts = {0, FD_UPDATE_TIMEOUT * 1000};
+ struct timespec abstime;
+ struct sockaddr_in saddr;
+ int d_eid;
if (resp)
return 0;
@@ -1115,12 +1036,13 @@ static int ipcp_udp_flow_alloc_resp(int fd,
pthread_rwlock_rdlock(&udp_data.flows_lock);
- skfd = udp_data.fd_to_uf[fd].skfd;
+ saddr = udp_data.fd_to_uf[fd].r_saddr;
d_eid = udp_data.fd_to_uf[fd].d_eid;
pthread_rwlock_unlock(&udp_data.flows_lock);
- if (ipcp_udp_port_alloc_resp(skfd, d_eid, fd, resp, data, len) < 0) {
+ if (ipcp_udp_port_alloc_resp(&saddr, d_eid, fd, resp, data, len) < 0) {
+ fset_del(udp_data.np1_flows, fd);
log_err("Failed to respond to flow request.");
return -1;
}
@@ -1135,23 +1057,17 @@ static int ipcp_udp_flow_alloc_resp(int fd,
static int ipcp_udp_flow_dealloc(int fd)
{
- int skfd = -1;
-
ipcp_flow_fini(fd);
fset_del(udp_data.np1_flows, fd);
pthread_rwlock_wrlock(&udp_data.flows_lock);
- skfd = udp_data.fd_to_uf[fd].skfd;
-
udp_data.fd_to_uf[fd].d_eid = -1;
- udp_data.fd_to_uf[fd].skfd = -1;
+ memset(&udp_data.fd_to_uf[fd].r_saddr, 0, SADDR_SIZE);
pthread_rwlock_unlock(&udp_data.flows_lock);
- close(skfd);
-
flow_dealloc(fd);
log_dbg("Flow with fd %d deallocated.", fd);
diff --git a/src/lib/ipcp_config.proto b/src/lib/ipcp_config.proto
index 9cbf1e49..185d9af7 100644
--- a/src/lib/ipcp_config.proto
+++ b/src/lib/ipcp_config.proto
@@ -40,12 +40,11 @@ message ipcp_config_msg {
// Config for UDP
optional uint32 ip_addr = 9;
optional uint32 dns_addr = 10;
- optional uint32 clt_port = 11;
- optional uint32 srv_port = 12;
+ optional uint32 port = 11;
// Config for the Ethernet
- optional string dev = 13;
+ optional string dev = 12;
// Config for DIX Ethernet
- optional uint32 ethertype = 14;
+ optional uint32 ethertype = 13;
}
enum enroll_code {
diff --git a/src/lib/irm.c b/src/lib/irm.c
index 19bee4d2..b86b02c9 100644
--- a/src/lib/irm.c
+++ b/src/lib/irm.c
@@ -140,10 +140,8 @@ int irm_bootstrap_ipcp(pid_t pid,
config.ip_addr = conf->ip_addr;
config.has_dns_addr = true;
config.dns_addr = conf->dns_addr;
- config.has_srv_port = true;
- config.srv_port = conf->srv_port;
- config.has_clt_port = true;
- config.clt_port = conf->clt_port;
+ config.has_port = true;
+ config.port = conf->port;
break;
case IPCP_LOCAL:
case IPCP_BROADCAST:
diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c
index cd6c3c8a..95330e99 100644
--- a/src/tools/irm/irm_ipcp_bootstrap.c
+++ b/src/tools/irm/irm_ipcp_bootstrap.c
@@ -73,8 +73,7 @@
#define DEFAULT_CONG_AVOID CA_MB_ECN
#define DEFAULT_HASH_ALGO DIR_HASH_SHA3_256
#define DEFAULT_ETHERTYPE 0xA000
-#define DEFAULT_CLIENT_PORT 0x0000 /* random port */
-#define DEFAULT_SERVER_PORT 0x0D6B /* 3435 */
+#define DEFAULT_UDP_PORT 0x0D6B /* 3435 */
#define FLAT_RANDOM_ADDR_AUTH "flat"
#define LINK_STATE_ROUTING "link_state"
@@ -109,8 +108,7 @@ static void usage(void)
SHA3_384 " " SHA3_512 "}\n\n"
"if TYPE == " UDP "\n"
" ip <IP address in dotted notation>\n"
- " [cport <client port> (default: random)]\n"
- " [sport <server port> (default: %d)]\n"
+ " [port <UDP port> (default: %d)]\n"
" [dns <DDNS IP address in dotted notation>"
" (default: none)]\n\n"
"if TYPE == " ETH_LLC "\n"
@@ -136,7 +134,7 @@ static void usage(void)
" [autobind]\n\n",
DEFAULT_ADDR_SIZE, DEFAULT_EID_SIZE, DEFAULT_TTL,
FLAT_RANDOM_ADDR_AUTH, LINK_STATE_ROUTING, MB_ECN_CA,
- SHA3_256, DEFAULT_SERVER_PORT, SHA3_256, 0xA000, SHA3_256,
+ SHA3_256, DEFAULT_UDP_PORT, SHA3_256, 0xA000, SHA3_256,
SHA3_256, SHA3_256);
}
@@ -165,8 +163,7 @@ int do_bootstrap_ipcp(int argc,
int i = 0;
bool autobind = false;
int cargs;
- int cport = DEFAULT_CLIENT_PORT;
- int sport = DEFAULT_SERVER_PORT;
+ int port = DEFAULT_UDP_PORT;
while (argc > 0) {
cargs = 2;
@@ -213,10 +210,8 @@ int do_bootstrap_ipcp(int argc,
eid_size = atoi(*(argv + 1));
} else if (matches(*argv, "ttl") == 0) {
max_ttl = atoi(*(argv + 1));
- } else if (matches(*argv, "cport") == 0) {
- cport = atoi(*(argv + 1));
- } else if (matches(*argv, "sport") == 0) {
- sport = atoi(*(argv + 1));
+ } else if (matches(*argv, "port") == 0) {
+ port = atoi(*(argv + 1));
} else if (matches(*argv, "autobind") == 0) {
autobind = true;
cargs = 1;
@@ -336,8 +331,7 @@ int do_bootstrap_ipcp(int argc,
goto fail_usage;
conf.ip_addr = ip_addr;
conf.dns_addr = dns_addr;
- conf.clt_port = cport;
- conf.srv_port = sport;
+ conf.port = port;
break;
case IPCP_ETH_LLC:
if (dev == NULL)