1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
188de7cf6bff36093dda9e25a1ab3718720cb54906Elliott Hughespackage java.net;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
205d930cadc8f62aee5f18e7921296fe66a54f18abElliott Hughesimport android.system.ErrnoException;
215d930cadc8f62aee5f18e7921296fe66a54f18abElliott Hughesimport android.system.StructGroupReq;
22f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstromimport dalvik.system.CloseGuard;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileDescriptor;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
250b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughesimport libcore.io.IoBridge;
2632b0fa4d1a31ef07bc4297c615f0fe50e9aa7c21Elliott Hughesimport libcore.io.Libcore;
276186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonimport libcore.util.EmptyArray;
285d930cadc8f62aee5f18e7921296fe66a54f18abElliott Hughesimport static android.system.OsConstants.*;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
318de7cf6bff36093dda9e25a1ab3718720cb54906Elliott Hughes * @hide used in java.nio.
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
33f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonpublic class PlainDatagramSocketImpl extends DatagramSocketImpl {
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private volatile boolean isNativeConnected;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3712f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom    private final CloseGuard guard = CloseGuard.get();
38f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * used to keep address to which the socket was connected to at the native
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * level
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private InetAddress connectedAddress;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int connectedPort = -1;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public PlainDatagramSocketImpl(FileDescriptor fd, int localPort) {
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.fd = fd;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.localPort = localPort;
50f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        if (fd.valid()) {
51f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom            guard.open("close");
52f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        }
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public PlainDatagramSocketImpl() {
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fd = new FileDescriptor();
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
590b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes    @Override public void bind(int port, InetAddress address) throws SocketException {
600b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        IoBridge.bind(fd, address, port);
613db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes        if (port != 0) {
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            localPort = port;
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
640b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes            localPort = IoBridge.getSocketLocalPort(fd);
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
670a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes            setOption(SocketOptions.SO_BROADCAST, Boolean.TRUE);
6858e5a8e6eeaf94d78522e0e9994c4565a3b33fdbJesse Wilson        } catch (IOException ignored) {
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
73933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    protected void onBind(InetAddress localAddress, int localPort) {
74933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        this.localPort = localPort;
75933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    }
76933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
77933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    @Override
78c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson    public synchronized void close() {
79f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        guard.close();
80c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson        try {
81f0d40d662d9dfdb04215c718961765837d2cf00cNeil Fuller            IoBridge.closeAndSignalBlockedThreads(fd);
82c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson        } catch (IOException ignored) {
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
87933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    protected void onClose() {
88933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        guard.close();
89933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    }
90933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
91933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    @Override
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void create() throws SocketException {
930b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        this.fd = IoBridge.socket(false);
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
96e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom    @Override protected void finalize() throws Throwable {
97e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom        try {
9812f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom            if (guard != null) {
9912f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom                guard.warnIfOpen();
10012f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom            }
10112f2d8e2760b78c673b7a187b9062b3938a03147Brian Carlstrom            close();
102e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom        } finally {
103e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom            super.finalize();
104e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom        }
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1070a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes    @Override public Object getOption(int option) throws SocketException {
1080b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        return IoBridge.getSocketOption(fd, option);
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getTimeToLive() throws IOException {
1130b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        return (Integer) getOption(IoBridge.JAVA_IP_MULTICAST_TTL);
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte getTTL() throws IOException {
1184401c75ac7d85da33472d0398d8166df6ce4beb5Elliott Hughes        return (byte) getTimeToLive();
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121438cb9e440d250c8aa5daf4fae0c400dce8b1499Elliott Hughes    private static StructGroupReq makeGroupReq(InetAddress gr_group, NetworkInterface networkInterface) {
122438cb9e440d250c8aa5daf4fae0c400dce8b1499Elliott Hughes        int gr_interface = (networkInterface != null) ? networkInterface.getIndex() : 0;
123438cb9e440d250c8aa5daf4fae0c400dce8b1499Elliott Hughes        return new StructGroupReq(gr_interface, gr_group);
124438cb9e440d250c8aa5daf4fae0c400dce8b1499Elliott Hughes    }
125438cb9e440d250c8aa5daf4fae0c400dce8b1499Elliott Hughes
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void join(InetAddress addr) throws IOException {
1280b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        setOption(IoBridge.JAVA_MCAST_JOIN_GROUP, makeGroupReq(addr, null));
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void joinGroup(SocketAddress addr, NetworkInterface netInterface) throws IOException {
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (addr instanceof InetSocketAddress) {
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress groupAddr = ((InetSocketAddress) addr).getAddress();
1350b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes            setOption(IoBridge.JAVA_MCAST_JOIN_GROUP, makeGroupReq(groupAddr, netInterface));
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void leave(InetAddress addr) throws IOException {
1410b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        setOption(IoBridge.JAVA_MCAST_LEAVE_GROUP, makeGroupReq(addr, null));
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
1450b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes    public void leaveGroup(SocketAddress addr, NetworkInterface netInterface) throws IOException {
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (addr instanceof InetSocketAddress) {
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress groupAddr = ((InetSocketAddress) addr).getAddress();
1480b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes            setOption(IoBridge.JAVA_MCAST_LEAVE_GROUP, makeGroupReq(groupAddr, netInterface));
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected int peek(InetAddress sender) throws IOException {
154753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes        // We don't actually want the data: we just want the DatagramPacket's filled-in address.
155693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes        DatagramPacket packet = new DatagramPacket(EmptyArray.BYTE, 0);
156753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes        int result = peekData(packet);
15723ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes        // Note: evil side-effect on InetAddress! This method should have returned InetSocketAddress!
1582f03ccad590827233fcba84a8b6eafcd414e5fe7Elliott Hughes        sender.ipaddress = packet.getAddress().getAddress();
159753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes        return result;
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
16223ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes    private void doRecv(DatagramPacket pack, int flags) throws IOException {
1630b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        IoBridge.recvfrom(false, fd, pack.getData(), pack.getOffset(), pack.getLength(), flags, pack, isNativeConnected);
1649f2b1b1c3bf9de560f29f257c855c7c85b405c0fElliott Hughes        if (isNativeConnected) {
1659f2b1b1c3bf9de560f29f257c855c7c85b405c0fElliott Hughes            updatePacketRecvAddress(pack);
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
17079ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes    public void receive(DatagramPacket pack) throws IOException {
17123ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes        doRecv(pack, 0);
17279ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes    }
17379ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes
17479ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes    @Override
17579ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes    public int peekData(DatagramPacket pack) throws IOException {
17623ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes        doRecv(pack, MSG_PEEK);
17779ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes        return pack.getPort();
17879ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes    }
17979ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes
18079ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes    @Override
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void send(DatagramPacket packet) throws IOException {
182221d0ccb4cc23ee0bf0646e9abe471fb48b3a1a8Elliott Hughes        int port = isNativeConnected ? 0 : packet.getPort();
183221d0ccb4cc23ee0bf0646e9abe471fb48b3a1a8Elliott Hughes        InetAddress address = isNativeConnected ? null : packet.getAddress();
184933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        IoBridge.sendto(fd, packet.getData(), packet.getOffset(), packet.getLength(), 0, address,
185933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller            port);
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
188c63f0d4e80a9fd3bdf99cd438d108b750226736aElliott Hughes    public void setOption(int option, Object value) throws SocketException {
1890b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        IoBridge.setSocketOption(fd, option, value);
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
193fdd13e86ec613e46b68376f90d2c89c2ac33b4b5Elliott Hughes    public void setTimeToLive(int ttl) throws IOException {
1940b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        setOption(IoBridge.JAVA_IP_MULTICAST_TTL, Integer.valueOf(ttl));
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
198fdd13e86ec613e46b68376f90d2c89c2ac33b4b5Elliott Hughes    public void setTTL(byte ttl) throws IOException {
1994d8e9333e494ceedff074def3b6e44f523f3830eElliott Hughes        setTimeToLive((int) ttl & 0xff); // Avoid sign extension.
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void connect(InetAddress inetAddr, int port) throws SocketException {
2040b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes        IoBridge.connect(fd, inetAddr, port); // Throws on failure.
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            connectedAddress = InetAddress.getByAddress(inetAddr.getAddress());
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (UnknownHostException e) {
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // this is never expected to happen as we should not have gotten
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // here if the address is not resolvable
210b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Host is unresolved: " + inetAddr.getHostName());
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        connectedPort = port;
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isNativeConnected = true;
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
217933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    protected void onConnect(InetAddress remoteAddress, int remotePort) {
218933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        isNativeConnected = true;
219933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        connectedAddress = remoteAddress;
220933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        connectedPort = remotePort;
221933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    }
222933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
223933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    @Override
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void disconnect() {
2259b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes        try {
2269b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes            Libcore.os.connect(fd, InetAddress.UNSPECIFIED, 0);
2279b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes        } catch (ErrnoException errnoException) {
2289b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes            throw new AssertionError(errnoException);
22926010ab930a2cee3bf10b9612cf070183c21228bElliott Hughes        } catch (SocketException ignored) {
23026010ab930a2cee3bf10b9612cf070183c21228bElliott Hughes            // Thrown if the socket has already been closed, but this method can't throw anything.
2319b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes        }
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        connectedPort = -1;
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        connectedAddress = null;
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isNativeConnected = false;
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
237933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    @Override
238933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    protected void onDisconnect() {
239933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        connectedPort = -1;
240933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        connectedAddress = null;
241933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        isNativeConnected = false;
242933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    }
243933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Set the received address and port in the packet. We do this when the
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Datagram socket is connected at the native level and the
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * recvConnnectedDatagramImpl does not update the packet with address from
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * which the packet was received
249f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param packet
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the packet to be updated
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void updatePacketRecvAddress(DatagramPacket packet) {
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        packet.setAddress(connectedAddress);
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        packet.setPort(connectedPort);
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
258