Skip to content

Commit

Permalink
Enhance socket connection with configurable timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
mz1999 authored and dmatej committed Feb 4, 2025
1 parent f3300cf commit 40da3f9
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 32 deletions.
14 changes: 12 additions & 2 deletions orbmain/src/main/java/com/sun/corba/ee/impl/misc/ORBUtility.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.sun.corba.ee.impl.misc;

import java.net.Socket;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.Policy;
Expand Down Expand Up @@ -72,24 +73,33 @@
import com.sun.corba.ee.impl.ior.iiop.JavaSerializationComponent;
import com.sun.corba.ee.impl.javax.rmi.CORBA.Util;

import static com.sun.corba.ee.spi.misc.ORBConstants.TRANSPORT_TCP_CONNECT_MAX_TIME_TO_WAIT;

/**
* Handy class full of static functions that don't belong in util.Utility for pure ORB reasons.
*/
public final class ORBUtility {

public static SocketChannel openSocketChannel(SocketAddress sa) throws IOException {
return openSocketChannel(sa, TRANSPORT_TCP_CONNECT_MAX_TIME_TO_WAIT);
}

/** Utility method for working around leak in SocketChannel.open( SocketAddress )
* method.
* @param sa address to connect to
* @param timeout – the timeout value to be used in milliseconds.
* @return The opened channel
* @throws java.io.IOException If an I/O error occurs
* @see SocketChannel#connect(java.net.SocketAddress)
*/
public static SocketChannel openSocketChannel( SocketAddress sa )
public static SocketChannel openSocketChannel(SocketAddress sa, int timeout)
throws IOException {

SocketChannel sc = SocketChannel.open() ;

try {
sc.connect( sa ) ;
Socket socket = sc.socket();
socket.connect(sa, timeout);
return sc ;
} catch (RuntimeException | IOException exc ) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,13 @@ private ConnectionImpl(ORB orb,
this.contactInfo = contactInfo;

try {
TcpTimeouts tcpConnectTimeouts = orb.getORBData().getTransportTcpConnectTimeouts();
defineSocket(useSelectThreadToWait,
orb.getORBData().getSocketFactory().createSocket(socketType, new InetSocketAddress(hostname, port)));
orb.getORBData().getSocketFactory().createSocket(
orb.getORBData().connectionSocketType(),
new InetSocketAddress(hostname, port),
tcpConnectTimeouts.get_max_time_to_wait())
);
} catch (Throwable t) {
throw wrapper.connectFailure(t, socketType, hostname,
Integer.toString(port));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
public class DefaultSocketFactoryImpl
implements ORBSocketFactory
{
private ORB orb;
protected ORB orb;

public void setORB(ORB orb)
{
Expand All @@ -62,27 +62,6 @@ public ServerSocket createServerSocket(String type,
return serverSocket;
}

public Socket createSocket(String type,
InetSocketAddress inetSocketAddress)
throws IOException
{
SocketChannel socketChannel = null;
Socket socket = null;

if (orb.getORBData().connectionSocketType().equals(ORBConstants.SOCKETCHANNEL)) {
socketChannel = ORBUtility.openSocketChannel(inetSocketAddress);
socket = socketChannel.socket();
} else {
socket = new Socket(inetSocketAddress.getHostName(),
inetSocketAddress.getPort());
}

// Disable Nagle's algorithm (i.e., always send immediately).
socket.setTcpNoDelay(true);

return socket;
}

public void setAcceptedSocketOptions(Acceptor acceptor,
ServerSocket serverSocket,
Socket socket)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@
import java.net.Socket;
import java.net.SocketException;
import java.net.ServerSocket;
import java.nio.channels.SocketChannel;

import com.sun.corba.ee.impl.misc.ORBUtility;
import com.sun.corba.ee.spi.misc.ORBConstants;
import com.sun.corba.ee.spi.orb.ORB;

import static com.sun.corba.ee.spi.misc.ORBConstants.TRANSPORT_TCP_CONNECT_MAX_TIME_TO_WAIT;

/**
* @author Harold Carr
*/
Expand All @@ -38,9 +43,31 @@ public ServerSocket createServerSocket(String type,
InetSocketAddress inetSocketAddress)
throws IOException;

public Socket createSocket(String type,
InetSocketAddress inetSocketAddress)
throws IOException;
public default Socket createSocket(String type,
InetSocketAddress inetSocketAddress) throws IOException {
return createSocket(type, inetSocketAddress, TRANSPORT_TCP_CONNECT_MAX_TIME_TO_WAIT);
}

public default Socket createSocket(String type,
InetSocketAddress inetSocketAddress,
int timeout)
throws IOException {
SocketChannel socketChannel = null;
Socket socket = null;

if (type.equals(ORBConstants.SOCKETCHANNEL)) {
socketChannel = ORBUtility.openSocketChannel(inetSocketAddress, timeout);
socket = socketChannel.socket();
} else {
socket = new Socket();
socket.connect(inetSocketAddress, timeout);
}

// Disable Nagle's algorithm (i.e., always send immediately).
socket.setTcpNoDelay(true);

return socket;
}

public void setAcceptedSocketOptions(Acceptor acceptor,
ServerSocket serverSocket,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.sun.corba.ee.impl.transport;

import com.sun.corba.ee.spi.misc.ORBConstants;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.UUID;

import static org.junit.Assert.*;

public class DefaultSocketFactoryImplTest {
private static final String TEST_TYPE = ORBConstants.SOCKETCHANNEL;
private static final int TEST_TIMEOUT = 1000;

@Test
public void testCreateSocketWithSocketChannelType() throws IOException {
DefaultSocketFactoryImpl sf = new DefaultSocketFactoryImpl();
String testMessage = UUID.randomUUID().toString();
try (ServerSocket serverSocket = createServerSocket(testMessage)) {
final InetSocketAddress address = new InetSocketAddress("localhost", serverSocket.getLocalPort());
Socket socket = sf.createSocket(TEST_TYPE, address, TEST_TIMEOUT);
assertNotNull(socket);
assertTrue(socket.getTcpNoDelay());
validateSocket(socket, testMessage);
}
}

@Test
public void testCreateSocketWithOtherType() throws IOException {
DefaultSocketFactoryImpl sf = new DefaultSocketFactoryImpl();
String testMessage = UUID.randomUUID().toString();
try (ServerSocket serverSocket = createServerSocket(testMessage)) {
final InetSocketAddress address = new InetSocketAddress("localhost", serverSocket.getLocalPort());
Socket socket = sf.createSocket("otherType", address, TEST_TIMEOUT);
assertNotNull(socket);
assertTrue(socket.getTcpNoDelay());
validateSocket(socket, testMessage);
}
}

@Test(expected = SocketTimeoutException.class)
public void testCreateSocketWithTimeoutSocketChannelType() throws IOException {
DefaultSocketFactoryImpl sf = new DefaultSocketFactoryImpl();
InetSocketAddress unreachableAddress = new InetSocketAddress("10.0.0.0", 8080);
sf.createSocket(TEST_TYPE, unreachableAddress, TEST_TIMEOUT);
}

@Test(expected = SocketTimeoutException.class)
public void testCreateSocketWithTimeoutOtherType() throws IOException {
DefaultSocketFactoryImpl sf = new DefaultSocketFactoryImpl();
InetSocketAddress unreachableAddress = new InetSocketAddress("10.0.0.0", 8080);
sf.createSocket("otherType", unreachableAddress, TEST_TIMEOUT);
}

private ServerSocket createServerSocket(String message) throws IOException {
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(null);

new Thread(() -> {
try {
Socket clientSocket = serverSocket.accept();
OutputStream out = clientSocket.getOutputStream();
out.write(message.getBytes());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}).start();

return serverSocket;
}

private void validateSocket(Socket socket, String expectedMessage) throws IOException {
InputStream in = socket.getInputStream();
byte[] buffer = new byte[expectedMessage.length()];
int read = in.read(buffer);
assertEquals(expectedMessage, new String(buffer, 0, read));
}
}
11 changes: 7 additions & 4 deletions test/src/share/classes/corba/nortel/NortelSocketFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package corba.nortel ;

import com.sun.corba.ee.impl.transport.DefaultSocketFactoryImpl;
import com.sun.corba.ee.spi.transport.TcpTimeouts;

import java.io.IOException;

Expand Down Expand Up @@ -62,13 +63,15 @@ public Socket createSocket(String type, InetSocketAddress in) throws IOException
}

Socket socket = null;
TcpTimeouts tcpConnectTimeouts = orb.getORBData().getTransportTcpConnectTimeouts();
if (useNio) {
socket = super.createSocket(type, in);
socket = super.createSocket(orb.getORBData().connectionSocketType(), in, tcpConnectTimeouts.get_max_time_to_wait());
} else {
socket = new Socket(in.getHostName(), in.getPort());
socket.setTcpNoDelay(true);
socket = new Socket();
socket.connect(in, tcpConnectTimeouts.get_max_time_to_wait());
}


socket.setTcpNoDelay(true);
savedSocket = socket;
return socket;
}
Expand Down

0 comments on commit 40da3f9

Please sign in to comment.