Skip to content

Added Null check to Close Methods, Added Proxy config for TCP Sender & enable SSL hostname verification #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
import com.cloudbees.syslog.util.CachingReference;
import com.cloudbees.syslog.util.IoUtils;

import com.cloudbees.syslog.sender.proxy.ProxyConfig;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
Expand Down Expand Up @@ -70,6 +73,13 @@ public class TcpSyslogMessageSender extends AbstractSyslogMessageSender implemen
private int socketConnectTimeoutInMillis = SETTING_SOCKET_CONNECT_TIMEOUT_IN_MILLIS_DEFAULT_VALUE;
private boolean ssl;
private SSLContext sslContext;
private ProxyConfig proxyConfig;
/**
* If the last connection was via a proxy server this will contain the
* InetAddress of the syslog server that was connected to via the proxy.
*/
private InetAddress proxyConnectedSyslogServer;

/**
* Number of retries to send a message before throwing an exception.
*/
Expand Down Expand Up @@ -122,9 +132,36 @@ public synchronized void sendMessage(@Nonnull SyslogMessage message) throws IOEx
}
}

/**
* @return true if not proxy connected and the socket is connected to current configured syslog
*/
private boolean notProxyConnectedAddressChange(final InetAddress inetAddress) {
return proxyConnectedSyslogServer == null && !Objects.equals(socket.getInetAddress(), inetAddress);
}

/**
* @return true if currentProxyConfig status does not match proxyConnectedSyslogServer
*/
private boolean proxyUseHasChanged(final ProxyConfig currentProxyConfig) {
return (currentProxyConfig != null && proxyConnectedSyslogServer == null)
|| (currentProxyConfig == null && proxyConnectedSyslogServer != null);
}

/**
* @return true if proxy connected and either proxy connection or syslog server connection have changed
*/
private boolean proxyConnectedAddressChange(final InetAddress syslogServer, final ProxyConfig currentProxyConfig) {
return proxyConnectedSyslogServer != null && (!Objects.equals(syslogServer, proxyConnectedSyslogServer)
|| !Objects.equals(socket.getInetAddress(), currentProxyConfig.getHostnameReference().get()));
}

private synchronized void ensureSyslogServerConnection() throws IOException {
InetAddress inetAddress = syslogServerHostnameReference.get();
if (socket != null && !Objects.equals(socket.getInetAddress(), inetAddress)) {
final ProxyConfig currentProxyConfig = this.proxyConfig;
if (socket != null && (
notProxyConnectedAddressChange(inetAddress)
|| proxyUseHasChanged(currentProxyConfig)
|| proxyConnectedAddressChange(inetAddress, currentProxyConfig))) {
logger.info("InetAddress of the Syslog Server have changed, create a new connection. " +
"Before=" + socket.getInetAddress() + ", new=" + inetAddress);
IoUtils.closeQuietly(socket, writer);
Expand All @@ -145,19 +182,44 @@ private synchronized void ensureSyslogServerConnection() throws IOException {
if (!socketIsValid) {
writer = null;
try {
if (ssl) {
final SocketFactory socketFactory;
if (ssl) {
if (sslContext == null) {
socket = SSLSocketFactory.getDefault().createSocket();
socketFactory = SSLSocketFactory.getDefault();
} else {
socket = sslContext.getSocketFactory().createSocket();
socketFactory = sslContext.getSocketFactory();
}
} else {
socket = SocketFactory.getDefault().createSocket();
socketFactory = SocketFactory.getDefault();
}
socket.setKeepAlive(true);
socket.connect(
new InetSocketAddress(inetAddress, syslogServerPort),
socketConnectTimeoutInMillis);

final InetSocketAddress syslogServer = new InetSocketAddress(inetAddress, syslogServerPort);

if(currentProxyConfig == null) {
socket = socketFactory.createSocket();
socket.setKeepAlive(true);
socket.connect(
syslogServer,
socketConnectTimeoutInMillis);
proxyConnectedSyslogServer = null;
}else {
final InetSocketAddress proxyAddr = new InetSocketAddress(currentProxyConfig.getHostnameReference().get(), currentProxyConfig.getPort());
final Socket underlying = new Socket(new Proxy(Proxy.Type.HTTP, proxyAddr));
underlying.setKeepAlive(true);
underlying.connect(syslogServer);
socket = ((SSLSocketFactory)socketFactory).createSocket(
underlying,
syslogServer.getHostName(),
syslogServer.getPort(),
true);
socket.setKeepAlive(true);
final SSLSocket sslSocket = (SSLSocket) socket;
final SSLParameters sslParams = new SSLParameters();
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
sslSocket.setSSLParameters(sslParams);
proxyConnectedSyslogServer = inetAddress;
}


if (socket instanceof SSLSocket && logger.isLoggable(Level.FINER)) {
try {
Expand Down Expand Up @@ -241,7 +303,15 @@ public synchronized SSLContext getSSLContext() {
return this.sslContext;
}

public int getSocketConnectTimeoutInMillis() {
public ProxyConfig getProxyConfig() {
return proxyConfig;
}

public void setProxyConfig(ProxyConfig proxyConfig) {
this.proxyConfig = proxyConfig;
}

public int getSocketConnectTimeoutInMillis() {
return socketConnectTimeoutInMillis;
}

Expand Down Expand Up @@ -287,6 +357,7 @@ public String toString() {

@Override
public void close() throws IOException {
this.socket.close();
if(this.socket != null)
this.socket.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public String toString() {

@Override
public void close() throws IOException {
this.datagramSocket.close();
if(this.datagramSocket != null)
this.datagramSocket.close();
}
}
46 changes: 46 additions & 0 deletions src/main/java/com/cloudbees/syslog/sender/proxy/ProxyConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.cloudbees.syslog.sender.proxy;

import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.annotation.Nullable;

import com.cloudbees.syslog.sender.SyslogMessageSender;
import com.cloudbees.syslog.util.CachingReference;

public class ProxyConfig {

private final int port;
private final String hostname;
private final CachingReference<InetAddress> hostnameReference;

public ProxyConfig (final int port, final String hostname) {
this.port = port;
this.hostname = hostname;
this.hostnameReference = new CachingReference<InetAddress>(SyslogMessageSender.DEFAULT_INET_ADDRESS_TTL_IN_NANOS) {
@Nullable
@Override
protected InetAddress newObject() {
try {
return InetAddress.getByName(hostname);
} catch (UnknownHostException e) {
throw new IllegalStateException(e);
}
}
};
}

public int getPort() {
return port;
}

public String getHostname() {
return hostname;
}

public CachingReference<InetAddress> getHostnameReference() {
return hostnameReference;
}


}