Resolve the pid field in PeerCredentials of KQueueDomainSocketChannels. (#9219)

Motivation:

This resolves a TODO from the initial transport-native-kqueue implementation, supplying the user with the pid of the local peer client/server process.

Modification:

Inside netty_kqueue_bsdsocket_getPeerCredentials, Call getsockopt with LOCAL_PEERPID and pass it to PeerCredentials constructor.
Add a test case in KQueueSocketTest.

Result:

PeerCredentials now have pid field set. Fixes https://github.com/netty/netty/issues/9213
This commit is contained in:
EliyahuStern 2019-06-04 15:15:42 +03:00 committed by Norman Maurer
parent 26275e8a3d
commit 5dacc5f3da
2 changed files with 38 additions and 4 deletions

View File

@ -159,8 +159,16 @@ static jobject netty_kqueue_bsdsocket_getPeerCredentials(JNIEnv *env, jclass cla
(*env)->SetIntArrayRegion(env, gids, 0, 1, (jint*) &credentials.cr_gid);
}
// TODO: getting the PID may require reading/sending "ancillary data" via SCM_CREDENTIALS which is not desirable.
return (*env)->NewObject(env, peerCredentialsClass, peerCredentialsMethodId, 0, credentials.cr_uid, gids);
pid_t pid = 0;
#ifdef LOCAL_PEERPID
socklen_t len = sizeof(pid);
// Getting the LOCAL_PEERPID is expected to return error in some cases (e.g. server socket FDs) - just return 0.
if (netty_unix_socket_getOption0(fd, SOCK_STREAM, LOCAL_PEERPID, &pid, len) < 0) {
pid = 0;
}
#endif
return (*env)->NewObject(env, peerCredentialsClass, peerCredentialsMethodId, pid, credentials.cr_uid, gids);
}
// JNI Registered Methods End

View File

@ -24,8 +24,7 @@ import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;
public class KQueueSocketTest extends SocketTest<BsdSocket> {
@ -55,6 +54,33 @@ public class KQueueSocketTest extends SocketTest<BsdSocket> {
}
}
@Test
public void testPeerPID() throws IOException {
BsdSocket s1 = BsdSocket.newSocketDomain();
BsdSocket s2 = BsdSocket.newSocketDomain();
try {
DomainSocketAddress dsa = UnixTestUtils.newSocketAddress();
s1.bind(dsa);
s1.listen(1);
// PID of client socket is expected to be 0 before connection
assertEquals(0, s2.getPeerCredentials().pid());
assertTrue(s2.connect(dsa));
byte [] addr = new byte[64];
int clientFd = s1.accept(addr);
assertNotEquals(-1, clientFd);
PeerCredentials pc = new BsdSocket(clientFd).getPeerCredentials();
assertNotEquals(0, pc.pid());
assertNotEquals(0, s2.getPeerCredentials().pid());
// Server socket FDs should not have pid field set:
assertEquals(0, s1.getPeerCredentials().pid());
} finally {
s1.close();
s2.close();
}
}
@Override
protected BsdSocket newSocket() {
return BsdSocket.newSocketStream();