gcc/libjava/java/net/natInetAddress.cc
Warren Levy f2ed9e9656 [multiple changes]
1999-05-26  Bryce McKinlay <bryce@albatross.co.nz>
	* java/net/DatagramSocket.java (getSoTimeout): Verify class type.
	* java/net/DatagramSocketImpl.java (getOption): Made abstract.
	(setOption): Made abstract.
	* java/net/PlainDatagramSocketImpl.java: Mirror SocketOptions fields
	to avoid cpp conflicts in native code.
	* java/net/PlainSocketImpl.java: Mirror SocketOptions fields to avoid
	cpp conflicts in native code.
	* java/net/ServerSocket.java (toString): Prepended "ServerSocket".
	* java/net/Socket.java (getLocalAddress): Implemented.
	(setTcpNoDelay): Implemented.
	(getTcpNoDelay): Implemented.
	(setSoLinger): Implemented.
	(getSoLinger): Implemented.
	(getSoTimeout): Verify class type.
	(setSendBufferSize): Implemented.
	(getSendBufferSize): Implemented.
	(setReceiveBufferSize): Implemented.
	(getReceiveBufferSize): Implemented.
	(toString): Prepended "Socket".
	* java/net/SocketImpl.java (toString): Rewritten.
	(getOption): Made abstract.
	(setOption): Made abstract.
	* java/net/natPlainSocketImpl.cc (connect): Set localport properly.
	(setOption): Implemented.
	(getOption): Implemented.
1999-05-26  Warren Levy  <warrenl@cygnus.com>
	* java/net/DatagramSocket.java (DatagramSocket): Get local host
	address when null.  Set SO_REUSEADDR for multicasts.
	(getSoTimeout): Implemented.
	(setSoTimeout): Implemented.
	* java/net/DatagramSocketImpl.java: Implement SocketOptions interface.
	* java/net/MulticastSocket.java (getInterface): Implemented.
	(setInterface): Implemented.
	(setTimeToLive): Check for invalid ttl.
	(joinGroup): Verify multicast address and security.
	(leaveGroup): Verify multicast address and security.
	(send): Implemented.
	* java/net/PlainDatagramSocketImpl.java (timeout): Added.
	(iface): Added.
	(ttl): Added.
	(setOption): Added.
	(getOption): Added.
	(mcastGrp): Added.
	(getTTL): Implemented as non-native.
	(setTTL): ditto.
	(join): ditto.
	(leave): ditto.
	* java/net/ServerSocket.java (setSoTimeout): Implemented.
	(getSoTimeout): Implemented.
	(setSocketFactory): Made synchronized.
	* java/net/Socket.java (setSoTimeout): Implemented.
	(getSoTimeout): Implemented.
	(close): Made synchronized.
	(setSocketImplFactory): Made synchronized.
	* java/net/SocketImpl.java: Implement SocketOptions interface.
	* java/net/natInetAddress.cc: Corrected module name at top of file.
	* java/net/natPlainDatagramSocketImpl.cc (McastReq): Added union.
	(bind): Added FIXME.
	(peek): Implemented.
	(setTTL): Removed.
	(getTTL): Removed.
	(join): Removed.
	(leave): Removed.
	(mcastGrp): Added.
	(setOption): Implemented for SO_REUSEADDR.
	(getOption): Implemented for SO_REUSEADDR.

From-SVN: r27184
1999-05-26 17:00:06 +00:00

278 lines
6.6 KiB
C++

// natInetAddress.cc
/* Copyright (C) 1998, 1999 Cygnus Solutions
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
#include <config.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include <cni.h>
#include <jvm.h>
#include <java/net/InetAddress.h>
#include <java/net/UnknownHostException.h>
#include <java/lang/SecurityException.h>
#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
#include <sys/utsname.h>
#endif
#ifndef HAVE_GETHOSTNAME_DECL
extern "C" int gethostname (char *name, int namelen);
#endif
jbyteArray
java::net::InetAddress::aton (jstring host)
{
char *hostname;
char buf[100];
int len = JvGetStringUTFLength(host);
if (len < 100)
hostname = buf;
else
hostname = (char*) _Jv_AllocBytesChecked (len+1);
JvGetStringUTFRegion (host, 0, host->length(), hostname);
buf[len] = '\0';
char* bytes = NULL;
int blen = 0;
#ifdef HAVE_INET_ATON
struct in_addr laddr;
if (inet_aton (hostname, &laddr))
{
bytes = (char*) &laddr;
len = 4;
}
#elif defined(HAVE_INET_ADDR)
in_addr_t laddr = inet_addr (hostname);
if (laddr != (in_addr_t)(-1))
{
bytes = (char*) &laddr;
len = 4;
}
#endif
#ifdef HAVE_INET_PTON
char inet6_addr[16];
if (len == 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
{
bytes = inet6_addr;
len = 16;
}
#endif
if (blen == 0)
return NULL;
jbyteArray result = JvNewByteArray (len);
memcpy (elements (result), bytes, blen);
return result;
}
JArray<java::net::InetAddress*> *
java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
jboolean all)
{
struct hostent *hptr = NULL;
#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
struct hostent hent_r;
#if defined (__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0
// glibc 2.0.7 has a bug where gethostbyname_r won't return an error
// if the buffer is too small. So in this case we size the buffer
// the same way that glibc does. This is fixed in glibc 2.1.
char fixed_buffer[1024];
#else
char fixed_buffer[200];
#endif
char *buffer_r = fixed_buffer;
int size_r = sizeof (fixed_buffer);
#endif
if (host != NULL)
{
char *hostname;
char buf[100];
int len = JvGetStringUTFLength(host);
if (len < 100)
hostname = buf;
else
hostname = (char*) _Jv_AllocBytesChecked (len+1);
JvGetStringUTFRegion (host, 0, host->length(), hostname);
buf[len] = '\0';
#ifdef HAVE_GETHOSTBYNAME_R
int herr = ERANGE;
while (hptr == NULL && herr == ERANGE)
{
int ok;
#ifdef GETHOSTBYNAME_R_RETURNS_INT
ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
&hptr, &herr);
#else
hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
ok = hptr != NULL;
#endif /* GETHOSTNAME_R_RETURNS_INT */
if (! ok && herr == ERANGE)
{
size_r *= 2;
buffer_r = (char *) _Jv_AllocBytesChecked (size_r);
}
}
#else
// FIXME: this is insufficient if some other piece of code calls
// this gethostbyname.
JvSynchronize sync (java::net::InetAddress::localhostAddress);
hptr = gethostbyname (hostname);
#endif /* HAVE_GETHOSTBYNAME_R */
}
else
{
jbyteArray bytes = iaddr->address;
char *chars = (char*) elements (bytes);
int len = bytes->length;
int type;
char *val;
if (len == 4)
{
val = chars;
type = AF_INET;
}
#ifdef HAVE_INET6
else if (len == 16)
{
val = (char *) &chars;
type = AF_INET6;
}
#endif /* HAVE_INET6 */
else
JvFail ("unrecognized size");
#ifdef HAVE_GETHOSTBYADDR_R
int herr = ERANGE;
while (hptr == NULL && herr == ERANGE)
{
int ok;
#ifdef GETHOSTBYADDR_R_RETURNS_INT
ok = ! gethostbyaddr_r (val, len, type, &hent_r,
buffer_r, size_r, &hptr, &herr);
#else
hptr = gethostbyaddr_r (val, len, type, &hent_r,
buffer_r, size_r, &herr);
ok = hptr != NULL;
#endif /* GETHOSTBYADDR_R_RETURNS_INT */
if (! ok && herr == ERANGE)
{
size_r *= 2;
buffer_r = (char *) _Jv_AllocBytesChecked (size_r);
}
}
#else /* HAVE_GETHOSTBYADDR_R */
// FIXME: this is insufficient if some other piece of code calls
// this gethostbyaddr.
JvSynchronize sync (java::net::InetAddress::localhostAddress);
hptr = gethostbyaddr (val, len, type);
#endif /* HAVE_GETHOSTBYADDR_R */
}
if (hptr != NULL)
{
host = JvNewStringUTF (hptr->h_name);
java::lang::SecurityException *ex = checkConnect (host);
if (ex != NULL)
{
if (iaddr == NULL || iaddr->address == NULL)
JvThrow (ex);
hptr = NULL;
}
}
if (hptr == NULL)
{
if (iaddr != NULL && iaddr->address != NULL)
{
iaddr->hostname = iaddr->getHostAddress();
return NULL;
}
else
JvThrow (new java::net::UnknownHostException(host));
}
int count;
if (all)
{
char** ptr = hptr->h_addr_list;
count = 0;
while (*ptr++) count++;
}
else
count = 1;
JArray<java::net::InetAddress*> *result;
java::net::InetAddress** iaddrs;
if (all)
{
result = java::net::InetAddress::allocArray (count);
iaddrs = elements (result);
}
else
{
result = NULL;
iaddrs = &iaddr;
}
for (int i = 0; i < count; i++)
{
if (iaddrs[i] == NULL)
iaddrs[i] = new java::net::InetAddress (NULL, NULL);
if (i == 0)
iaddrs[0]->hostname = host;
if (iaddrs[i]->address == NULL)
{
char *bytes = hptr->h_addr_list[i];
iaddr->address = JvNewByteArray (hptr->h_length);
memcpy (elements (iaddr->address), bytes, hptr->h_length);
}
}
return result;
}
jstring
java::net::InetAddress::getLocalHostname ()
{
char *chars;
#ifdef HAVE_GETHOSTNAME
char buffer[MAXHOSTNAMELEN];
if (gethostname (buffer, MAXHOSTNAMELEN))
return NULL;
chars = buffer;
#elif HAVE_UNAME
struct utsname stuff;
if (uname (&stuff) != 0)
return NULL:
chars = stuff.nodename;
#else
return NULL;
#endif
// It is admittedly non-optimal to convert the hostname to Unicode
// only to convert it back in getByName, but simplicity wins. Note
// that unless there is a SecurityManager, we only get called once
// anyway, thanks to the InetAddress.localhost cache.
return JvNewStringUTF (chars);
}