1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.unix;
17
18 import io.netty.channel.ChannelException;
19 import io.netty.channel.socket.InternetProtocolFamily;
20 import io.netty.util.CharsetUtil;
21 import io.netty.util.NetUtil;
22
23 import java.io.IOException;
24 import java.net.Inet6Address;
25 import java.net.InetAddress;
26 import java.net.InetSocketAddress;
27 import java.net.PortUnreachableException;
28 import java.net.SocketAddress;
29 import java.nio.ByteBuffer;
30 import java.nio.channels.ClosedChannelException;
31
32 import static io.netty.channel.unix.Errors.ERRNO_EAGAIN_NEGATIVE;
33 import static io.netty.channel.unix.Errors.ERRNO_EINPROGRESS_NEGATIVE;
34 import static io.netty.channel.unix.Errors.ERRNO_EWOULDBLOCK_NEGATIVE;
35 import static io.netty.channel.unix.Errors.ERROR_ECONNREFUSED_NEGATIVE;
36 import static io.netty.channel.unix.Errors.handleConnectErrno;
37 import static io.netty.channel.unix.Errors.ioResult;
38 import static io.netty.channel.unix.Errors.newIOException;
39 import static io.netty.channel.unix.NativeInetAddress.address;
40 import static io.netty.channel.unix.NativeInetAddress.ipv4MappedIpv6Address;
41
42
43
44
45
46 public class Socket extends FileDescriptor {
47
48 private static volatile boolean isIpv6Preferred;
49
50 @Deprecated
51 public static final int UDS_SUN_PATH_SIZE = 100;
52
53 protected final boolean ipv6;
54
55 public Socket(int fd) {
56 super(fd);
57 ipv6 = isIPv6(fd);
58 }
59
60
61
62 private boolean useIpv6(InetAddress address) {
63 return useIpv6(this, address);
64 }
65
66
67
68
69
70 protected static boolean useIpv6(Socket socket, InetAddress address) {
71 return socket.ipv6 || address instanceof Inet6Address;
72 }
73
74 public final void shutdown() throws IOException {
75 shutdown(true, true);
76 }
77
78 public final void shutdown(boolean read, boolean write) throws IOException {
79 for (;;) {
80
81
82
83
84 final int oldState = state;
85 if (isClosed(oldState)) {
86 throw new ClosedChannelException();
87 }
88 int newState = oldState;
89 if (read && !isInputShutdown(newState)) {
90 newState = inputShutdown(newState);
91 }
92 if (write && !isOutputShutdown(newState)) {
93 newState = outputShutdown(newState);
94 }
95
96
97 if (newState == oldState) {
98 return;
99 }
100 if (casState(oldState, newState)) {
101 break;
102 }
103 }
104 int res = shutdown(fd, read, write);
105 if (res < 0) {
106 ioResult("shutdown", res);
107 }
108 }
109
110 public final boolean isShutdown() {
111 int state = this.state;
112 return isInputShutdown(state) && isOutputShutdown(state);
113 }
114
115 public final boolean isInputShutdown() {
116 return isInputShutdown(state);
117 }
118
119 public final boolean isOutputShutdown() {
120 return isOutputShutdown(state);
121 }
122
123 public final int sendTo(ByteBuffer buf, int pos, int limit, InetAddress addr, int port) throws IOException {
124 return sendTo(buf, pos, limit, addr, port, false);
125 }
126
127 public final int sendTo(ByteBuffer buf, int pos, int limit, InetAddress addr, int port, boolean fastOpen)
128 throws IOException {
129
130
131 byte[] address;
132 int scopeId;
133 if (addr instanceof Inet6Address) {
134 address = addr.getAddress();
135 scopeId = ((Inet6Address) addr).getScopeId();
136 } else {
137
138 scopeId = 0;
139 address = ipv4MappedIpv6Address(addr.getAddress());
140 }
141 int flags = fastOpen ? msgFastopen() : 0;
142 int res = sendTo(fd, useIpv6(addr), buf, pos, limit, address, scopeId, port, flags);
143 if (res >= 0) {
144 return res;
145 }
146 if (res == ERRNO_EINPROGRESS_NEGATIVE && fastOpen) {
147
148
149
150 return 0;
151 }
152 if (res == ERROR_ECONNREFUSED_NEGATIVE) {
153 throw new PortUnreachableException("sendTo failed");
154 }
155 return ioResult("sendTo", res);
156 }
157
158 public final int sendToDomainSocket(ByteBuffer buf, int pos, int limit, byte[] path) throws IOException {
159 int res = sendToDomainSocket(fd, buf, pos, limit, path);
160 if (res >= 0) {
161 return res;
162 }
163 return ioResult("sendToDomainSocket", res);
164 }
165
166 public final int sendToAddress(long memoryAddress, int pos, int limit, InetAddress addr, int port)
167 throws IOException {
168 return sendToAddress(memoryAddress, pos, limit, addr, port, false);
169 }
170
171 public final int sendToAddress(long memoryAddress, int pos, int limit, InetAddress addr, int port,
172 boolean fastOpen) throws IOException {
173
174
175 byte[] address;
176 int scopeId;
177 if (addr instanceof Inet6Address) {
178 address = addr.getAddress();
179 scopeId = ((Inet6Address) addr).getScopeId();
180 } else {
181
182 scopeId = 0;
183 address = ipv4MappedIpv6Address(addr.getAddress());
184 }
185 int flags = fastOpen ? msgFastopen() : 0;
186 int res = sendToAddress(fd, useIpv6(addr), memoryAddress, pos, limit, address, scopeId, port, flags);
187 if (res >= 0) {
188 return res;
189 }
190 if (res == ERRNO_EINPROGRESS_NEGATIVE && fastOpen) {
191
192
193
194 return 0;
195 }
196 if (res == ERROR_ECONNREFUSED_NEGATIVE) {
197 throw new PortUnreachableException("sendToAddress failed");
198 }
199 return ioResult("sendToAddress", res);
200 }
201
202 public final int sendToAddressDomainSocket(long memoryAddress, int pos, int limit, byte[] path) throws IOException {
203 int res = sendToAddressDomainSocket(fd, memoryAddress, pos, limit, path);
204 if (res >= 0) {
205 return res;
206 }
207 return ioResult("sendToAddressDomainSocket", res);
208 }
209
210 public final int sendToAddresses(long memoryAddress, int length, InetAddress addr, int port) throws IOException {
211 return sendToAddresses(memoryAddress, length, addr, port, false);
212 }
213
214 public final int sendToAddresses(long memoryAddress, int length, InetAddress addr, int port, boolean fastOpen)
215 throws IOException {
216
217
218 byte[] address;
219 int scopeId;
220 if (addr instanceof Inet6Address) {
221 address = addr.getAddress();
222 scopeId = ((Inet6Address) addr).getScopeId();
223 } else {
224
225 scopeId = 0;
226 address = ipv4MappedIpv6Address(addr.getAddress());
227 }
228 int flags = fastOpen ? msgFastopen() : 0;
229 int res = sendToAddresses(fd, useIpv6(addr), memoryAddress, length, address, scopeId, port, flags);
230 if (res >= 0) {
231 return res;
232 }
233 if (res == ERRNO_EINPROGRESS_NEGATIVE && fastOpen) {
234
235
236
237 return 0;
238 }
239 if (res == ERROR_ECONNREFUSED_NEGATIVE) {
240 throw new PortUnreachableException("sendToAddresses failed");
241 }
242 return ioResult("sendToAddresses", res);
243 }
244
245 public final int sendToAddressesDomainSocket(long memoryAddress, int length, byte[] path) throws IOException {
246 int res = sendToAddressesDomainSocket(fd, memoryAddress, length, path);
247 if (res >= 0) {
248 return res;
249 }
250 return ioResult("sendToAddressesDomainSocket", res);
251 }
252
253 public final DatagramSocketAddress recvFrom(ByteBuffer buf, int pos, int limit) throws IOException {
254 return recvFrom(fd, buf, pos, limit);
255 }
256
257 public final DatagramSocketAddress recvFromAddress(long memoryAddress, int pos, int limit) throws IOException {
258 return recvFromAddress(fd, memoryAddress, pos, limit);
259 }
260
261 public final DomainDatagramSocketAddress recvFromDomainSocket(ByteBuffer buf, int pos, int limit)
262 throws IOException {
263 return recvFromDomainSocket(fd, buf, pos, limit);
264 }
265
266 public final DomainDatagramSocketAddress recvFromAddressDomainSocket(long memoryAddress, int pos, int limit)
267 throws IOException {
268 return recvFromAddressDomainSocket(fd, memoryAddress, pos, limit);
269 }
270
271 public int recv(ByteBuffer buf, int pos, int limit) throws IOException {
272 int res = recv(intValue(), buf, pos, limit);
273 if (res > 0) {
274 return res;
275 }
276 if (res == 0) {
277 return -1;
278 }
279 return ioResult("recv", res);
280 }
281
282 public int recvAddress(long address, int pos, int limit) throws IOException {
283 int res = recvAddress(intValue(), address, pos, limit);
284 if (res > 0) {
285 return res;
286 }
287 if (res == 0) {
288 return -1;
289 }
290 return ioResult("recvAddress", res);
291 }
292
293 public int send(ByteBuffer buf, int pos, int limit) throws IOException {
294 int res = send(intValue(), buf, pos, limit);
295 if (res >= 0) {
296 return res;
297 }
298 return ioResult("send", res);
299 }
300
301 public int sendAddress(long address, int pos, int limit) throws IOException {
302 int res = sendAddress(intValue(), address, pos, limit);
303 if (res >= 0) {
304 return res;
305 }
306 return ioResult("sendAddress", res);
307 }
308
309 public final int recvFd() throws IOException {
310 int res = recvFd(fd);
311 if (res > 0) {
312 return res;
313 }
314 if (res == 0) {
315 return -1;
316 }
317
318 if (res == ERRNO_EAGAIN_NEGATIVE || res == ERRNO_EWOULDBLOCK_NEGATIVE) {
319
320 return 0;
321 }
322 throw newIOException("recvFd", res);
323 }
324
325 public final int sendFd(int fdToSend) throws IOException {
326 int res = sendFd(fd, fdToSend);
327 if (res >= 0) {
328 return res;
329 }
330 if (res == ERRNO_EAGAIN_NEGATIVE || res == ERRNO_EWOULDBLOCK_NEGATIVE) {
331
332 return -1;
333 }
334 throw newIOException("sendFd", res);
335 }
336
337 public final boolean connect(SocketAddress socketAddress) throws IOException {
338 int res;
339 if (socketAddress instanceof InetSocketAddress) {
340 InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress;
341 InetAddress inetAddress = inetSocketAddress.getAddress();
342 NativeInetAddress address = NativeInetAddress.newInstance(inetAddress);
343 res = connect(fd, useIpv6(inetAddress), address.address, address.scopeId, inetSocketAddress.getPort());
344 } else if (socketAddress instanceof DomainSocketAddress) {
345 DomainSocketAddress unixDomainSocketAddress = (DomainSocketAddress) socketAddress;
346 res = connectDomainSocket(fd, unixDomainSocketAddress.path().getBytes(CharsetUtil.UTF_8));
347 } else {
348 throw new Error("Unexpected SocketAddress implementation " + socketAddress);
349 }
350 if (res < 0) {
351 return handleConnectErrno("connect", res);
352 }
353 return true;
354 }
355
356 public final boolean finishConnect() throws IOException {
357 int res = finishConnect(fd);
358 if (res < 0) {
359 return handleConnectErrno("finishConnect", res);
360 }
361 return true;
362 }
363
364 public final void disconnect() throws IOException {
365 int res = disconnect(fd, ipv6);
366 if (res < 0) {
367 handleConnectErrno("disconnect", res);
368 }
369 }
370
371 public final void bind(SocketAddress socketAddress) throws IOException {
372 if (socketAddress instanceof InetSocketAddress) {
373 InetSocketAddress addr = (InetSocketAddress) socketAddress;
374 InetAddress inetAddress = addr.getAddress();
375 NativeInetAddress address = NativeInetAddress.newInstance(inetAddress);
376 int res = bind(fd, useIpv6(inetAddress), address.address, address.scopeId, addr.getPort());
377 if (res < 0) {
378 throw newIOException("bind", res);
379 }
380 } else if (socketAddress instanceof DomainSocketAddress) {
381 DomainSocketAddress addr = (DomainSocketAddress) socketAddress;
382 int res = bindDomainSocket(fd, addr.path().getBytes(CharsetUtil.UTF_8));
383 if (res < 0) {
384 throw newIOException("bind", res);
385 }
386 } else {
387 throw new Error("Unexpected SocketAddress implementation " + socketAddress);
388 }
389 }
390
391 public final void listen(int backlog) throws IOException {
392 int res = listen(fd, backlog);
393 if (res < 0) {
394 throw newIOException("listen", res);
395 }
396 }
397
398 public final int accept(byte[] addr) throws IOException {
399 int res = accept(fd, addr);
400 if (res >= 0) {
401 return res;
402 }
403 if (res == ERRNO_EAGAIN_NEGATIVE || res == ERRNO_EWOULDBLOCK_NEGATIVE) {
404
405 return -1;
406 }
407 throw newIOException("accept", res);
408 }
409
410 public final InetSocketAddress remoteAddress() {
411 byte[] addr = remoteAddress(fd);
412
413
414 return addr == null ? null : address(addr, 0, addr.length);
415 }
416
417 public final DomainSocketAddress remoteDomainSocketAddress() {
418 byte[] addr = remoteDomainSocketAddress(fd);
419 return addr == null ? null : new DomainSocketAddress(new String(addr));
420 }
421
422 public final InetSocketAddress localAddress() {
423 byte[] addr = localAddress(fd);
424
425
426 return addr == null ? null : address(addr, 0, addr.length);
427 }
428
429 public final DomainSocketAddress localDomainSocketAddress() {
430 byte[] addr = localDomainSocketAddress(fd);
431 return addr == null ? null : new DomainSocketAddress(new String(addr));
432 }
433
434 public final int getReceiveBufferSize() throws IOException {
435 return getReceiveBufferSize(fd);
436 }
437
438 public final int getSendBufferSize() throws IOException {
439 return getSendBufferSize(fd);
440 }
441
442 public final boolean isKeepAlive() throws IOException {
443 return isKeepAlive(fd) != 0;
444 }
445
446 public final boolean isTcpNoDelay() throws IOException {
447 return isTcpNoDelay(fd) != 0;
448 }
449
450 public final boolean isReuseAddress() throws IOException {
451 return isReuseAddress(fd) != 0;
452 }
453
454 public final boolean isReusePort() throws IOException {
455 return isReusePort(fd) != 0;
456 }
457
458 public final boolean isBroadcast() throws IOException {
459 return isBroadcast(fd) != 0;
460 }
461
462 public final int getSoLinger() throws IOException {
463 return getSoLinger(fd);
464 }
465
466 public final int getSoError() throws IOException {
467 return getSoError(fd);
468 }
469
470 public final int getTrafficClass() throws IOException {
471 return getTrafficClass(fd, ipv6);
472 }
473
474 public final void setKeepAlive(boolean keepAlive) throws IOException {
475 setKeepAlive(fd, keepAlive ? 1 : 0);
476 }
477
478 public final void setReceiveBufferSize(int receiveBufferSize) throws IOException {
479 setReceiveBufferSize(fd, receiveBufferSize);
480 }
481
482 public final void setSendBufferSize(int sendBufferSize) throws IOException {
483 setSendBufferSize(fd, sendBufferSize);
484 }
485
486 public final void setTcpNoDelay(boolean tcpNoDelay) throws IOException {
487 setTcpNoDelay(fd, tcpNoDelay ? 1 : 0);
488 }
489
490 public final void setSoLinger(int soLinger) throws IOException {
491 setSoLinger(fd, soLinger);
492 }
493
494 public final void setReuseAddress(boolean reuseAddress) throws IOException {
495 setReuseAddress(fd, reuseAddress ? 1 : 0);
496 }
497
498 public final void setReusePort(boolean reusePort) throws IOException {
499 setReusePort(fd, reusePort ? 1 : 0);
500 }
501
502 public final void setBroadcast(boolean broadcast) throws IOException {
503 setBroadcast(fd, broadcast ? 1 : 0);
504 }
505
506 public final void setTrafficClass(int trafficClass) throws IOException {
507 setTrafficClass(fd, ipv6, trafficClass);
508 }
509
510 public void setIntOpt(int level, int optname, int optvalue) throws IOException {
511 setIntOpt(fd, level, optname, optvalue);
512 }
513
514 public void setRawOpt(int level, int optname, ByteBuffer optvalue) throws IOException {
515 int limit = optvalue.limit();
516 if (optvalue.isDirect()) {
517 setRawOptAddress(fd, level, optname,
518 Buffer.memoryAddress(optvalue) + optvalue.position(), optvalue.remaining());
519 } else if (optvalue.hasArray()) {
520 setRawOptArray(fd, level, optname,
521 optvalue.array(), optvalue.arrayOffset() + optvalue.position(), optvalue.remaining());
522 } else {
523 byte[] bytes = new byte[optvalue.remaining()];
524 optvalue.duplicate().get(bytes);
525 setRawOptArray(fd, level, optname, bytes, 0, bytes.length);
526 }
527 optvalue.position(limit);
528 }
529
530 public int getIntOpt(int level, int optname) throws IOException {
531 return getIntOpt(fd, level, optname);
532 }
533
534 public void getRawOpt(int level, int optname, ByteBuffer out) throws IOException {
535 if (out.isDirect()) {
536 getRawOptAddress(fd, level, optname, Buffer.memoryAddress(out) + out.position() , out.remaining());
537 } else if (out.hasArray()) {
538 getRawOptArray(fd, level, optname, out.array(), out.position() + out.arrayOffset(), out.remaining());
539 } else {
540 byte[] outArray = new byte[out.remaining()];
541 getRawOptArray(fd, level, optname, outArray, 0, outArray.length);
542 out.put(outArray);
543 }
544 out.position(out.limit());
545 }
546
547 public static boolean isIPv6Preferred() {
548 return isIpv6Preferred;
549 }
550
551 public static boolean shouldUseIpv6(InternetProtocolFamily family) {
552 return family == null ? isIPv6Preferred() :
553 family == InternetProtocolFamily.IPv6;
554 }
555
556 private static native boolean isIPv6Preferred0(boolean ipv4Preferred);
557
558 private static native boolean isIPv6(int fd);
559
560 @Override
561 public String toString() {
562 return "Socket{" +
563 "fd=" + fd +
564 '}';
565 }
566
567 public static Socket newSocketStream() {
568 return new Socket(newSocketStream0());
569 }
570
571 public static Socket newSocketDgram() {
572 return new Socket(newSocketDgram0());
573 }
574
575 public static Socket newSocketDomain() {
576 return new Socket(newSocketDomain0());
577 }
578
579 public static Socket newSocketDomainDgram() {
580 return new Socket(newSocketDomainDgram0());
581 }
582
583 public static void initialize() {
584 isIpv6Preferred = isIPv6Preferred0(NetUtil.isIpV4StackPreferred());
585 }
586
587 protected static int newSocketStream0() {
588 return newSocketStream0(isIPv6Preferred());
589 }
590
591 protected static int newSocketStream0(InternetProtocolFamily protocol) {
592 return newSocketStream0(shouldUseIpv6(protocol));
593 }
594
595 protected static int newSocketStream0(boolean ipv6) {
596 int res = newSocketStreamFd(ipv6);
597 if (res < 0) {
598 throw new ChannelException(newIOException("newSocketStream", res));
599 }
600 return res;
601 }
602
603 protected static int newSocketDgram0() {
604 return newSocketDgram0(isIPv6Preferred());
605 }
606
607 protected static int newSocketDgram0(InternetProtocolFamily family) {
608 return newSocketDgram0(shouldUseIpv6(family));
609 }
610
611 protected static int newSocketDgram0(boolean ipv6) {
612 int res = newSocketDgramFd(ipv6);
613 if (res < 0) {
614 throw new ChannelException(newIOException("newSocketDgram", res));
615 }
616 return res;
617 }
618
619 protected static int newSocketDomain0() {
620 int res = newSocketDomainFd();
621 if (res < 0) {
622 throw new ChannelException(newIOException("newSocketDomain", res));
623 }
624 return res;
625 }
626
627 protected static int newSocketDomainDgram0() {
628 int res = newSocketDomainDgramFd();
629 if (res < 0) {
630 throw new ChannelException(newIOException("newSocketDomainDgram", res));
631 }
632 return res;
633 }
634
635 private static native int shutdown(int fd, boolean read, boolean write);
636 private static native int connect(int fd, boolean ipv6, byte[] address, int scopeId, int port);
637 private static native int connectDomainSocket(int fd, byte[] path);
638 private static native int finishConnect(int fd);
639 private static native int disconnect(int fd, boolean ipv6);
640 private static native int bind(int fd, boolean ipv6, byte[] address, int scopeId, int port);
641 private static native int bindDomainSocket(int fd, byte[] path);
642 private static native int listen(int fd, int backlog);
643 private static native int accept(int fd, byte[] addr);
644
645 private static native byte[] remoteAddress(int fd);
646 private static native byte[] remoteDomainSocketAddress(int fd);
647 private static native byte[] localAddress(int fd);
648 private static native byte[] localDomainSocketAddress(int fd);
649
650 private static native int send(int fd, ByteBuffer buf, int pos, int limit);
651 private static native int sendAddress(int fd, long address, int pos, int limit);
652 private static native int recv(int fd, ByteBuffer buf, int pos, int limit);
653
654 private static native int recvAddress(int fd, long address, int pos, int limit);
655
656 private static native int sendTo(
657 int fd, boolean ipv6, ByteBuffer buf, int pos, int limit, byte[] address, int scopeId, int port,
658 int flags);
659
660 private static native int sendToAddress(
661 int fd, boolean ipv6, long memoryAddress, int pos, int limit, byte[] address, int scopeId, int port,
662 int flags);
663
664 private static native int sendToAddresses(
665 int fd, boolean ipv6, long memoryAddress, int length, byte[] address, int scopeId, int port,
666 int flags);
667
668 private static native int sendToDomainSocket(int fd, ByteBuffer buf, int pos, int limit, byte[] path);
669 private static native int sendToAddressDomainSocket(int fd, long memoryAddress, int pos, int limit, byte[] path);
670 private static native int sendToAddressesDomainSocket(int fd, long memoryAddress, int length, byte[] path);
671
672 private static native DatagramSocketAddress recvFrom(
673 int fd, ByteBuffer buf, int pos, int limit) throws IOException;
674 private static native DatagramSocketAddress recvFromAddress(
675 int fd, long memoryAddress, int pos, int limit) throws IOException;
676 private static native DomainDatagramSocketAddress recvFromDomainSocket(
677 int fd, ByteBuffer buf, int pos, int limit) throws IOException;
678 private static native DomainDatagramSocketAddress recvFromAddressDomainSocket(
679 int fd, long memoryAddress, int pos, int limit) throws IOException;
680 private static native int recvFd(int fd);
681 private static native int sendFd(int socketFd, int fd);
682 private static native int msgFastopen();
683
684 private static native int newSocketStreamFd(boolean ipv6);
685 private static native int newSocketDgramFd(boolean ipv6);
686 private static native int newSocketDomainFd();
687 private static native int newSocketDomainDgramFd();
688
689 private static native int isReuseAddress(int fd) throws IOException;
690 private static native int isReusePort(int fd) throws IOException;
691 private static native int getReceiveBufferSize(int fd) throws IOException;
692 private static native int getSendBufferSize(int fd) throws IOException;
693 private static native int isKeepAlive(int fd) throws IOException;
694 private static native int isTcpNoDelay(int fd) throws IOException;
695 private static native int isBroadcast(int fd) throws IOException;
696 private static native int getSoLinger(int fd) throws IOException;
697 private static native int getSoError(int fd) throws IOException;
698 private static native int getTrafficClass(int fd, boolean ipv6) throws IOException;
699
700 private static native void setReuseAddress(int fd, int reuseAddress) throws IOException;
701 private static native void setReusePort(int fd, int reuseAddress) throws IOException;
702 private static native void setKeepAlive(int fd, int keepAlive) throws IOException;
703 private static native void setReceiveBufferSize(int fd, int receiveBufferSize) throws IOException;
704 private static native void setSendBufferSize(int fd, int sendBufferSize) throws IOException;
705 private static native void setTcpNoDelay(int fd, int tcpNoDelay) throws IOException;
706 private static native void setSoLinger(int fd, int soLinger) throws IOException;
707 private static native void setBroadcast(int fd, int broadcast) throws IOException;
708 private static native void setTrafficClass(int fd, boolean ipv6, int trafficClass) throws IOException;
709
710 private static native void setIntOpt(int fd, int level, int optname, int optvalue) throws IOException;
711 private static native void setRawOptArray(int fd, int level, int optname, byte[] optvalue, int offset, int length)
712 throws IOException;
713 private static native void setRawOptAddress(int fd, int level, int optname, long optvalueMemoryAddress, int length)
714 throws IOException;
715 private static native int getIntOpt(int fd, int level, int optname) throws IOException;
716 private static native void getRawOptArray(int fd, int level, int optname, byte[] out, int offset, int length)
717 throws IOException;
718 private static native void getRawOptAddress(int fd, int level, int optname, long outMemoryAddress, int length)
719 throws IOException;
720 }