summaryrefslogtreecommitdiffstats
path: root/src/portmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/portmap.c')
-rw-r--r--src/portmap.c130
1 files changed, 80 insertions, 50 deletions
diff --git a/src/portmap.c b/src/portmap.c
index 5b463c0..f2e009e 100644
--- a/src/portmap.c
+++ b/src/portmap.c
@@ -96,38 +96,39 @@ main(int argc, char **argv)
}
setregid(2516, 2516);
setreuid(2510, 2510);
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_TCP,
- 0);
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_UDP,
- 0);
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_TCP,
- 0);
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_UDP,
- 0);
- portmap_register("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_TCP,
- port);
- portmap_register("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_UDP,
- port);
- portmap_register("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_TCP,
- port);
- portmap_register("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_UDP,
- port);
+ sleep(60);
+ portmap_unregister("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET, IPPROTO_TCP, 0);
+ portmap_unregister("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET, IPPROTO_UDP, 0);
+ portmap_unregister("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET6, IPPROTO_TCP, 0);
+ portmap_unregister("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET6, IPPROTO_UDP, 0);
+ portmap_register("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET, IPPROTO_TCP, port);
+ portmap_register("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET, IPPROTO_UDP, port);
+ portmap_register("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET6, IPPROTO_TCP, port);
+ portmap_register("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET6, IPPROTO_UDP, port);
ret = system("rpcinfo | grep ypserv");
ret = system("rpcinfo -p | grep ypserv");
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_TCP,
- port);
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_UDP,
- port);
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_TCP,
- port);
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_UDP,
- port);
+ portmap_unregister("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET, IPPROTO_TCP, port);
+ portmap_unregister("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET, IPPROTO_UDP, port);
+ portmap_unregister("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET6, IPPROTO_TCP, port);
+ portmap_unregister("portmap", &s, port, YPPROG, YPVERS,
+ AF_INET6, IPPROTO_UDP, port);
return 0;
}
#endif
static bool_t
-portmap_register_work(const char *module, int client_sock,
+portmap_register_work(const char *module, int *client_sock, int but_not,
bool_t stream,
struct sockaddr *dgram_address, socklen_t addrlen,
int prog, int vers, int proc,
@@ -142,7 +143,7 @@ portmap_register_work(const char *module, int client_sock,
bool_t ret = FALSE;
struct sockaddr addr;
struct pollfd pollfd;
- int i;
+ int i, err, sock2 = -1;
static u_long xid;
log_id = (char *) module;
@@ -197,7 +198,7 @@ portmap_register_work(const char *module, int client_sock,
portmap_length += 4;
} else {
/* Point the datagram socket at the remote. */
- if (connect(client_sock, dgram_address, addrlen) != 0) {
+ if (connect(*client_sock, dgram_address, addrlen) != 0) {
slapi_log_error(SLAPI_LOG_FATAL, log_id,
"error targeting portmap: %s\n",
strerror(errno));
@@ -210,26 +211,56 @@ portmap_register_work(const char *module, int client_sock,
for (i = 1; i < 32; i *= 2) {
/* Try to send our request. If there's any problem,
* immediately retry. */
- if (send(client_sock, &portmap_buf, portmap_length,
+ if (send(*client_sock, &portmap_buf, portmap_length,
MSG_NOSIGNAL) != portmap_length) {
+ err = errno;
slapi_log_error(SLAPI_LOG_FATAL, log_id,
"error sending request to portmap or "
- "rpcbind on %d: %s\n", client_sock,
- strerror(errno));
+ "rpcbind on %d: %s\n", *client_sock,
+ strerror(err));
if (stream) {
- break;
+ if (err == EPIPE) {
+ /* Try again with a new client
+ * connection -- some RPC
+ * implementations will cause rpcbind
+ * to drop idle clients. */
+ snprintf(reply_buf, sizeof(reply_buf),
+ "%s", module);
+ sock2 = portmap_create_client_socket(reply_buf,
+ but_not);
+ if (sock2 != -1) {
+ if (send(sock2, &portmap_buf, portmap_length,
+ MSG_NOSIGNAL) == portmap_length) {
+ slapi_log_error(SLAPI_LOG_FATAL, log_id,
+ "retried sending request "
+ "to portmap or rpcbind "
+ "on %d, and succeeded\n",
+ sock2);
+ close(*client_sock);
+ *client_sock = sock2;
+ } else {
+ /* Still got an error -- bail. */
+ close(sock2);
+ break;
+ }
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
} else {
continue;
}
}
/* Wait for a response. */
- pollfd.fd = client_sock;
+ pollfd.fd = *client_sock;
pollfd.events = POLLIN | POLLERR;
if ((poll(&pollfd, 1, stream ? -1 : i * 1000) > 0) &&
(pollfd.revents & POLLIN)) {
/* Read the response. */
- reply_length = recv(client_sock,
+ reply_length = recv(*client_sock,
reply_buf, sizeof(reply_buf), 0);
/* Decode the response. */
if (reply_length > 0) {
@@ -266,6 +297,8 @@ portmap_register_work(const char *module, int client_sock,
if ((msg.rm_direction == REPLY) &&
(msg.rm_xid == xid)) {
xdr_destroy(&portmap_xdrs);
+ memset(&portmap_xdrs, 0,
+ sizeof(portmap_xdrs));
break;
}
}
@@ -280,7 +313,7 @@ portmap_register_work(const char *module, int client_sock,
* socket around. */
memset(&addr, 0, sizeof(addr));
addr.sa_family = AF_UNSPEC;
- connect(client_sock, &addr, sizeof(addr));
+ connect(*client_sock, &addr, sizeof(addr));
/* Check for a timeout. */
if (i == 32) {
slapi_log_error(SLAPI_LOG_FATAL, log_id,
@@ -336,7 +369,6 @@ portmap_register_work(const char *module, int client_sock,
"RPC mismatch\n");
break;
}
- xdr_destroy(&portmap_xdrs);
return FALSE;
}
@@ -355,7 +387,6 @@ portmap_register_work(const char *module, int client_sock,
if (msg.rm_reply.rp_acpt.ar_stat != SUCCESS) {
slapi_log_error(SLAPI_LOG_FATAL, log_id,
"portmap request not processed\n");
- xdr_destroy(&portmap_xdrs);
return FALSE;
}
@@ -368,8 +399,6 @@ portmap_register_work(const char *module, int client_sock,
"portmap request failed\n");
}
- xdr_destroy(&portmap_xdrs);
-
return ret;
}
@@ -392,7 +421,7 @@ portmap_xdr_rpcbind_req(XDR *xdrs, struct rpcbind_req *req)
}
static bool_t
-portmap_register_rpcbind(const char *module, int client_sock,
+portmap_register_rpcbind(const char *module, int *client_sock, int but_not,
bool_t create,
int family, int protocol, int port,
int program, int version)
@@ -444,7 +473,8 @@ portmap_register_rpcbind(const char *module, int client_sock,
req.address = NULL;
break;
}
- return portmap_register_work(module, client_sock, TRUE, NULL, 0,
+ return portmap_register_work(module, client_sock, but_not,
+ TRUE, NULL, 0,
RPCBPROG, RPCBVERS,
create ? RPCBPROC_SET : RPCBPROC_UNSET,
&req,
@@ -452,7 +482,7 @@ portmap_register_rpcbind(const char *module, int client_sock,
}
static bool_t
-portmap_register_portmap(const char *module, int client_sock,
+portmap_register_portmap(const char *module, int *client_sock, int but_not,
bool_t create,
int protocol, int port, int program, int version)
{
@@ -466,7 +496,7 @@ portmap_register_portmap(const char *module, int client_sock,
map.pm_vers = version;
map.pm_prot = protocol;
map.pm_port = port;
- return portmap_register_work(module, client_sock,
+ return portmap_register_work(module, client_sock, but_not,
FALSE,
(struct sockaddr *) &sin, sizeof(sin),
PMAPPROG, PMAPVERS,
@@ -486,32 +516,32 @@ portmap_is_stream(int sd)
}
bool_t
-portmap_register(const char *log_id, int resv_sock,
+portmap_register(const char *log_id, int *resv_sock, int but_not,
int program, int version,
int family, int protocol, int port)
{
- return portmap_is_stream(resv_sock) ?
- portmap_register_rpcbind(log_id, resv_sock,
+ return portmap_is_stream(*resv_sock) ?
+ portmap_register_rpcbind(log_id, resv_sock, but_not,
TRUE,
family, protocol, port,
program, version) :
- portmap_register_portmap(log_id, resv_sock,
+ portmap_register_portmap(log_id, resv_sock, but_not,
TRUE,
protocol, port,
program, version);
}
bool_t
-portmap_unregister(const char *log_id, int resv_sock,
+portmap_unregister(const char *log_id, int *resv_sock, int but_not,
int program, int version,
int family, int protocol, int port)
{
- return portmap_is_stream(resv_sock) ?
- portmap_register_rpcbind(log_id, resv_sock,
+ return portmap_is_stream(*resv_sock) ?
+ portmap_register_rpcbind(log_id, resv_sock, but_not,
FALSE,
family, protocol, port,
program, version) :
- portmap_register_portmap(log_id, resv_sock,
+ portmap_register_portmap(log_id, resv_sock, but_not,
FALSE,
protocol, port,
program, version);