1 /* PlainDatagramSocketImpl.java -- Default DatagramSocket implementation 2 Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package gnu.java.net; 40 41 import gnu.classpath.Configuration; 42 43 import java.io.IOException; 44 import java.net.DatagramPacket; 45 import java.net.DatagramSocketImpl; 46 import java.net.InetAddress; 47 import java.net.InetSocketAddress; 48 import java.net.NetworkInterface; 49 import java.net.SocketAddress; 50 import java.net.SocketException; 51 import java.net.SocketOptions; 52 53 /** 54 * Written using on-line Java Platform 1.2 API Specification, as well 55 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). 56 * Status: Believed complete and correct. 57 */ 58 59 /** 60 * This is the default socket implementation for datagram sockets. 61 * It makes native calls to C routines that implement BSD style 62 * SOCK_DGRAM sockets in the AF_INET family. 63 * 64 * @author Aaron M. Renn (arenn@urbanophile.com) 65 * @author Warren Levy (warrenl@cygnus.com) 66 */ 67 public final class PlainDatagramSocketImpl extends DatagramSocketImpl 68 { 69 // Static initializer to load native library 70 static 71 { 72 if (Configuration.INIT_LOAD_LIBRARY) 73 { 74 System.loadLibrary("javanet"); 75 } 76 } 77 78 // These fields are mirrored for use in native code to avoid cpp conflicts 79 // when the #defines in system header files are the same as the public fields. 80 static final int _Jv_TCP_NODELAY_ = SocketOptions.TCP_NODELAY, 81 _Jv_SO_BINDADDR_ = SocketOptions.SO_BINDADDR, 82 _Jv_SO_REUSEADDR_ = SocketOptions.SO_REUSEADDR, 83 _Jv_SO_BROADCAST_ = SocketOptions.SO_BROADCAST, 84 _Jv_SO_OOBINLINE_ = SocketOptions.SO_OOBINLINE, 85 _Jv_IP_MULTICAST_IF_ = SocketOptions.IP_MULTICAST_IF, 86 _Jv_IP_MULTICAST_IF2_ = SocketOptions.IP_MULTICAST_IF2, 87 _Jv_IP_MULTICAST_LOOP_ = SocketOptions.IP_MULTICAST_LOOP, 88 _Jv_IP_TOS_ = SocketOptions.IP_TOS, 89 _Jv_SO_LINGER_ = SocketOptions.SO_LINGER, 90 _Jv_SO_TIMEOUT_ = SocketOptions.SO_TIMEOUT, 91 _Jv_SO_SNDBUF_ = SocketOptions.SO_SNDBUF, 92 _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF, 93 _Jv_SO_KEEPALIVE_ = SocketOptions.SO_KEEPALIVE; 94 95 /** 96 * This is the actual underlying file descriptor 97 */ 98 int native_fd = -1; 99 100 /** 101 * Lock object to serialize threads wanting to receive 102 */ 103 private final Object RECEIVE_LOCK = new Object(); 104 105 /** 106 * Lock object to serialize threads wanting to send 107 */ 108 private final Object SEND_LOCK = new Object(); 109 110 // FIXME: Is this necessary? Could it help w/ DatagramSocket.getLocalAddress? 111 // InetAddress address; 112 113 // localAddress cache 114 InetAddress localAddress; 115 116 // 'timeout' is set/read by setOption/getOption. 117 int timeout = 0; 118 119 /** 120 * Default do nothing constructor 121 */ PlainDatagramSocketImpl()122 public PlainDatagramSocketImpl() throws IOException 123 { 124 } 125 finalize()126 protected void finalize() throws Throwable 127 { 128 synchronized (this) 129 { 130 if (native_fd != -1) 131 close(); 132 } 133 super.finalize(); 134 } 135 getNativeFD()136 public int getNativeFD() 137 { 138 return native_fd; 139 } 140 141 /** 142 * Binds this socket to a particular port and interface 143 * 144 * @param port The port to bind to 145 * @param addr The address to bind to 146 * 147 * @exception SocketException If an error occurs 148 */ bind(int port, InetAddress addr)149 protected native void bind(int port, InetAddress addr) 150 throws SocketException; 151 connect(InetAddress addr, int port)152 protected native void connect(InetAddress addr, int port) 153 throws SocketException; 154 disconnect()155 protected native void disconnect(); 156 157 /** 158 * Creates a new datagram socket 159 * 160 * @exception SocketException If an error occurs 161 */ create()162 protected native void create() throws SocketException; 163 peek(InetAddress addr)164 protected native int peek(InetAddress addr) throws IOException; 165 peekData(DatagramPacket packet)166 protected native int peekData(DatagramPacket packet) throws IOException; 167 168 /** 169 * Sets the Time to Live value for the socket 170 * 171 * @param ttl The new TTL value 172 * 173 * @exception IOException If an error occurs 174 */ setTimeToLive(int ttl)175 protected native void setTimeToLive(int ttl) throws IOException; 176 177 /** 178 * Gets the Time to Live value for the socket 179 * 180 * @return The TTL value 181 * 182 * @exception IOException If an error occurs 183 */ getTimeToLive()184 protected native int getTimeToLive() throws IOException; 185 186 /** 187 * Sends a packet of data to a remote host 188 * 189 * @param packet The packet to send 190 * 191 * @exception IOException If an error occurs 192 */ send(DatagramPacket packet)193 protected native void send(DatagramPacket packet) throws IOException; 194 195 /** 196 * Receives a UDP packet from the network 197 * 198 * @param packet The packet to fill in with the data received 199 * 200 * @exception IOException IOException If an error occurs 201 */ receive(DatagramPacket packet)202 protected native void receive(DatagramPacket packet) throws IOException; 203 204 /** 205 * Sets the value of an option on the socket 206 * 207 * @param option_id The identifier of the option to set 208 * @param val The value of the option to set 209 * 210 * @exception SocketException If an error occurs 211 */ setOption(int option_id, Object val)212 public native void setOption(int option_id, Object val) 213 throws SocketException; 214 215 /** 216 * Retrieves the value of an option on the socket 217 * 218 * @param option_id The identifier of the option to retrieve 219 * 220 * @return The value of the option 221 * 222 * @exception SocketException If an error occurs 223 */ getOption(int option_id)224 public native Object getOption(int option_id) 225 throws SocketException; 226 227 /** 228 * Joins or leaves a broadcasting group on a given network interface. 229 * If the network interface is <code>null</code> the group is join/left on 230 * all locale network interfaces. 231 * 232 * @param inetAddr The broadcast address. 233 * @param netIf The network interface to join the group on. 234 * @param join True to join a broadcasting group, fals to leave it. 235 * 236 * @exception IOException If an error occurs. 237 */ mcastGrp(InetAddress inetAddr, NetworkInterface netIf, boolean join)238 private native void mcastGrp(InetAddress inetAddr, NetworkInterface netIf, 239 boolean join) 240 throws IOException; 241 242 /** 243 * Closes the socket 244 */ close()245 protected native void close(); 246 247 /** 248 * Gets the Time to Live value for the socket 249 * 250 * @return The TTL value 251 * 252 * @exception IOException If an error occurs 253 * 254 * @deprecated 1.2 255 */ getTTL()256 protected byte getTTL() throws IOException 257 { 258 return (byte) getTimeToLive(); 259 } 260 261 /** 262 * Sets the Time to Live value for the socket 263 * 264 * @param ttl The new TTL value 265 * 266 * @exception IOException If an error occurs 267 * 268 * @deprecated 1.2 269 */ setTTL(byte ttl)270 protected void setTTL(byte ttl) throws IOException 271 { 272 setTimeToLive(((int) ttl) & 0xFF); 273 } 274 275 /** 276 * Joins a multicast group 277 * 278 * @param addr The group to join 279 * 280 * @exception IOException If an error occurs 281 */ join(InetAddress addr)282 protected void join(InetAddress addr) throws IOException 283 { 284 mcastGrp(addr, null, true); 285 } 286 287 /** 288 * Leaves a multicast group 289 * 290 * @param addr The group to leave 291 * 292 * @exception IOException If an error occurs 293 */ leave(InetAddress addr)294 protected void leave(InetAddress addr) throws IOException 295 { 296 mcastGrp(addr, null, false); 297 } 298 joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)299 protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) 300 throws IOException 301 { 302 mcastGrp(((InetSocketAddress) mcastaddr).getAddress(), netIf, true); 303 } 304 leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)305 protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) 306 throws IOException 307 { 308 mcastGrp(((InetSocketAddress) mcastaddr).getAddress(), netIf, false); 309 } 310 } 311