[#3112] Add supprt for TCP_INFO when using EpollSocketChannel

Motivation:

On Linux, you can gather various metrics using getsockopt(..., TCP_INFO,
...).

Modifications:

Add EpollSocketChannel.tcpInfo() which returns EpollTcpInfo that exposes
all metrics exposed via getsockopt(..., TCP_INFO, ...)

Result:

TCP_INFO support implemented
This commit is contained in:
Norman Maurer 2014-11-13 14:06:47 +01:00
parent 23fa4d4750
commit 201d9ed9ba
6 changed files with 431 additions and 67 deletions

View File

@ -1297,6 +1297,48 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_getTcpKeepCnt(JNIEnv*
return optval;
}
JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_tcpInfo0(JNIEnv* env, jclass clazz, jint fd, jintArray array) {
struct tcp_info tcp_info;
if (getOption(env, fd, SOL_TCP, TCP_INFO, &tcp_info, sizeof(tcp_info)) == -1) {
return;
}
unsigned int cArray[32];
cArray[0] = tcp_info.tcpi_state;
cArray[1] = tcp_info.tcpi_ca_state;
cArray[2] = tcp_info.tcpi_retransmits;
cArray[3] = tcp_info.tcpi_probes;
cArray[4] = tcp_info.tcpi_backoff;
cArray[5] = tcp_info.tcpi_options;
cArray[6] = tcp_info.tcpi_snd_wscale;
cArray[7] = tcp_info.tcpi_rcv_wscale;
cArray[8] = tcp_info.tcpi_rto;
cArray[9] = tcp_info.tcpi_ato;
cArray[10] = tcp_info.tcpi_snd_mss;
cArray[11] = tcp_info.tcpi_rcv_mss;
cArray[12] = tcp_info.tcpi_unacked;
cArray[13] = tcp_info.tcpi_sacked;
cArray[14] = tcp_info.tcpi_lost;
cArray[15] = tcp_info.tcpi_retrans;
cArray[16] = tcp_info.tcpi_fackets;
cArray[17] = tcp_info.tcpi_last_data_sent;
cArray[18] = tcp_info.tcpi_last_ack_sent;
cArray[19] = tcp_info.tcpi_last_data_recv;
cArray[20] = tcp_info.tcpi_last_ack_recv;
cArray[21] = tcp_info.tcpi_pmtu;
cArray[22] = tcp_info.tcpi_rcv_ssthresh;
cArray[23] = tcp_info.tcpi_rtt;
cArray[24] = tcp_info.tcpi_rttvar;
cArray[25] = tcp_info.tcpi_snd_ssthresh;
cArray[26] = tcp_info.tcpi_snd_cwnd;
cArray[27] = tcp_info.tcpi_advmss;
cArray[28] = tcp_info.tcpi_reordering;
cArray[29] = tcp_info.tcpi_rcv_rtt;
cArray[30] = tcp_info.tcpi_rcv_space;
cArray[31] = tcp_info.tcpi_total_retrans;
(*env)->SetIntArrayRegion(env, array, 0, 32, cArray);
}
JNIEXPORT jstring JNICALL Java_io_netty_channel_epoll_Native_kernelVersion(JNIEnv* env, jclass clazz) {
struct utsname name;

View File

@ -38,75 +38,81 @@
#define UIO_MAXIOV 1024
#endif /* UIO_MAXIOV */
jint Java_io_netty_channel_epoll_Native_eventFd(JNIEnv * env, jclass clazz);
void Java_io_netty_channel_epoll_Native_eventFdWrite(JNIEnv * env, jclass clazz, jint fd, jlong value);
void Java_io_netty_channel_epoll_Native_eventFdRead(JNIEnv * env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_epollCreate(JNIEnv * env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_epollWait(JNIEnv * env, jclass clazz, jint efd, jlongArray events, jint timeout);
void Java_io_netty_channel_epoll_Native_epollCtlAdd(JNIEnv * env, jclass clazz, jint efd, jint fd, jint flags, jint id);
void Java_io_netty_channel_epoll_Native_epollCtlMod(JNIEnv * env, jclass clazz, jint efd, jint fd, jint flags, jint id);
void Java_io_netty_channel_epoll_Native_epollCtlDel(JNIEnv * env, jclass clazz, jint efd, jint fd);
jint Java_io_netty_channel_epoll_Native_write0(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit);
jint Java_io_netty_channel_epoll_Native_writeAddress0(JNIEnv * env, jclass clazz, jint fd, jlong address, jint pos, jint limit);
jlong Java_io_netty_channel_epoll_Native_writev0(JNIEnv * env, jclass clazz, jint fd, jobjectArray buffers, jint offset, jint length);
jlong Java_io_netty_channel_epoll_Native_writevAddresses0(JNIEnv * env, jclass clazz, jint fd, jlong memoryAddress, jint length);
jint Java_io_netty_channel_epoll_Native_sendTo(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_sendToAddress(JNIEnv * env, jclass clazz, jint fd, jlong memoryAddress, jint pos, jint limit, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_sendToAddresses(JNIEnv * env, jclass clazz, jint fd, jlong memoryAddress, jint length, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_sendmmsg(JNIEnv * env, jclass clazz, jint fd, jobjectArray packets, jint offset, jint len);
jint Java_io_netty_channel_epoll_Native_eventFd(JNIEnv* env, jclass clazz);
void Java_io_netty_channel_epoll_Native_eventFdWrite(JNIEnv* env, jclass clazz, jint fd, jlong value);
void Java_io_netty_channel_epoll_Native_eventFdRead(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_epollCreate(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_epollWait(JNIEnv* env, jclass clazz, jint efd, jlongArray events, jint timeout);
void Java_io_netty_channel_epoll_Native_epollCtlAdd(JNIEnv* env, jclass clazz, jint efd, jint fd, jint flags, jint id);
void Java_io_netty_channel_epoll_Native_epollCtlMod(JNIEnv* env, jclass clazz, jint efd, jint fd, jint flags, jint id);
void Java_io_netty_channel_epoll_Native_epollCtlDel(JNIEnv* env, jclass clazz, jint efd, jint fd);
jint Java_io_netty_channel_epoll_Native_write0(JNIEnv* env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit);
jint Java_io_netty_channel_epoll_Native_writeAddress0(JNIEnv* env, jclass clazz, jint fd, jlong address, jint pos, jint limit);
jlong Java_io_netty_channel_epoll_Native_writev0(JNIEnv* env, jclass clazz, jint fd, jobjectArray buffers, jint offset, jint length);
jlong Java_io_netty_channel_epoll_Native_writevAddresses0(JNIEnv* env, jclass clazz, jint fd, jlong memoryAddress, jint length);
jint Java_io_netty_channel_epoll_Native_sendTo(JNIEnv* env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_sendToAddress(JNIEnv* env, jclass clazz, jint fd, jlong memoryAddress, jint pos, jint limit, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_sendToAddresses(JNIEnv* env, jclass clazz, jint fd, jlong memoryAddress, jint length, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_sendmmsg(JNIEnv* env, jclass clazz, jint fd, jobjectArray packets, jint offset, jint len);
jint Java_io_netty_channel_epoll_Native_read0(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit);
jint Java_io_netty_channel_epoll_Native_readAddress0(JNIEnv * env, jclass clazz, jint fd, jlong address, jint pos, jint limit);
jobject Java_io_netty_channel_epoll_Native_recvFrom(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit);
jobject Java_io_netty_channel_epoll_Native_recvFromAddress(JNIEnv * env, jclass clazz, jint fd, jlong address, jint pos, jint limit);
jint Java_io_netty_channel_epoll_Native_close0(JNIEnv * env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_shutdown0(JNIEnv * env, jclass clazz, jint fd, jboolean read, jboolean write);
jint Java_io_netty_channel_epoll_Native_socketStream(JNIEnv * env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_socketDgram(JNIEnv * env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_read0(JNIEnv* env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit);
jint Java_io_netty_channel_epoll_Native_readAddress0(JNIEnv* env, jclass clazz, jint fd, jlong address, jint pos, jint limit);
jobject Java_io_netty_channel_epoll_Native_recvFrom(JNIEnv* env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit);
jobject Java_io_netty_channel_epoll_Native_recvFromAddress(JNIEnv* env, jclass clazz, jint fd, jlong address, jint pos, jint limit);
jint Java_io_netty_channel_epoll_Native_close0(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_shutdown0(JNIEnv* env, jclass clazz, jint fd, jboolean read, jboolean write);
jint Java_io_netty_channel_epoll_Native_socketStream(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_socketDgram(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_socketDomain(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_bind(JNIEnv * env, jclass clazz, jint fd, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_listen0(JNIEnv * env, jclass clazz, jint fd, jint backlog);
jint Java_io_netty_channel_epoll_Native_connect(JNIEnv * env, jclass clazz, jint fd, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_finishConnect0(JNIEnv * env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_accept0(JNIEnv * env, jclass clazz, jint fd);
jlong Java_io_netty_channel_epoll_Native_sendfile0(JNIEnv *env, jclass clazz, jint fd, jobject fileRegion, jlong base_off, jlong off, jlong len);
jbyteArray Java_io_netty_channel_epoll_Native_remoteAddress0(JNIEnv * env, jclass clazz, jint fd);
jbyteArray Java_io_netty_channel_epoll_Native_localAddress0(JNIEnv * env, jclass clazz, jint fd);
void Java_io_netty_channel_epoll_Native_setReuseAddress(JNIEnv * env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setReusePort(JNIEnv * env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpNoDelay(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setReceiveBufferSize(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setSendBufferSize(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setKeepAlive(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpCork(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setSoLinger(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTrafficClass(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setBroadcast(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpKeepIdle(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpKeepIntvl(JNIEnv *env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpKeepCnt(JNIEnv *env, jclass clazz, jint fd, jint optval);
jint Java_io_netty_channel_epoll_Native_bind(JNIEnv* env, jclass clazz, jint fd, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_bindDomainSocket(JNIEnv* env, jclass clazz, jint fd, jstring address);
jint Java_io_netty_channel_epoll_Native_recvFd0(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_sendFd0(JNIEnv* env, jclass clazz, jint socketFd, jint fd);
jint Java_io_netty_channel_epoll_Native_isReuseAddresss(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_isReusePort(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_isTcpNoDelay(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getReceiveBufferSize(JNIEnv * env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getSendBufferSize(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_isTcpCork(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getSoLinger(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getTrafficClass(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_isBroadcast(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getTcpKeepIdle(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getTcpKeepIntvl(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getTcpKeepCnt(JNIEnv *env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_listen0(JNIEnv* env, jclass clazz, jint fd, jint backlog);
jint Java_io_netty_channel_epoll_Native_connect(JNIEnv* env, jclass clazz, jint fd, jbyteArray address, jint scopeId, jint port);
jint Java_io_netty_channel_epoll_Native_connectDomainSocket(JNIEnv* env, jclass clazz, jint fd, jstring address);
jint Java_io_netty_channel_epoll_Native_finishConnect0(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_accept0(JNIEnv* env, jclass clazz, jint fd);
jlong Java_io_netty_channel_epoll_Native_sendfile0(JNIEnv* env, jclass clazz, jint fd, jobject fileRegion, jlong base_off, jlong off, jlong len);
jbyteArray Java_io_netty_channel_epoll_Native_remoteAddress0(JNIEnv* env, jclass clazz, jint fd);
jbyteArray Java_io_netty_channel_epoll_Native_localAddress0(JNIEnv* env, jclass clazz, jint fd);
void Java_io_netty_channel_epoll_Native_setReuseAddress(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setReusePort(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpNoDelay(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setReceiveBufferSize(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setSendBufferSize(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setKeepAlive(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpCork(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setSoLinger(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTrafficClass(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setBroadcast(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpKeepIdle(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpKeepIntvl(JNIEnv* env, jclass clazz, jint fd, jint optval);
void Java_io_netty_channel_epoll_Native_setTcpKeepCnt(JNIEnv* env, jclass clazz, jint fd, jint optval);
jstring Java_io_netty_channel_epoll_Native_kernelVersion(JNIEnv *env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_iovMax(JNIEnv *env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_uioMaxIov(JNIEnv *env, jclass clazz);
jboolean Java_io_netty_channel_epoll_Native_isSupportingSendmmsg(JNIEnv *env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_isReuseAddresss(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_isReusePort(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_isTcpNoDelay(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getReceiveBufferSize(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getSendBufferSize(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_isTcpCork(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getSoLinger(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getTrafficClass(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_isBroadcast(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getTcpKeepIdle(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getTcpKeepIntvl(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_getTcpKeepCnt(JNIEnv* env, jclass clazz, jint fd);
jint Java_io_netty_channel_epoll_Native_errnoEBADF(JNIEnv *env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEPIPE(JNIEnv *env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEAGAIN(JNIEnv *env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEWOULDBLOCK(JNIEnv *env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEINPROGRESS(JNIEnv *env, jclass clazz);
jstring Java_io_netty_channel_epoll_Native_strError(JNIEnv *env, jclass clazz, jint err);
jstring Java_io_netty_channel_epoll_Native_kernelVersion(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_iovMax(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_uioMaxIov(JNIEnv* env, jclass clazz);
jboolean Java_io_netty_channel_epoll_Native_isSupportingSendmmsg(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEBADF(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEPIPE(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEAGAIN(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEWOULDBLOCK(JNIEnv* env, jclass clazz);
jint Java_io_netty_channel_epoll_Native_errnoEINPROGRESS(JNIEnv* env, jclass clazz);
jstring Java_io_netty_channel_epoll_Native_strError(JNIEnv* env, jclass clazz, jint err);

View File

@ -82,6 +82,22 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
config = new EpollSocketChannelConfig(this);
}
/**
* Returns the {@code TCP_INFO} for the current socket. See <a href="http://linux.die.net/man/7/tcp">man 7 tcp</a>.
*/
public EpollTcpInfo tcpInfo() {
return tcpInfo(new EpollTcpInfo());
}
/**
* Updates and returns the {@code TCP_INFO} for the current socket.
* See <a href="http://linux.die.net/man/7/tcp">man 7 tcp</a>.
*/
public EpollTcpInfo tcpInfo(EpollTcpInfo info) {
Native.tcpInfo(fd, info);
return info;
}
@Override
protected AbstractEpollUnsafe newUnsafe() {
return new EpollSocketUnsafe();

View File

@ -0,0 +1,193 @@
/*
* Copyright 2014 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.channel.epoll;
/**
* <p>
* struct tcp_info
* {
* __u8 tcpi_state;
* __u8 tcpi_ca_state;
* __u8 tcpi_retransmits;
* __u8 tcpi_probes;
* __u8 tcpi_backoff;
* __u8 tcpi_options;
* __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
*
* __u32 tcpi_rto;
* __u32 tcpi_ato;
* __u32 tcpi_snd_mss;
* __u32 tcpi_rcv_mss;
*
* __u32 tcpi_unacked;
* __u32 tcpi_sacked;
* __u32 tcpi_lost;
* __u32 tcpi_retrans;
* __u32 tcpi_fackets;
*
* __u32 tcpi_last_data_sent;
* __u32 tcpi_last_ack_sent;
* __u32 tcpi_last_data_recv;
* __u32 tcpi_last_ack_recv;
*
* __u32 tcpi_pmtu;
* __u32 tcpi_rcv_ssthresh;
* __u32 tcpi_rtt;
* __u32 tcpi_rttvar;
* __u32 tcpi_snd_ssthresh;
* __u32 tcpi_snd_cwnd;
* __u32 tcpi_advmss;
* __u32 tcpi_reordering;
*
* __u32 tcpi_rcv_rtt;
* __u32 tcpi_rcv_space;
*
* __u32 tcpi_total_retrans;
* };
* </p>
*/
public final class EpollTcpInfo {
final int[] info = new int[32];
public int state() {
return info[0] & 0xFF;
}
public int caState() {
return info[1] & 0xFF;
}
public int retransmits() {
return info[2] & 0xFF;
}
public int probes() {
return info[3] & 0xFF;
}
public int backoff() {
return info[4] & 0xFF;
}
public int options() {
return info[5] & 0xFF;
}
public int sndWscale() {
return info[6] & 0xFF;
}
public int rcvWscale() {
return info[7] & 0xFF;
}
public long rto() {
return info[8] & 0xFFFFFFFFL;
}
public long ato() {
return info[9] & 0xFFFFFFFFL;
}
public long sndMss() {
return info[10] & 0xFFFFFFFFL;
}
public long rcvMss() {
return info[11] & 0xFFFFFFFFL;
}
public long unacked() {
return info[12] & 0xFFFFFFFFL;
}
public long sacked() {
return info[13] & 0xFFFFFFFFL;
}
public long lost() {
return info[14] & 0xFFFFFFFFL;
}
public long retrans() {
return info[15] & 0xFFFFFFFFL;
}
public long fackets() {
return info[16] & 0xFFFFFFFFL;
}
public long lastDataSent() {
return info[17] & 0xFFFFFFFFL;
}
public long lastAckSent() {
return info[18] & 0xFFFFFFFFL;
}
public long lastDataRecv() {
return info[19] & 0xFFFFFFFFL;
}
public long lastAckRecv() {
return info[20] & 0xFFFFFFFFL;
}
public long pmtu() {
return info[21] & 0xFFFFFFFFL;
}
public long rcvSsthresh() {
return info[22] & 0xFFFFFFFFL;
}
public long rtt() {
return info[23] & 0xFFFFFFFFL;
}
public long rttvar() {
return info[24] & 0xFFFFFFFFL;
}
public long sndSsthresh() {
return info[25] & 0xFFFFFFFFL;
}
public long sndCwnd() {
return info[26] & 0xFFFFFFFFL;
}
public long advmss() {
return info[27] & 0xFFFFFFFFL;
}
public long reordering() {
return info[28] & 0xFFFFFFFFL;
}
public long rcvRtt() {
return info[29] & 0xFFFFFFFFL;
}
public long rcvSpace() {
return info[30] & 0xFFFFFFFFL;
}
public long totalRetrans() {
return info[31] & 0xFFFFFFFFL;
}
}

View File

@ -515,6 +515,12 @@ final class Native {
public static native void setTcpKeepIntvl(int fd, int seconds);
public static native void setTcpKeepCnt(int fd, int probes);
public static void tcpInfo(int fd, EpollTcpInfo info) {
tcpInfo0(fd, info.info);
}
private static native void tcpInfo0(int fd, int[] array);
private static NativeInetAddress toNativeInetAddress(InetAddress addr) {
byte[] bytes = addr.getAddress();
if (addr instanceof Inet6Address) {

View File

@ -0,0 +1,101 @@
/*
* Copyright 2014 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.channel.epoll;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoopGroup;
import org.junit.Assert;
import org.junit.Test;
import java.net.InetSocketAddress;
public class EpollSocketChannelTest {
@Test
public void testTcpInfo() throws Exception {
EventLoopGroup group = new EpollEventLoopGroup(1);
try {
Bootstrap bootstrap = new Bootstrap();
EpollSocketChannel ch = (EpollSocketChannel) bootstrap.group(group)
.channel(EpollSocketChannel.class)
.handler(new ChannelInboundHandlerAdapter())
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
EpollTcpInfo info = ch.tcpInfo();
assertTcpInfo0(info);
ch.close().syncUninterruptibly();
} finally {
group.shutdownGracefully();
}
}
@Test
public void testTcpInfoReuse() throws Exception {
EventLoopGroup group = new EpollEventLoopGroup(1);
try {
Bootstrap bootstrap = new Bootstrap();
EpollSocketChannel ch = (EpollSocketChannel) bootstrap.group(group)
.channel(EpollSocketChannel.class)
.handler(new ChannelInboundHandlerAdapter())
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
EpollTcpInfo info = new EpollTcpInfo();
ch.tcpInfo(info);
assertTcpInfo0(info);
ch.close().syncUninterruptibly();
} finally {
group.shutdownGracefully();
}
}
private static void assertTcpInfo0(EpollTcpInfo info) throws Exception {
Assert.assertNotNull(info);
Assert.assertTrue(info.state() >= 0);
Assert.assertTrue(info.caState() >= 0);
Assert.assertTrue(info.retransmits() >= 0);
Assert.assertTrue(info.probes() >= 0);
Assert.assertTrue(info.backoff() >= 0);
Assert.assertTrue(info.options() >= 0);
Assert.assertTrue(info.sndWscale() >= 0);
Assert.assertTrue(info.rcvWscale() >= 0);
Assert.assertTrue(info.rto() >= 0);
Assert.assertTrue(info.ato() >= 0);
Assert.assertTrue(info.sndMss() >= 0);
Assert.assertTrue(info.rcvMss() >= 0);
Assert.assertTrue(info.unacked() >= 0);
Assert.assertTrue(info.sacked() >= 0);
Assert.assertTrue(info.lost() >= 0);
Assert.assertTrue(info.retrans() >= 0);
Assert.assertTrue(info.fackets() >= 0);
Assert.assertTrue(info.lastDataSent() >= 0);
Assert.assertTrue(info.lastAckSent() >= 0);
Assert.assertTrue(info.lastDataRecv() >= 0);
Assert.assertTrue(info.lastAckRecv() >= 0);
Assert.assertTrue(info.pmtu() >= 0);
Assert.assertTrue(info.rcvSsthresh() >= 0);
Assert.assertTrue(info.rtt() >= 0);
Assert.assertTrue(info.rttvar() >= 0);
Assert.assertTrue(info.sndSsthresh() >= 0);
Assert.assertTrue(info.sndCwnd() >= 0);
Assert.assertTrue(info.advmss() >= 0);
Assert.assertTrue(info.reordering() >= 0);
Assert.assertTrue(info.rcvRtt() >= 0);
Assert.assertTrue(info.rcvSpace() >= 0);
Assert.assertTrue(info.totalRetrans() >= 0);
}
}