Skip to content

Commit 0a2f69f

Browse files
author
Ian Craggs
committed
Fix up SNI function, while (re)allowing proxy support #573
1 parent 841cd90 commit 0a2f69f

15 files changed

Lines changed: 477 additions & 86 deletions

File tree

org.eclipse.paho.client.mqttv3/src/main/java/org/eclipse/paho/client/mqttv3/internal/SSLNetworkModule.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009, 2018 IBM Corp.
2+
* Copyright (c) 2009, 2019 IBM Corp.
33
*
44
* All rights reserved. This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License v1.0
@@ -16,8 +16,12 @@
1616
package org.eclipse.paho.client.mqttv3.internal;
1717

1818
import java.io.IOException;
19+
import java.util.ArrayList;
20+
import java.util.List;
1921

2022
import javax.net.ssl.HostnameVerifier;
23+
import javax.net.ssl.SNIHostName;
24+
import javax.net.ssl.SNIServerName;
2125
import javax.net.ssl.SSLParameters;
2226
import javax.net.ssl.SSLPeerUnverifiedException;
2327
import javax.net.ssl.SSLSession;
@@ -129,6 +133,13 @@ public void start() throws IOException, MqttException {
129133
// RTC 765: Set a timeout to avoid the SSL handshake being blocked indefinitely
130134
socket.setSoTimeout(this.handshakeTimeoutSecs * 1000);
131135

136+
// SNI support. Should be automatic under some circumstances - not all, apparently
137+
SSLParameters sslParameters = new SSLParameters();
138+
List<SNIServerName> sniHostNames = new ArrayList<SNIServerName>(1);
139+
sniHostNames.add(new SNIHostName(host));
140+
sslParameters.setServerNames(sniHostNames);
141+
((SSLSocket)socket).setSSLParameters(sslParameters);
142+
132143
// If default Hostname verification is enabled, use the same method that is used with HTTPS
133144
if(this.httpsHostnameVerificationEnabled) {
134145
SSLParameters sslParams = new SSLParameters();

org.eclipse.paho.client.mqttv3/src/main/java/org/eclipse/paho/client/mqttv3/internal/TCPNetworkModule.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009, 2018 IBM Corp.
2+
* Copyright (c) 2009, 2019 IBM Corp.
33
*
44
* All rights reserved. This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License v1.0
@@ -24,7 +24,6 @@
2424
import java.net.SocketAddress;
2525

2626
import javax.net.SocketFactory;
27-
import javax.net.ssl.SSLSocketFactory;
2827

2928
import org.eclipse.paho.client.mqttv3.MqttException;
3029
import org.eclipse.paho.client.mqttv3.logging.Logger;
@@ -71,15 +70,8 @@ public void start() throws IOException, MqttException {
7170
// @TRACE 252=connect to host {0} port {1} timeout {2}
7271
log.fine(CLASS_NAME,methodName, "252", new Object[] {host, Integer.valueOf(port), Long.valueOf(conTimeout*1000)});
7372
SocketAddress sockaddr = new InetSocketAddress(host, port);
74-
if (factory instanceof SSLSocketFactory) {
75-
// SNI support
76-
Socket tempsocket = new Socket();
77-
tempsocket.connect(sockaddr, conTimeout*1000);
78-
socket = ((SSLSocketFactory)factory).createSocket(tempsocket, host, port, true);
79-
} else {
80-
socket = factory.createSocket();
81-
socket.connect(sockaddr, conTimeout*1000);
82-
}
73+
socket = factory.createSocket();
74+
socket.connect(sockaddr, conTimeout*1000);
8375
socket.setSoTimeout(1000);
8476
}
8577
catch (ConnectException ex) {

org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/IMqttClient.java

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009, 2018 IBM Corp.
2+
* Copyright (c) 2009, 2019 IBM Corp.
33
*
44
* All rights reserved. This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License v1.0
@@ -335,21 +335,6 @@ public interface IMqttClient { //extends IMqttAsyncClient {
335335
* @param messageListener one callbacks to handle incoming messages
336336
* @throws MqttException if there was an error registering the subscription.
337337
*/
338-
public void subscribe(String[] topicFilters, IMqttMessageListener messageListener) throws MqttException;
339-
340-
/**
341-
* Subscribe to a topic, which may include wildcards.
342-
*
343-
* @see #subscribe(String[], int[])
344-
*
345-
* @param topicFilter the topic to subscribe to, which can include wildcards.
346-
* @param qos the maximum quality of service at which to subscribe. Messages
347-
* published at a lower quality of service will be received at the published
348-
* QoS. Messages published at a higher quality of service will be received using
349-
* the QoS specified on the subscribe.
350-
* @param messageListener a callback to handle incoming messages
351-
* @throws MqttException if there was an error registering the subscription.
352-
*/
353338
public void subscribe(String topicFilter, int qos, IMqttMessageListener messageListener) throws MqttException;
354339

355340
/**
@@ -783,7 +768,7 @@ public interface IMqttClient { //extends IMqttAsyncClient {
783768
* Get a topic object which can be used to publish messages.
784769
* <p>An alternative method that should be used in preference to this one when publishing a message is:</p>
785770
* <ul>
786-
* <li>{@link MqttLegacyBlockingClient#publish(String, MqttMessage)} to publish a message in a blocking manner
771+
* <li>{@link MqttClient#publish(String, MqttMessage)} to publish a message in a blocking manner
787772
* <li>or use publish methods on the non-blocking client like {@link IMqttAsyncClient#publish(String, MqttMessage, Object, MqttActionListener)}
788773
* </ul>
789774
* <p>When building an application,

org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/MqttAsyncClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009, 2018 IBM Corp.
2+
* Copyright (c) 2009, 2019 IBM Corp.
33
*
44
* All rights reserved. This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License v1.0
@@ -959,7 +959,7 @@ public String getCurrentServerURI() {
959959
* <ul>
960960
* <li>{@link MqttAsyncClient#publish(String, MqttMessage)} to publish a message
961961
* in a non-blocking manner or</li>
962-
* <li>{@link MqttLegacyBlockingClient#publish(String, MqttMessage)} to publish
962+
* <li>{@link MqttClient#publish(String, MqttMessage)} to publish
963963
* a message in a blocking manner</li>
964964
* </ul>
965965
* <p>

org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/MqttLegacyBlockingClient.java renamed to org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/MqttClient.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009, 2015 IBM Corp.
2+
* Copyright (c) 2009, 2019 IBM Corp.
33
*
44
* All rights reserved. This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License v1.0
@@ -76,7 +76,7 @@
7676
*
7777
* @see IMqttClient
7878
*/
79-
public class MqttLegacyBlockingClient implements IMqttClient {
79+
public class MqttClient implements IMqttClient {
8080

8181
protected MqttAsyncClient aClient = null; // Delegate implementation to MqttAsyncClient
8282
protected long timeToWait = -1; // How long each method should wait for action to complete
@@ -168,7 +168,7 @@ public class MqttLegacyBlockingClient implements IMqttClient {
168168
* @throws MqttException
169169
* if any other problem was encountered
170170
*/
171-
public MqttLegacyBlockingClient(String serverURI, String clientId) throws MqttException {
171+
public MqttClient(String serverURI, String clientId) throws MqttException {
172172
this(serverURI, clientId, new MqttDefaultFilePersistence());
173173
}
174174

@@ -275,7 +275,7 @@ public MqttLegacyBlockingClient(String serverURI, String clientId) throws MqttEx
275275
* @throws MqttException
276276
* if any other problem was encountered
277277
*/
278-
public MqttLegacyBlockingClient(String serverURI, String clientId, MqttClientPersistence persistence)
278+
public MqttClient(String serverURI, String clientId, MqttClientPersistence persistence)
279279
throws MqttException {
280280
aClient = new MqttAsyncClient(serverURI, clientId, persistence);
281281
}
@@ -386,7 +386,7 @@ public MqttLegacyBlockingClient(String serverURI, String clientId, MqttClientPer
386386
* @throws MqttException
387387
* if any other problem was encountered
388388
*/
389-
public MqttLegacyBlockingClient(String serverURI, String clientId, MqttClientPersistence persistence,
389+
public MqttClient(String serverURI, String clientId, MqttClientPersistence persistence,
390390
ScheduledExecutorService executorService) throws MqttException {
391391
aClient = new MqttAsyncClient(serverURI, clientId, persistence, null, executorService);
392392
}
@@ -516,13 +516,26 @@ public void subscribe(MqttSubscription[] subscriptions) throws MqttException {
516516
int[] grantedQos = tok.getGrantedQos();
517517
for (int i = 0; i < grantedQos.length; ++i) {
518518
subscriptions[i].setQos(grantedQos[i]);
519-
;
520519
}
521520
if (grantedQos.length == 1 && subscriptions[0].getQos() == 0x80) {
522521
throw new MqttException(MqttClientException.REASON_CODE_SUBSCRIBE_FAILED);
523522
}
524523
}
525524

525+
@Override
526+
public void subscribe(String[] topicFilters, int[] qos) throws MqttException {
527+
if (topicFilters.length != qos.length) {
528+
throw new MqttException(MqttClientException.REASON_CODE_UNEXPECTED_ERROR);
529+
}
530+
531+
MqttSubscription[] subscriptions = new MqttSubscription[topicFilters.length];
532+
for (int i = 0; i < topicFilters.length; ++i) {
533+
subscriptions[i] = new MqttSubscription(topicFilters[i], qos[i]);
534+
}
535+
536+
this.subscribe(subscriptions);
537+
}
538+
526539
/*
527540
* (non-Javadoc)
528541
*
@@ -533,11 +546,6 @@ public void subscribe(String topicFilter, IMqttMessageListener messageListener)
533546
this.subscribe(new String[] { topicFilter }, new int[] { 1 }, new IMqttMessageListener[] { messageListener });
534547
}
535548

536-
@Override
537-
public void subscribe(String[] topicFilters, IMqttMessageListener messageListener) throws MqttException {
538-
this.subscribe(topicFilters, new IMqttMessageListener[] { messageListener });
539-
}
540-
541549
/*
542550
* (non-Javadoc)
543551
*
@@ -562,10 +570,6 @@ public void subscribe(String topicFilter, int qos, IMqttMessageListener messageL
562570
this.subscribe(new String[] { topicFilter }, new int[] { qos }, new IMqttMessageListener[] { messageListener });
563571
}
564572

565-
@Override
566-
public void subscribe(String[] topicFilters, int[] qos) throws MqttException {
567-
this.subscribe(topicFilters, qos, new IMqttMessageListener[] {});
568-
}
569573

570574
public void subscribe(String[] topicFilters, int[] qos, IMqttMessageListener[] messageListeners)
571575
throws MqttException {
@@ -673,7 +677,7 @@ public void setTimeToWait(long timeToWaitInMillis) throws IllegalArgumentExcepti
673677
* Return the maximum time to wait for an action to complete.
674678
*
675679
* @return the time to wait
676-
* @see MqttLegacyBlockingClient#setTimeToWait(long)
680+
* @see MqttClient#setTimeToWait(long)
677681
*/
678682
public long getTimeToWait() {
679683
return this.timeToWait;

org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/MqttClientPersistence.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009, 2014 IBM Corp.
2+
* Copyright (c) 2009, 2019 IBM Corp.
33
*
44
* All rights reserved. This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License v1.0
@@ -23,8 +23,8 @@
2323
/**
2424
* Represents a persistent data store, used to store outbound and inbound messages while they
2525
* are in flight, enabling delivery to the QoS specified. You can specify an implementation
26-
* of this interface using {@link MqttLegacyBlockingClient#MqttLegacyBlockingClient(String, String, MqttClientPersistence)},
27-
* which the {@link MqttLegacyBlockingClient} will use to persist QoS 1 and 2 messages.
26+
* of this interface using {@link MqttClient#MqttLegacyBlockingClient(String, String, MqttClientPersistence)},
27+
* which the {@link MqttClient} will use to persist QoS 1 and 2 messages.
2828
* <p>
2929
* If the methods defined throw the MqttPersistenceException then the state of the data persisted
3030
* should remain as prior to the method being called. For example, if {@link #put(String, MqttPersistable)}

org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/alpha/MqttClientPersistence.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.eclipse.paho.mqttv5.client.alpha;
1717

18-
import org.eclipse.paho.mqttv5.client.MqttLegacyBlockingClient;
18+
import org.eclipse.paho.mqttv5.client.MqttClient;
1919
import org.eclipse.paho.mqttv5.common.MqttPersistable;
2020
import org.eclipse.paho.mqttv5.common.MqttPersistenceException;
2121

org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/internal/SSLNetworkModule.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009, 2018 IBM Corp.
2+
* Copyright (c) 2009, 2019 IBM Corp.
33
*
44
* All rights reserved. This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License v1.0
@@ -16,8 +16,12 @@
1616
package org.eclipse.paho.mqttv5.client.internal;
1717

1818
import java.io.IOException;
19+
import java.util.ArrayList;
20+
import java.util.List;
1921

2022
import javax.net.ssl.HostnameVerifier;
23+
import javax.net.ssl.SNIHostName;
24+
import javax.net.ssl.SNIServerName;
2125
import javax.net.ssl.SSLParameters;
2226
import javax.net.ssl.SSLPeerUnverifiedException;
2327
import javax.net.ssl.SSLSession;
@@ -125,12 +129,18 @@ public void start() throws IOException, MqttException {
125129
// RTC 765: Set a timeout to avoid the SSL handshake being blocked indefinitely
126130
socket.setSoTimeout(this.handshakeTimeoutSecs * 1000);
127131

128-
// If default Hostname verification is enabled, use the same method that is used
129-
// with HTTPS
132+
// SNI support. Should be automatic under some circumstances - not all, apparently
133+
SSLParameters sslParameters = new SSLParameters();
134+
List<SNIServerName> sniHostNames = new ArrayList<SNIServerName>(1);
135+
sniHostNames.add(new SNIHostName(host));
136+
sslParameters.setServerNames(sniHostNames);
137+
((SSLSocket)socket).setSSLParameters(sslParameters);
138+
139+
// If default Hostname verification is enabled, use the same method that is used with HTTPS
130140
if (this.httpsHostnameVerificationEnabled) {
131141
SSLParameters sslParams = new SSLParameters();
132142
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
133-
((SSLSocket) socket).setSSLParameters(sslParams);
143+
((SSLSocket) socket).setSSLParameters(sslParams);
134144
}
135145

136146
((SSLSocket) socket).startHandshake();

org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/internal/TCPNetworkModule.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.net.SocketAddress;
2525

2626
import javax.net.SocketFactory;
27-
import javax.net.ssl.SSLSocketFactory;
2827

2928
import org.eclipse.paho.mqttv5.client.MqttClientException;
3029
import org.eclipse.paho.mqttv5.client.logging.Logger;
@@ -69,25 +68,12 @@ public TCPNetworkModule(SocketFactory factory, String host, int port, String res
6968
public void start() throws IOException, MqttException {
7069
final String methodName = "start";
7170
try {
72-
// InetAddress localAddr = InetAddress.getLocalHost();
73-
// socket = factory.createSocket(host, port, localAddr, 0);
7471
// @TRACE 252=connect to host {0} port {1} timeout {2}
7572
log.fine(CLASS_NAME,methodName, "252", new Object[] {host, new Integer(port), new Long(conTimeout*1000)});
7673
SocketAddress sockaddr = new InetSocketAddress(host, port);
77-
if (factory instanceof SSLSocketFactory) {
78-
// SNI support
79-
Socket tempsocket = new Socket();
80-
tempsocket.connect(sockaddr, conTimeout*1000);
81-
socket = ((SSLSocketFactory)factory).createSocket(tempsocket, host, port, true);
82-
} else {
83-
socket = factory.createSocket();
84-
socket.connect(sockaddr, conTimeout*1000);
85-
}
74+
socket = factory.createSocket();
75+
socket.connect(sockaddr, conTimeout*1000);
8676
socket.setSoTimeout(1000);
87-
88-
// SetTcpNoDelay was originally set ot true disabling Nagle's algorithm.
89-
// This should not be required.
90-
// socket.setTcpNoDelay(true); // TCP_NODELAY on, which means we do not use Nagle's algorithm
9177
}
9278
catch (ConnectException ex) {
9379
//@TRACE 250=Failed to create TCP socket

0 commit comments

Comments
 (0)