I’m using a veeery old distributed uptime server https://ru1.sourceforge.net/ on Linux (opensuse leap 15.6 currently) which generates the code part for rpc communication by calling rpcgen. Due to firewall issues I’ve changed the resulting code such that a fixed tcp port is used instead of a random one created by using RPC_ANYSOCK.
This worked fine as long as the sun rpc code was in glibc, but after it was moved to libtirpc it fails silently without any error messages.
The code generated by rpgcen is this (only the main procedure, inlcuding my changes):
int main (int argc, char **argv) {
int c; // used by getopt
long server_port = -1;
register SVCXPRT *transp;
pmap_unset (RWPROG, RWVERS);
transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create udp service.");
exit(1);
}
if (!svc_register(transp, RWPROG, RWVERS, rwprog_1, IPPROTO_UDP)) {
fprintf (stderr, "%s", "unable to register (RWPROG, RWVERS, udp).");
exit(1);
}
/* transp = svctcp_create(RPC_ANYSOCK, 0, 0); */
/* my code added: */
int sd;
struct sockaddr_in sin;
sd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(62222);
bind(sd, &sin, sizeof(sin));
transp = svctcp_create(sd, 0, 0);
/* end of my code added */
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create tcp service.");
exit(1);
}
if (!svc_register(transp, RWPROG, RWVERS, rwprog_1, IPPROTO_TCP)) {
fprintf (stderr, "%s", "unable to register (RWPROG, RWVERS, tcp).");
exit(1);
}
svc_run ();
fprintf (stderr, "%s", "svc_run returned");
exit (1);
/* NOTREACHED */
}
The part that I added to replace ransp = svctcp_create(RPC_ANYSOCK, 0, 0);
is marked.
This compiles and starts fine, but calling “netstat -tulpn” afterwards I see only the udp port is used (random port number). When reverting to “svctcp_create(RPC_ANYSOCK, 0, 0);” the server is also listening on a (random) tcp port.
Comparing both servers startups with strace I don’t see why using the fixed port fails. That’s the relevant part from using RPC_ANYSOCK:
getsockname(4, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
getsockopt(4, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
openat(AT_FDCWD, "/proc/sys/net/ipv4/ip_local_reserved_ports", O_RDONLY) = 5
fstat(5, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
read(5, "n", 1024) = 1
read(5, "", 1024) = 0
close(5) = 0
bind(4, {sa_family=AF_INET, sin_port=htons(63242), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(4, 4096) = 0
getpeername(4, 0x7ffe8af2fa10, [128]) = -1 ENOTCONN (Transport endpoint is not connected)
getsockname(4, {sa_family=AF_INET, sin_port=htons(63242), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
getsockopt(4, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(63242), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
openat(AT_FDCWD, "/etc/netconfig", O_RDONLY) = 5
fstat(5, {st_mode=S_IFREG|0644, st_size=767, ...}) = 0
read(5, "#n# The network configuration fi"..., 4096) = 767
close(5) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 5
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
getpeername(5, 0x7ffe8af2f730, [128]) = -1 ENOTCONN (Transport endpoint is not connected)
connect(5, {sa_family=AF_UNIX, sun_path="/var/run/rpcbind.sock"}, 23) = 0
getsockname(5, {sa_family=AF_UNIX}, [128 => 2]) = 0
getsockopt(5, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
With my fixed-port code I get this:
openat(AT_FDCWD, "/etc/netconfig", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=767, ...}) = 0
read(4, "#n# The network configuration fi"..., 4096) = 767
close(4) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 4
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
getpeername(4, 0x7fff5be340b0, [128]) = -1 ENOTCONN (Transport endpoint is not connected)
connect(4, {sa_family=AF_UNIX, sun_path="/var/run/rpcbind.sock"}, 23) = 0
getsockname(4, {sa_family=AF_UNIX}, [128 => 2]) = 0
getsockopt(4, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
getpid() = 1701
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
geteuid() = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
write(4, "200T<B2222120624031"..., 88) = 88
read(4, "20034<B22211", 9000) = 32
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
close(4) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 4
bind(4, {sa_family=AF_INET, sin_port=htons(62222), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
openat(AT_FDCWD, "/etc/netconfig", O_RDONLY) = 5
fstat(5, {st_mode=S_IFREG|0644, st_size=767, ...}) = 0
read(5, "#n# The network configuration fi"..., 4096) = 767
close(5) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(62222), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
getsockopt(4, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(62222), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
getpeername(4, 0x7fff5be34390, [128]) = -1 ENOTCONN (Transport endpoint is not connected)
getsockname(4, {sa_family=AF_INET, sin_port=htons(62222), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
getsockopt(4, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(62222), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
openat(AT_FDCWD, "/etc/netconfig", O_RDONLY) = 5
fstat(5, {st_mode=S_IFREG|0644, st_size=767, ...}) = 0
read(5, "#n# The network configuration fi"..., 4096) = 767
close(5) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 5
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
getpeername(5, 0x7fff5be340b0, [128]) = -1 ENOTCONN (Transport endpoint is not connected)
connect(5, {sa_family=AF_UNIX, sun_path="/var/run/rpcbind.sock"}, 23) = 0
getsockname(5, {sa_family=AF_UNIX}, [128 => 2]) = 0
getsockopt(5, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
I don’t see any kind of obvious error as the “Transport endpoint is not connected” also occurs for the code chosing a random port.
Any ideas what’s going wrong here and what I could try to make the fixed port work?
Thanks a lot!