From 485bc9b9a7a19d7cef7a4b0c4c919323f3011aa8 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 26 Jun 2011 18:40:00 +1000 Subject: [PATCH] add function to bind a udp rpc context to a local port/address --- include/libnfs-private.h | 2 ++ lib/socket.c | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/libnfs-private.h b/include/libnfs-private.h index 2671a2b..883745b 100644 --- a/include/libnfs-private.h +++ b/include/libnfs-private.h @@ -76,4 +76,6 @@ void nfs_set_error(struct nfs_context *nfs, char *error_string, ...); struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs); +/* we dont want to expose UDP to normal applications/users this is private to libnfs to use exclusively for broadcast RPC */ +int rpc_bind_udp(struct rpc_context *rpc, char *addr, int port); struct rpc_context *rpc_init_udp_context(void); diff --git a/lib/socket.c b/lib/socket.c index a0ededa..3e4ad05 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" @@ -340,3 +343,48 @@ int rpc_disconnect(struct rpc_context *rpc, char *error) return 0; } + + +int rpc_bind_udp(struct rpc_context *rpc, char *addr, int port) +{ + struct addrinfo *ai = NULL; + char service[6]; + + if (rpc->is_udp == 0) { + rpc_set_error(rpc, "Cant not bind UDP. Not UDP context"); + return -1; + } + + snprintf(service, 6, "%d", port); + if (getaddrinfo(addr, service, NULL, &ai) != 0) { + rpc_set_error(rpc, "Invalid address:%s. " + "Can not resolv into IPv4/v6 structure."); + return -1; + } + + switch(ai->ai_family) { + case AF_INET: + rpc->fd = socket(ai->ai_family, SOCK_DGRAM, 0); + if (rpc->fd == -1) { + rpc_set_error(rpc, "Failed to create UDP socket: %s", strerror(errno)); + freeaddrinfo(ai); + return -1; + } + + if (bind(rpc->fd, (struct sockaddr *)ai->ai_addr, sizeof(struct sockaddr_in)) != 0) { + rpc_set_error(rpc, "Failed to bind to UDP socket: %s",strerror(errno)); + freeaddrinfo(ai); + return -1; + } + break; + default: + rpc_set_error(rpc, "Can not handle UPD sockets of family %d yet", ai->ai_family); + freeaddrinfo(ai); + return -1; + } + + freeaddrinfo(ai); + + return 0; +} + -- 2.34.1