• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.net;
28 
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.io.FileDescriptor;
33 
34 import dalvik.annotation.optimization.ReachabilitySensitive;
35 import dalvik.system.BlockGuard;
36 import dalvik.system.CloseGuard;
37 import dalvik.system.SocketTagger;
38 import sun.net.ConnectionResetException;
39 import sun.net.NetHooks;
40 import sun.net.ResourceManager;
41 
42 /**
43  * Default Socket Implementation. This implementation does
44  * not implement any security checks.
45  * Note this class should <b>NOT</b> be public.
46  *
47  * @author  Steven B. Byrne
48  */
49 abstract class AbstractPlainSocketImpl extends SocketImpl
50 {
51     /* instance variable for SO_TIMEOUT */
52     int timeout;   // timeout in millisec
53     // Android-removed: traffic class is set through socket
54     // private int trafficClass;
55 
56     private boolean shut_rd = false;
57     private boolean shut_wr = false;
58 
59     private SocketInputStream socketInputStream = null;
60     private SocketOutputStream socketOutputStream = null;
61 
62     /* number of threads using the FileDescriptor */
63     protected int fdUseCount = 0;
64 
65     /* lock when increment/decrementing fdUseCount */
66     // Android-added: @ReachabilitySensitive
67     // Marked mostly because it's used where fd is, and fd isn't declared here.
68     // This adds reachabilityFences where we would if fd were annotated.
69     @ReachabilitySensitive
70     protected final Object fdLock = new Object();
71 
72     /* indicates a close is pending on the file descriptor */
73     protected boolean closePending = false;
74 
75     /* indicates connection reset state */
76     private int CONNECTION_NOT_RESET = 0;
77     private int CONNECTION_RESET_PENDING = 1;
78     private int CONNECTION_RESET = 2;
79     private int resetState;
80     private final Object resetLock = new Object();
81 
82    /* whether this Socket is a stream (TCP) socket or not (UDP)
83     */
84     protected boolean stream;
85 
86     // BEGIN Android-removed: Android doesn't need to load native net library
87     /*
88     /**
89      * Load net library into runtime.
90      *
91     static {
92         java.security.AccessController.doPrivileged(
93             new java.security.PrivilegedAction<Void>() {
94                 public Void run() {
95                     System.loadLibrary("net");
96                     return null;
97                 }
98             });
99     }
100     */
101     // END Android-removed: Android doesn't need to load native net library
102 
103     // Android-added: logs a warning if socket is not closed
104     @ReachabilitySensitive
105     private final CloseGuard guard = CloseGuard.get();
106 
107     /**
108      * Creates a socket with a boolean that specifies whether this
109      * is a stream socket (true) or an unconnected UDP socket (false).
110      */
create(boolean stream)111     protected synchronized void create(boolean stream) throws IOException {
112         this.stream = stream;
113         if (!stream) {
114             ResourceManager.beforeUdpCreate();
115             // Android-removed: socketCreate should set fd if it succeeds
116             // fd = new FileDescriptor();
117             try {
118                 socketCreate(false);
119             } catch (IOException ioe) {
120                 ResourceManager.afterUdpClose();
121                 // Android-removed: b/26470377 Represent closed sockets with invalid fd, not null.
122                 // fd = null;
123                 throw ioe;
124             }
125         } else {
126             // Android-removed: socketCreate should set fd if it succeeds
127             // fd = new FileDescriptor();
128             socketCreate(true);
129         }
130         if (socket != null)
131             socket.setCreated();
132         if (serverSocket != null)
133             serverSocket.setCreated();
134 
135         // Android-added: CloseGuard
136         if (fd != null && fd.valid()) {
137             guard.open("close");
138         }
139     }
140 
141     /**
142      * Creates a socket and connects it to the specified port on
143      * the specified host.
144      * @param host the specified host
145      * @param port the specified port
146      */
connect(String host, int port)147     protected void connect(String host, int port)
148         throws UnknownHostException, IOException
149     {
150         boolean connected = false;
151         try {
152             InetAddress address = InetAddress.getByName(host);
153             this.port = port;
154             this.address = address;
155 
156             connectToAddress(address, port, timeout);
157             connected = true;
158         } finally {
159             if (!connected) {
160                 try {
161                     close();
162                 } catch (IOException ioe) {
163                     /* Do nothing. If connect threw an exception then
164                        it will be passed up the call stack */
165                 }
166             }
167         }
168     }
169 
170     /**
171      * Creates a socket and connects it to the specified address on
172      * the specified port.
173      * @param address the address
174      * @param port the specified port
175      */
connect(InetAddress address, int port)176     protected void connect(InetAddress address, int port) throws IOException {
177         this.port = port;
178         this.address = address;
179 
180         try {
181             connectToAddress(address, port, timeout);
182             return;
183         } catch (IOException e) {
184             // everything failed
185             close();
186             throw e;
187         }
188     }
189 
190     /**
191      * Creates a socket and connects it to the specified address on
192      * the specified port.
193      * @param address the address
194      * @param timeout the timeout value in milliseconds, or zero for no timeout.
195      * @throws IOException if connection fails
196      * @throws  IllegalArgumentException if address is null or is a
197      *          SocketAddress subclass not supported by this socket
198      * @since 1.4
199      */
connect(SocketAddress address, int timeout)200     protected void connect(SocketAddress address, int timeout)
201             throws IOException {
202         boolean connected = false;
203         try {
204             if (address == null || !(address instanceof InetSocketAddress))
205                 throw new IllegalArgumentException("unsupported address type");
206             InetSocketAddress addr = (InetSocketAddress) address;
207             if (addr.isUnresolved())
208                 throw new UnknownHostException(addr.getHostName());
209             this.port = addr.getPort();
210             this.address = addr.getAddress();
211 
212             connectToAddress(this.address, port, timeout);
213             connected = true;
214         } finally {
215             if (!connected) {
216                 try {
217                     close();
218                 } catch (IOException ioe) {
219                     /* Do nothing. If connect threw an exception then
220                        it will be passed up the call stack */
221                 }
222             }
223         }
224     }
225 
connectToAddress(InetAddress address, int port, int timeout)226     private void connectToAddress(InetAddress address, int port, int timeout) throws IOException {
227         if (address.isAnyLocalAddress()) {
228             doConnect(InetAddress.getLocalHost(), port, timeout);
229         } else {
230             doConnect(address, port, timeout);
231         }
232     }
233 
setOption(int opt, Object val)234     public void setOption(int opt, Object val) throws SocketException {
235         if (isClosedOrPending()) {
236             throw new SocketException("Socket Closed");
237         }
238         // BEGIN Android-removed: Logic dealing with value type moved to socketSetOption.
239         /*
240         boolean on = true;
241         switch (opt) {
242             /* check type safety b4 going native.  These should never
243              * fail, since only java.Socket* has access to
244              * PlainSocketImpl.setOption().
245              *
246         case SO_LINGER:
247             if (val == null || (!(val instanceof Integer) && !(val instanceof Boolean)))
248                 throw new SocketException("Bad parameter for option");
249             if (val instanceof Boolean) {
250                 /* true only if disabling - enabling should be Integer *
251                 on = false;
252             }
253             break;
254         case SO_TIMEOUT:
255             if (val == null || (!(val instanceof Integer)))
256                 throw new SocketException("Bad parameter for SO_TIMEOUT");
257             int tmp = ((Integer) val).intValue();
258             if (tmp < 0)
259                 throw new IllegalArgumentException("timeout < 0");
260             timeout = tmp;
261             break;
262         case IP_TOS:
263              if (val == null || !(val instanceof Integer)) {
264                  throw new SocketException("bad argument for IP_TOS");
265              }
266              trafficClass = ((Integer)val).intValue();
267              break;
268         case SO_BINDADDR:
269             throw new SocketException("Cannot re-bind socket");
270         case TCP_NODELAY:
271             if (val == null || !(val instanceof Boolean))
272                 throw new SocketException("bad parameter for TCP_NODELAY");
273             on = ((Boolean)val).booleanValue();
274             break;
275         case SO_SNDBUF:
276         case SO_RCVBUF:
277             if (val == null || !(val instanceof Integer) ||
278                 !(((Integer)val).intValue() > 0)) {
279                 throw new SocketException("bad parameter for SO_SNDBUF " +
280                                           "or SO_RCVBUF");
281             }
282             break;
283         case SO_KEEPALIVE:
284             if (val == null || !(val instanceof Boolean))
285                 throw new SocketException("bad parameter for SO_KEEPALIVE");
286             on = ((Boolean)val).booleanValue();
287             break;
288         case SO_OOBINLINE:
289             if (val == null || !(val instanceof Boolean))
290                 throw new SocketException("bad parameter for SO_OOBINLINE");
291             on = ((Boolean)val).booleanValue();
292             break;
293         case SO_REUSEADDR:
294             if (val == null || !(val instanceof Boolean))
295                 throw new SocketException("bad parameter for SO_REUSEADDR");
296             on = ((Boolean)val).booleanValue();
297             break;
298         default:
299             throw new SocketException("unrecognized TCP option: " + opt);
300         }
301         socketSetOption(opt, on, val);
302         */
303         // END Android-removed: Logic dealing with value type moved to socketSetOption.
304         // Android-added: Keep track of timeout value not handled by socketSetOption
305         if (opt == SO_TIMEOUT) {
306             timeout = (Integer) val;
307         }
308         socketSetOption(opt, val);
309     }
getOption(int opt)310     public Object getOption(int opt) throws SocketException {
311         if (isClosedOrPending()) {
312             throw new SocketException("Socket Closed");
313         }
314         if (opt == SO_TIMEOUT) {
315             return new Integer(timeout);
316         }
317         // BEGIN Android-changed: Logic dealing with value type moved to socketGetOption.
318         /*
319         int ret = 0;
320         /*
321          * The native socketGetOption() knows about 3 options.
322          * The 32 bit value it returns will be interpreted according
323          * to what we're asking.  A return of -1 means it understands
324          * the option but its turned off.  It will raise a SocketException
325          * if "opt" isn't one it understands.
326          *
327 
328         switch (opt) {
329         case TCP_NODELAY:
330             ret = socketGetOption(opt, null);
331             return Boolean.valueOf(ret != -1);
332         case SO_OOBINLINE:
333             ret = socketGetOption(opt, null);
334             return Boolean.valueOf(ret != -1);
335         case SO_LINGER:
336             ret = socketGetOption(opt, null);
337             return (ret == -1) ? Boolean.FALSE: (Object)(new Integer(ret));
338         case SO_REUSEADDR:
339             ret = socketGetOption(opt, null);
340             return Boolean.valueOf(ret != -1);
341         case SO_BINDADDR:
342             InetAddressContainer in = new InetAddressContainer();
343             ret = socketGetOption(opt, in);
344             return in.addr;
345         case SO_SNDBUF:
346         case SO_RCVBUF:
347             ret = socketGetOption(opt, null);
348             return new Integer(ret);
349         case IP_TOS:
350             try {
351                 ret = socketGetOption(opt, null);
352                 if (ret == -1) { // ipv6 tos
353                     return trafficClass;
354                 } else {
355                     return ret;
356                 }
357             } catch (SocketException se) {
358                 // TODO - should make better effort to read TOS or TCLASS
359                 return trafficClass; // ipv6 tos
360             }
361         case SO_KEEPALIVE:
362             ret = socketGetOption(opt, null);
363             return Boolean.valueOf(ret != -1);
364         // should never get here
365         default:
366             return null;
367         }
368         */
369         return socketGetOption(opt);
370         // END Android-changed: Logic dealing with value type moved to socketGetOption.
371     }
372 
373     /**
374      * The workhorse of the connection operation.  Tries several times to
375      * establish a connection to the given <host, port>.  If unsuccessful,
376      * throws an IOException indicating what went wrong.
377      */
378 
doConnect(InetAddress address, int port, int timeout)379     synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
380         synchronized (fdLock) {
381             if (!closePending && (socket == null || !socket.isBound())) {
382                 NetHooks.beforeTcpConnect(fd, address, port);
383             }
384         }
385         try {
386             acquireFD();
387             try {
388                 // Android-added: BlockGuard
389                 BlockGuard.getThreadPolicy().onNetwork();
390                 socketConnect(address, port, timeout);
391                 /* socket may have been closed during poll/select */
392                 synchronized (fdLock) {
393                     if (closePending) {
394                         throw new SocketException ("Socket closed");
395                     }
396                 }
397                 // If we have a ref. to the Socket, then sets the flags
398                 // created, bound & connected to true.
399                 // This is normally done in Socket.connect() but some
400                 // subclasses of Socket may call impl.connect() directly!
401                 if (socket != null) {
402                     socket.setBound();
403                     socket.setConnected();
404                 }
405             } finally {
406                 releaseFD();
407             }
408         } catch (IOException e) {
409             close();
410             throw e;
411         }
412     }
413 
414     /**
415      * Binds the socket to the specified address of the specified local port.
416      * @param address the address
417      * @param lport the port
418      */
bind(InetAddress address, int lport)419     protected synchronized void bind(InetAddress address, int lport)
420         throws IOException
421     {
422        synchronized (fdLock) {
423             if (!closePending && (socket == null || !socket.isBound())) {
424                 NetHooks.beforeTcpBind(fd, address, lport);
425             }
426         }
427         socketBind(address, lport);
428         if (socket != null)
429             socket.setBound();
430         if (serverSocket != null)
431             serverSocket.setBound();
432     }
433 
434     /**
435      * Listens, for a specified amount of time, for connections.
436      * @param count the amount of time to listen for connections
437      */
listen(int count)438     protected synchronized void listen(int count) throws IOException {
439         socketListen(count);
440     }
441 
442     /**
443      * Accepts connections.
444      * @param s the connection
445      */
accept(SocketImpl s)446     protected void accept(SocketImpl s) throws IOException {
447         acquireFD();
448         try {
449             // Android-added: BlockGuard
450             BlockGuard.getThreadPolicy().onNetwork();
451             socketAccept(s);
452         } finally {
453             releaseFD();
454         }
455     }
456 
457     /**
458      * Gets an InputStream for this socket.
459      */
getInputStream()460     protected synchronized InputStream getInputStream() throws IOException {
461         synchronized (fdLock) {
462             if (isClosedOrPending())
463                 throw new IOException("Socket Closed");
464             if (shut_rd)
465                 throw new IOException("Socket input is shutdown");
466             if (socketInputStream == null)
467                 socketInputStream = new SocketInputStream(this);
468         }
469         return socketInputStream;
470     }
471 
setInputStream(SocketInputStream in)472     void setInputStream(SocketInputStream in) {
473         socketInputStream = in;
474     }
475 
476     /**
477      * Gets an OutputStream for this socket.
478      */
getOutputStream()479     protected synchronized OutputStream getOutputStream() throws IOException {
480         synchronized (fdLock) {
481             if (isClosedOrPending())
482                 throw new IOException("Socket Closed");
483             if (shut_wr)
484                 throw new IOException("Socket output is shutdown");
485             if (socketOutputStream == null)
486                 socketOutputStream = new SocketOutputStream(this);
487         }
488         return socketOutputStream;
489     }
490 
491     // Android-removed: this.fd is maintained by the concrete implementation.
492     /*
493     void setFileDescriptor(FileDescriptor fd) {
494         this.fd = fd;
495     }
496     */
497 
setAddress(InetAddress address)498     void setAddress(InetAddress address) {
499         this.address = address;
500     }
501 
setPort(int port)502     void setPort(int port) {
503         this.port = port;
504     }
505 
setLocalPort(int localport)506     void setLocalPort(int localport) {
507         this.localport = localport;
508     }
509 
510     /**
511      * Returns the number of bytes that can be read without blocking.
512      */
available()513     protected synchronized int available() throws IOException {
514         if (isClosedOrPending()) {
515             throw new IOException("Stream closed.");
516         }
517 
518         /*
519          * If connection has been reset or shut down for input, then return 0
520          * to indicate there are no buffered bytes.
521          */
522         if (isConnectionReset() || shut_rd) {
523             return 0;
524         }
525 
526         /*
527          * If no bytes available and we were previously notified
528          * of a connection reset then we move to the reset state.
529          *
530          * If are notified of a connection reset then check
531          * again if there are bytes buffered on the socket.
532          */
533         int n = 0;
534         try {
535             n = socketAvailable();
536             if (n == 0 && isConnectionResetPending()) {
537                 setConnectionReset();
538             }
539         } catch (ConnectionResetException exc1) {
540             setConnectionResetPending();
541             try {
542                 n = socketAvailable();
543                 if (n == 0) {
544                     setConnectionReset();
545                 }
546             } catch (ConnectionResetException exc2) {
547             }
548         }
549         return n;
550     }
551 
552     /**
553      * Closes the socket.
554      */
close()555     protected void close() throws IOException {
556         synchronized(fdLock) {
557             if (fd != null && fd.valid()) {
558                 if (!stream) {
559                     ResourceManager.afterUdpClose();
560                 }
561                 // Android-changed:
562                 // Socket should be untagged before the preclose. After preclose,
563                 // socket will dup2-ed to marker_fd, therefore, it won't describe the same file.
564                 // If closingPending is true, then the socket has been preclosed.
565                 //
566                 // Also, close the CloseGuard when the #close is called.
567                 if (!closePending) {
568                     closePending = true;
569                     guard.close();
570 
571                     if (fdUseCount == 0) {
572                         /*
573                          * We close the FileDescriptor in two-steps - first the
574                          * "pre-close" which closes the socket but doesn't
575                          * release the underlying file descriptor. This operation
576                          * may be lengthy due to untransmitted data and a long
577                          * linger interval. Once the pre-close is done we do the
578                          * actual socket to release the fd.
579                          */
580                         try {
581                             socketPreClose();
582                         } finally {
583                             socketClose();
584                         }
585                         // Android-changed(http://b/26470377): Some Android code doesn't expect file
586                         // descriptor to be null. socketClose invalidates the fd by closing the fd.
587                         // fd = null;
588                         return;
589                     } else {
590                         /*
591                          * If a thread has acquired the fd and a close
592                          * isn't pending then use a deferred close.
593                          * Also decrement fdUseCount to signal the last
594                          * thread that releases the fd to close it.
595                          */
596                         fdUseCount--;
597                         socketPreClose();
598                     }
599                 }
600             }
601         }
602     }
603 
reset()604     void reset() throws IOException {
605         if (fd != null && fd.valid()) {
606             socketClose();
607             // Android-changed: Notified the CloseGuard object as the fd has been released.
608             guard.close();
609         }
610         // Android-removed: b/26470377 Represent closed sockets with invalid fd, not null.
611         // fd = null;
612         super.reset();
613     }
614 
615 
616     /**
617      * Shutdown read-half of the socket connection;
618      */
shutdownInput()619     protected void shutdownInput() throws IOException {
620       // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
621       if (fd != null && fd.valid()) {
622           socketShutdown(SHUT_RD);
623           if (socketInputStream != null) {
624               socketInputStream.setEOF(true);
625           }
626           shut_rd = true;
627       }
628     }
629 
630     /**
631      * Shutdown write-half of the socket connection;
632      */
shutdownOutput()633     protected void shutdownOutput() throws IOException {
634       // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
635       if (fd != null && fd.valid()) {
636           socketShutdown(SHUT_WR);
637           shut_wr = true;
638       }
639     }
640 
supportsUrgentData()641     protected boolean supportsUrgentData () {
642         return true;
643     }
644 
sendUrgentData(int data)645     protected void sendUrgentData (int data) throws IOException {
646         // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
647         if (fd == null || !fd.valid()) {
648             throw new IOException("Socket Closed");
649         }
650         socketSendUrgentData (data);
651     }
652 
653     /**
654      * Cleans up if the user forgets to close it.
655      */
finalize()656     protected void finalize() throws IOException {
657         // Android-added: CloseGuard
658         if (guard != null) {
659             guard.warnIfOpen();
660         }
661 
662         close();
663     }
664 
665     /*
666      * "Acquires" and returns the FileDescriptor for this impl
667      *
668      * A corresponding releaseFD is required to "release" the
669      * FileDescriptor.
670      */
acquireFD()671     FileDescriptor acquireFD() {
672         synchronized (fdLock) {
673             fdUseCount++;
674             return fd;
675         }
676     }
677 
678     /*
679      * "Release" the FileDescriptor for this impl.
680      *
681      * If the use count goes to -1 then the socket is closed.
682      */
releaseFD()683     void releaseFD() {
684         synchronized (fdLock) {
685             fdUseCount--;
686             if (fdUseCount == -1) {
687                 if (fd != null) {
688                     try {
689                         socketClose();
690                     } catch (IOException e) {
691                         // Android-removed: b/26470377 Some Android code doesn't expect file
692                         // descriptor to be null. socketClose invalidates the fd by closing the fd.
693                         // } finally {
694                         //     fd = null;
695                     }
696                 }
697             }
698         }
699     }
700 
isConnectionReset()701     public boolean isConnectionReset() {
702         synchronized (resetLock) {
703             return (resetState == CONNECTION_RESET);
704         }
705     }
706 
isConnectionResetPending()707     public boolean isConnectionResetPending() {
708         synchronized (resetLock) {
709             return (resetState == CONNECTION_RESET_PENDING);
710         }
711     }
712 
setConnectionReset()713     public void setConnectionReset() {
714         synchronized (resetLock) {
715             resetState = CONNECTION_RESET;
716         }
717     }
718 
setConnectionResetPending()719     public void setConnectionResetPending() {
720         synchronized (resetLock) {
721             if (resetState == CONNECTION_NOT_RESET) {
722                 resetState = CONNECTION_RESET_PENDING;
723             }
724         }
725 
726     }
727 
728     /*
729      * Return true if already closed or close is pending
730      */
isClosedOrPending()731     public boolean isClosedOrPending() {
732         /*
733          * Lock on fdLock to ensure that we wait if a
734          * close is in progress.
735          */
736         synchronized (fdLock) {
737             // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
738             if (closePending || (fd == null) || !fd.valid()) {
739                 return true;
740             } else {
741                 return false;
742             }
743         }
744     }
745 
746     /*
747      * Return the current value of SO_TIMEOUT
748      */
getTimeout()749     public int getTimeout() {
750         return timeout;
751     }
752 
753     /*
754      * "Pre-close" a socket by dup'ing the file descriptor - this enables
755      * the socket to be closed without releasing the file descriptor.
756      */
socketPreClose()757     private void socketPreClose() throws IOException {
758         socketClose0(true);
759     }
760 
761     /*
762      * Close the socket (and release the file descriptor).
763      */
socketClose()764     protected void socketClose() throws IOException {
765         socketClose0(false);
766     }
767 
socketCreate(boolean isServer)768     abstract void socketCreate(boolean isServer) throws IOException;
socketConnect(InetAddress address, int port, int timeout)769     abstract void socketConnect(InetAddress address, int port, int timeout)
770         throws IOException;
socketBind(InetAddress address, int port)771     abstract void socketBind(InetAddress address, int port)
772         throws IOException;
socketListen(int count)773     abstract void socketListen(int count)
774         throws IOException;
socketAccept(SocketImpl s)775     abstract void socketAccept(SocketImpl s)
776         throws IOException;
socketAvailable()777     abstract int socketAvailable()
778         throws IOException;
socketClose0(boolean useDeferredClose)779     abstract void socketClose0(boolean useDeferredClose)
780         throws IOException;
socketShutdown(int howto)781     abstract void socketShutdown(int howto)
782         throws IOException;
783 
784     // Android-changed: Method signature changed, socket{Get,Set}Option work directly with Object
785     // values.
socketSetOption(int cmd, Object value)786     abstract void socketSetOption(int cmd, Object value) throws SocketException;
socketGetOption(int opt)787     abstract Object socketGetOption(int opt) throws SocketException;
788 
socketSendUrgentData(int data)789     abstract void socketSendUrgentData(int data)
790         throws IOException;
791 
792     public final static int SHUT_RD = 0;
793     public final static int SHUT_WR = 1;
794 }
795