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