Skip to content

Commit efb2d14

Browse files
committed
Correctly handle unsigned int values returned from TCP_INFO
Motivation: We used an int[] to store all values that are returned in the struct for TCP_INFO which is not good enough as it uses usigned int values. Modifications: - Change int[] to long[] and correctly cast values. Result: No more truncated values.
1 parent 34fdc7a commit efb2d14

File tree

3 files changed

+72
-71
lines changed

3 files changed

+72
-71
lines changed

transport-native-epoll/src/main/c/netty_epoll_linuxsocket.c

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -178,46 +178,47 @@ static jint netty_epoll_linuxsocket_isIpTransparent(JNIEnv* env, jclass clazz, j
178178
return optval;
179179
}
180180

181-
static void netty_epoll_linuxsocket_getTcpInfo(JNIEnv* env, jclass clazz, jint fd, jintArray array) {
181+
static void netty_epoll_linuxsocket_getTcpInfo(JNIEnv* env, jclass clazz, jint fd, jlongArray array) {
182182
struct tcp_info tcp_info;
183183
if (netty_unix_socket_getOption(env, fd, IPPROTO_TCP, TCP_INFO, &tcp_info, sizeof(tcp_info)) == -1) {
184184
return;
185185
}
186-
unsigned int cArray[32];
187-
cArray[0] = tcp_info.tcpi_state;
188-
cArray[1] = tcp_info.tcpi_ca_state;
189-
cArray[2] = tcp_info.tcpi_retransmits;
190-
cArray[3] = tcp_info.tcpi_probes;
191-
cArray[4] = tcp_info.tcpi_backoff;
192-
cArray[5] = tcp_info.tcpi_options;
193-
cArray[6] = tcp_info.tcpi_snd_wscale;
194-
cArray[7] = tcp_info.tcpi_rcv_wscale;
195-
cArray[8] = tcp_info.tcpi_rto;
196-
cArray[9] = tcp_info.tcpi_ato;
197-
cArray[10] = tcp_info.tcpi_snd_mss;
198-
cArray[11] = tcp_info.tcpi_rcv_mss;
199-
cArray[12] = tcp_info.tcpi_unacked;
200-
cArray[13] = tcp_info.tcpi_sacked;
201-
cArray[14] = tcp_info.tcpi_lost;
202-
cArray[15] = tcp_info.tcpi_retrans;
203-
cArray[16] = tcp_info.tcpi_fackets;
204-
cArray[17] = tcp_info.tcpi_last_data_sent;
205-
cArray[18] = tcp_info.tcpi_last_ack_sent;
206-
cArray[19] = tcp_info.tcpi_last_data_recv;
207-
cArray[20] = tcp_info.tcpi_last_ack_recv;
208-
cArray[21] = tcp_info.tcpi_pmtu;
209-
cArray[22] = tcp_info.tcpi_rcv_ssthresh;
210-
cArray[23] = tcp_info.tcpi_rtt;
211-
cArray[24] = tcp_info.tcpi_rttvar;
212-
cArray[25] = tcp_info.tcpi_snd_ssthresh;
213-
cArray[26] = tcp_info.tcpi_snd_cwnd;
214-
cArray[27] = tcp_info.tcpi_advmss;
215-
cArray[28] = tcp_info.tcpi_reordering;
216-
cArray[29] = tcp_info.tcpi_rcv_rtt;
217-
cArray[30] = tcp_info.tcpi_rcv_space;
218-
cArray[31] = tcp_info.tcpi_total_retrans;
219-
220-
(*env)->SetIntArrayRegion(env, array, 0, 32, cArray);
186+
jlong cArray[32];
187+
// Expand to 64 bits, then cast away unsigned-ness.
188+
cArray[0] = (jlong) (uint64_t) tcp_info.tcpi_state;
189+
cArray[1] = (jlong) (uint64_t) tcp_info.tcpi_ca_state;
190+
cArray[2] = (jlong) (uint64_t) tcp_info.tcpi_retransmits;
191+
cArray[3] = (jlong) (uint64_t) tcp_info.tcpi_probes;
192+
cArray[4] = (jlong) (uint64_t) tcp_info.tcpi_backoff;
193+
cArray[5] = (jlong) (uint64_t) tcp_info.tcpi_options;
194+
cArray[6] = (jlong) (uint64_t) tcp_info.tcpi_snd_wscale;
195+
cArray[7] = (jlong) (uint64_t) tcp_info.tcpi_rcv_wscale;
196+
cArray[8] = (jlong) (uint64_t) tcp_info.tcpi_rto;
197+
cArray[9] = (jlong) (uint64_t) tcp_info.tcpi_ato;
198+
cArray[10] = (jlong) (uint64_t) tcp_info.tcpi_snd_mss;
199+
cArray[11] = (jlong) (uint64_t) tcp_info.tcpi_rcv_mss;
200+
cArray[12] = (jlong) (uint64_t) tcp_info.tcpi_unacked;
201+
cArray[13] = (jlong) (uint64_t) tcp_info.tcpi_sacked;
202+
cArray[14] = (jlong) (uint64_t) tcp_info.tcpi_lost;
203+
cArray[15] = (jlong) (uint64_t) tcp_info.tcpi_retrans;
204+
cArray[16] = (jlong) (uint64_t) tcp_info.tcpi_fackets;
205+
cArray[17] = (jlong) (uint64_t) tcp_info.tcpi_last_data_sent;
206+
cArray[18] = (jlong) (uint64_t) tcp_info.tcpi_last_ack_sent;
207+
cArray[19] = (jlong) (uint64_t) tcp_info.tcpi_last_data_recv;
208+
cArray[20] = (jlong) (uint64_t) tcp_info.tcpi_last_ack_recv;
209+
cArray[21] = (jlong) (uint64_t) tcp_info.tcpi_pmtu;
210+
cArray[22] = (jlong) (uint64_t) tcp_info.tcpi_rcv_ssthresh;
211+
cArray[23] = (jlong) (uint64_t) tcp_info.tcpi_rtt;
212+
cArray[24] = (jlong) (uint64_t) tcp_info.tcpi_rttvar;
213+
cArray[25] = (jlong) (uint64_t) tcp_info.tcpi_snd_ssthresh;
214+
cArray[26] = (jlong) (uint64_t) tcp_info.tcpi_snd_cwnd;
215+
cArray[27] = (jlong) (uint64_t) tcp_info.tcpi_advmss;
216+
cArray[28] = (jlong) (uint64_t) tcp_info.tcpi_reordering;
217+
cArray[29] = (jlong) (uint64_t) tcp_info.tcpi_rcv_rtt;
218+
cArray[30] = (jlong) (uint64_t) tcp_info.tcpi_rcv_space;
219+
cArray[31] = (jlong) (uint64_t) tcp_info.tcpi_total_retrans;
220+
221+
(*env)->SetLongArrayRegion(env, array, 0, 32, cArray);
221222
}
222223

223224
static jint netty_epoll_linuxsocket_isTcpCork(JNIEnv* env, jclass clazz, jint fd) {
@@ -286,7 +287,7 @@ static const JNINativeMethod fixed_method_table[] = {
286287
{ "getTcpUserTimeout", "(I)I", (void *) netty_epoll_linuxsocket_getTcpUserTimeout },
287288
{ "isIpFreeBind", "(I)I", (void *) netty_epoll_linuxsocket_isIpFreeBind },
288289
{ "isIpTransparent", "(I)I", (void *) netty_epoll_linuxsocket_isIpTransparent },
289-
{ "getTcpInfo", "(I[I)V", (void *) netty_epoll_linuxsocket_getTcpInfo },
290+
{ "getTcpInfo", "(I[J)V", (void *) netty_epoll_linuxsocket_getTcpInfo },
290291
{ "setTcpMd5Sig", "(I[BI[B)V", (void *) netty_epoll_linuxsocket_setTcpMd5Sig }
291292
};
292293

transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollTcpInfo.java

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -61,133 +61,133 @@
6161
*/
6262
public final class EpollTcpInfo {
6363

64-
final int[] info = new int[32];
64+
final long[] info = new long[32];
6565

6666
public int state() {
67-
return info[0] & 0xFF;
67+
return (int) info[0];
6868
}
6969

7070
public int caState() {
71-
return info[1] & 0xFF;
71+
return (int) info[1];
7272
}
7373

7474
public int retransmits() {
75-
return info[2] & 0xFF;
75+
return (int) info[2];
7676
}
7777

7878
public int probes() {
79-
return info[3] & 0xFF;
79+
return (int) info[3];
8080
}
8181

8282
public int backoff() {
83-
return info[4] & 0xFF;
83+
return (int) info[4];
8484
}
8585

8686
public int options() {
87-
return info[5] & 0xFF;
87+
return (int) info[5];
8888
}
8989

9090
public int sndWscale() {
91-
return info[6] & 0xFF;
91+
return (int) info[6];
9292
}
9393

9494
public int rcvWscale() {
95-
return info[7] & 0xFF;
95+
return (int) info[7];
9696
}
9797

9898
public long rto() {
99-
return info[8] & 0xFFFFFFFFL;
99+
return info[8];
100100
}
101101

102102
public long ato() {
103-
return info[9] & 0xFFFFFFFFL;
103+
return info[9];
104104
}
105105

106106
public long sndMss() {
107-
return info[10] & 0xFFFFFFFFL;
107+
return info[10];
108108
}
109109

110110
public long rcvMss() {
111-
return info[11] & 0xFFFFFFFFL;
111+
return info[11];
112112
}
113113

114114
public long unacked() {
115-
return info[12] & 0xFFFFFFFFL;
115+
return info[12];
116116
}
117117

118118
public long sacked() {
119-
return info[13] & 0xFFFFFFFFL;
119+
return info[13];
120120
}
121121

122122
public long lost() {
123-
return info[14] & 0xFFFFFFFFL;
123+
return info[14];
124124
}
125125

126126
public long retrans() {
127-
return info[15] & 0xFFFFFFFFL;
127+
return info[15];
128128
}
129129

130130
public long fackets() {
131-
return info[16] & 0xFFFFFFFFL;
131+
return info[16];
132132
}
133133

134134
public long lastDataSent() {
135-
return info[17] & 0xFFFFFFFFL;
135+
return info[17];
136136
}
137137

138138
public long lastAckSent() {
139-
return info[18] & 0xFFFFFFFFL;
139+
return info[18];
140140
}
141141

142142
public long lastDataRecv() {
143-
return info[19] & 0xFFFFFFFFL;
143+
return info[19];
144144
}
145145

146146
public long lastAckRecv() {
147-
return info[20] & 0xFFFFFFFFL;
147+
return info[20];
148148
}
149149

150150
public long pmtu() {
151-
return info[21] & 0xFFFFFFFFL;
151+
return info[21];
152152
}
153153

154154
public long rcvSsthresh() {
155-
return info[22] & 0xFFFFFFFFL;
155+
return info[22];
156156
}
157157

158158
public long rtt() {
159-
return info[23] & 0xFFFFFFFFL;
159+
return info[23];
160160
}
161161

162162
public long rttvar() {
163-
return info[24] & 0xFFFFFFFFL;
163+
return info[24];
164164
}
165165

166166
public long sndSsthresh() {
167-
return info[25] & 0xFFFFFFFFL;
167+
return info[25];
168168
}
169169

170170
public long sndCwnd() {
171-
return info[26] & 0xFFFFFFFFL;
171+
return info[26];
172172
}
173173

174174
public long advmss() {
175-
return info[27] & 0xFFFFFFFFL;
175+
return info[27];
176176
}
177177

178178
public long reordering() {
179-
return info[28] & 0xFFFFFFFFL;
179+
return info[28];
180180
}
181181

182182
public long rcvRtt() {
183-
return info[29] & 0xFFFFFFFFL;
183+
return info[29];
184184
}
185185

186186
public long rcvSpace() {
187-
return info[30] & 0xFFFFFFFFL;
187+
return info[30];
188188
}
189189

190190
public long totalRetrans() {
191-
return info[31] & 0xFFFFFFFFL;
191+
return info[31];
192192
}
193193
}

transport-native-epoll/src/main/java/io/netty/channel/epoll/LinuxSocket.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public static LinuxSocket newSocketDomain() {
154154
private static native int getTcpUserTimeout(int fd) throws IOException;
155155
private static native int isIpFreeBind(int fd) throws IOException;
156156
private static native int isIpTransparent(int fd) throws IOException;
157-
private static native void getTcpInfo(int fd, int[] array) throws IOException;
157+
private static native void getTcpInfo(int fd, long[] array) throws IOException;
158158
private static native PeerCredentials getPeerCredentials(int fd) throws IOException;
159159

160160
private static native void setTcpDeferAccept(int fd, int deferAccept) throws IOException;

0 commit comments

Comments
 (0)