Skip to content

Commit 240d207

Browse files
committed
Merge branch 'master' into jdbc-test
2 parents 1257b87 + fc626bc commit 240d207

File tree

13 files changed

+1740
-1176
lines changed

13 files changed

+1740
-1176
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
<apache.mina.version>2.2.4</apache.mina.version>
102102
<commons.io.version>2.20.0</commons.io.version>
103103
<orchestra.file>OrchestraFIXLatest.xml</orchestra.file>
104-
<org.quickfixj.orchestra.tools.version>1.0.2</org.quickfixj.orchestra.tools.version>
104+
<org.quickfixj.orchestra.tools.version>1.0.3</org.quickfixj.orchestra.tools.version>
105105
<jaxen.version>2.0.0</jaxen.version>
106106
<jmh.version>1.37</jmh.version>
107107
<jcstress.version>0.16</jcstress.version>

quickfixj-base/src/main/java/quickfix/Message.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ private void toXMLFields(Element message, String section, FieldMap fieldMap,
432432
}
433433
}
434434

435-
public final Header getHeader() {
435+
public Header getHeader() {
436436
return header;
437437
}
438438

quickfixj-codegenerator/src/main/resources/org/quickfixj/codegenerator/Message.xsl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ public class Message extends quickfix.Message {
8080
return new Header(this);
8181
}
8282

83+
@Override
84+
public Header getHeader() {
85+
return (Message.Header)header;
86+
}
87+
8388
public static class Header extends quickfix.Message.Header {
8489

8590
static final long serialVersionUID = <xsl:value-of select="$serialVersionUID"/>;

quickfixj-core/pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,13 @@
123123
<version>4.2.6.Final</version>
124124
<scope>test</scope>
125125
</dependency>
126-
<dependency>
126+
<dependency>
127+
<groupId>org.burningwave</groupId>
128+
<artifactId>tools</artifactId>
129+
<version>0.27.2</version>
130+
<scope>test</scope>
131+
</dependency>
132+
<dependency>
127133
<groupId>org.apache.mina</groupId>
128134
<artifactId>mina-core</artifactId>
129135
</dependency>

quickfixj-core/src/main/doc/usermanual/usage/configuration.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,22 @@ <H3>QuickFIX Settings</H3>
714714
<TD></TD>
715715
<TD></TD>
716716
</TR>
717+
<TR ALIGN="left" VALIGN="middle">
718+
<TD valign="top"> <I>UseSNI</I></TD>
719+
<TD>
720+
Enables the SSL engine to use Server Name Indication (SNI). This option is only applicable for initiators.
721+
<p>If provided, <i>SNIHostName</i> will be used as the server name. Otherwise, <i>SocketConnectHost</i> or <i>SocketConnectHost&lt;n&gt;</i> will be used.</p>
722+
<p>Note: When this option is disabled, the JVM may still implicitly send the SSL <code>server_name</code> extension.</p>
723+
</TD>
724+
<TD>Y<BR>N</TD>
725+
<TD>N</TD>
726+
</TR>
727+
<TR ALIGN="left" VALIGN="middle">
728+
<TD valign="top"> <I>SNIHostName</I></TD>
729+
<TD>SNI host name to be used as desired Server Name Indication (SNI) parameter.</TD>
730+
<TD></TD>
731+
<TD></TD>
732+
</TR>
717733

718734
<TR ALIGN="center" VALIGN="middle">
719735
<TD COLSPAN="4" class="subsection"><A NAME="Security">Socks Proxy Options (Initiator only)</A></TD>

quickfixj-core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import quickfix.mina.ProtocolFactory;
4040
import quickfix.mina.SessionConnector;
4141
import quickfix.mina.message.FIXProtocolCodecFactory;
42+
import quickfix.mina.ssl.InitiatorSslFilter;
4243
import quickfix.mina.ssl.SSLConfig;
4344
import quickfix.mina.ssl.SSLContextFactory;
4445
import quickfix.mina.ssl.SSLSupport;
@@ -193,7 +194,7 @@ private void setupIoConnector() throws ConfigError, GeneralSecurityException {
193194
private void installSslFilter(CompositeIoFilterChainBuilder ioFilterChainBuilder)
194195
throws GeneralSecurityException {
195196
final SSLContext sslContext = SSLContextFactory.getInstance(sslConfig);
196-
final SslFilter sslFilter = new SslFilter(sslContext, false);
197+
final SslFilter sslFilter = new InitiatorSslFilter(sslContext, getSniHostName(sslConfig));
197198
sslFilter.setEnabledCipherSuites(sslConfig.getEnabledCipherSuites() != null ? sslConfig.getEnabledCipherSuites()
198199
: SSLSupport.getDefaultCipherSuites(sslContext));
199200
sslFilter.setEnabledProtocols(sslConfig.getEnabledProtocols() != null ? sslConfig.getEnabledProtocols()
@@ -202,6 +203,22 @@ private void installSslFilter(CompositeIoFilterChainBuilder ioFilterChainBuilder
202203
ioFilterChainBuilder.addLast(SSLSupport.FILTER_NAME, sslFilter);
203204
}
204205

206+
public String getSniHostName(SSLConfig sslConfig) {
207+
if (!sslConfig.isUseSNI()) {
208+
return null;
209+
}
210+
211+
if (sslConfig.getSniHostName() != null) {
212+
return sslConfig.getSniHostName();
213+
}
214+
215+
if (socketAddresses[nextSocketAddressIndex] instanceof InetSocketAddress) {
216+
return ((InetSocketAddress) socketAddresses[nextSocketAddressIndex]).getHostName();
217+
}
218+
219+
return null;
220+
}
221+
205222
@Override
206223
public void run() {
207224
resetIoConnector();
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package quickfix.mina.ssl;
2+
3+
import org.apache.mina.core.session.IoSession;
4+
import org.apache.mina.filter.ssl.SslFilter;
5+
6+
import javax.net.ssl.SNIHostName;
7+
import javax.net.ssl.SSLContext;
8+
import javax.net.ssl.SSLEngine;
9+
import javax.net.ssl.SSLParameters;
10+
import java.net.InetSocketAddress;
11+
import java.util.Arrays;
12+
13+
public final class InitiatorSslFilter extends SslFilter {
14+
15+
private final String sniHostName;
16+
17+
public InitiatorSslFilter(SSLContext sslContext, String sniHostName) {
18+
super(sslContext, false);
19+
this.sniHostName = sniHostName;
20+
}
21+
22+
@Override
23+
protected SSLEngine createEngine(IoSession session, InetSocketAddress addr) {
24+
SSLEngine sslEngine;
25+
26+
if (addr != null) {
27+
sslEngine = sslContext.createSSLEngine(addr.getHostName(), addr.getPort());
28+
} else {
29+
sslEngine = sslContext.createSSLEngine();
30+
}
31+
32+
if (wantClientAuth) {
33+
sslEngine.setWantClientAuth(true);
34+
}
35+
36+
if (needClientAuth) {
37+
sslEngine.setNeedClientAuth(true);
38+
}
39+
40+
if (enabledCipherSuites != null) {
41+
sslEngine.setEnabledCipherSuites(enabledCipherSuites);
42+
}
43+
44+
if (enabledProtocols != null) {
45+
sslEngine.setEnabledProtocols(enabledProtocols);
46+
}
47+
48+
if (getEndpointIdentificationAlgorithm() != null) {
49+
SSLParameters sslParameters = sslEngine.getSSLParameters();
50+
sslParameters.setEndpointIdentificationAlgorithm(getEndpointIdentificationAlgorithm());
51+
sslEngine.setSSLParameters(sslParameters);
52+
}
53+
54+
if (sniHostName != null) {
55+
SSLParameters sslParameters = sslEngine.getSSLParameters();
56+
sslParameters.setServerNames(Arrays.asList(new SNIHostName(sniHostName)));
57+
sslEngine.setSSLParameters(sslParameters);
58+
}
59+
60+
sslEngine.setUseClientMode(!session.isServer());
61+
62+
return sslEngine;
63+
}
64+
}

quickfixj-core/src/main/java/quickfix/mina/ssl/SSLConfig.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public class SSLConfig {
3838
private String[] enabledCipherSuites;
3939
private boolean needClientAuth;
4040
private String endpointIdentificationAlgorithm;
41+
private boolean useSNI;
42+
private String sniHostName;
4143

4244
public String[] getEnabledCipherSuites() {
4345
return enabledCipherSuites;
@@ -87,7 +89,15 @@ public String getEndpointIdentificationAlgorithm() {
8789
return endpointIdentificationAlgorithm;
8890
}
8991

90-
public void setEnabledCipherSuites(String[] enabledCipherSuites) {
92+
public boolean isUseSNI() {
93+
return useSNI;
94+
}
95+
96+
public String getSniHostName() {
97+
return sniHostName;
98+
}
99+
100+
public void setEnabledCipherSuites(String[] enabledCipherSuites) {
91101
this.enabledCipherSuites = enabledCipherSuites;
92102
}
93103

@@ -119,7 +129,15 @@ public void setEndpointIdentificationAlgorithm(String endpointIdentificationAlgo
119129
this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
120130
}
121131

122-
public void setTrustManagerFactoryAlgorithm(String trustManagerFactoryAlgorithm) {
132+
public void setUseSNI(boolean useSNI) {
133+
this.useSNI = useSNI;
134+
}
135+
136+
public void setSniHostName(String sniHostName) {
137+
this.sniHostName = sniHostName;
138+
}
139+
140+
public void setTrustManagerFactoryAlgorithm(String trustManagerFactoryAlgorithm) {
123141
this.trustManagerFactoryAlgorithm = trustManagerFactoryAlgorithm;
124142
}
125143

@@ -151,12 +169,14 @@ public boolean equals(Object o) {
151169
Objects.equals(trustStoreType, sslConfig.trustStoreType) &&
152170
Arrays.equals(enabledProtocols, sslConfig.enabledProtocols) &&
153171
Arrays.equals(enabledCipherSuites, sslConfig.enabledCipherSuites) &&
154-
Objects.equals(endpointIdentificationAlgorithm, sslConfig.endpointIdentificationAlgorithm);
172+
Objects.equals(endpointIdentificationAlgorithm, sslConfig.endpointIdentificationAlgorithm) &&
173+
Objects.equals(useSNI, sslConfig.useSNI) &&
174+
Objects.equals(sniHostName, sslConfig.sniHostName);
155175
}
156176

157177
@Override
158178
public int hashCode() {
159-
int result = Objects.hash(keyStoreName, keyManagerFactoryAlgorithm, keyStoreType, trustStoreName, trustManagerFactoryAlgorithm, trustStoreType, needClientAuth, endpointIdentificationAlgorithm);
179+
int result = Objects.hash(keyStoreName, keyManagerFactoryAlgorithm, keyStoreType, trustStoreName, trustManagerFactoryAlgorithm, trustStoreType, needClientAuth, endpointIdentificationAlgorithm, useSNI, sniHostName);
160180
result = 31 * result + Arrays.hashCode(keyStorePassword);
161181
result = 31 * result + Arrays.hashCode(trustStorePassword);
162182
result = 31 * result + Arrays.hashCode(enabledProtocols);

quickfixj-core/src/main/java/quickfix/mina/ssl/SSLSupport.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public class SSLSupport {
4040
public static final String SETTING_TRUST_STORE_TYPE = "TrustStoreType";
4141
public static final String SETTING_NEED_CLIENT_AUTH = "NeedClientAuth";
4242
public static final String SETTING_ENDPOINT_IDENTIFICATION_ALGORITHM = "EndpointIdentificationAlgorithm";
43+
public static final String SETTING_USE_SNI = "UseSNI";
44+
public static final String SETTING_SNI_HOST_NAME = "SNIHostName";
4345
public static final String SETTING_ENABLED_PROTOCOLS = "EnabledProtocols";
4446
public static final String SETTING_CIPHER_SUITES = "CipherSuites";
4547
static final String DEFAULT_STORE_TYPE = "JKS";
@@ -112,6 +114,8 @@ public static SSLConfig getSslConfig(SessionSettings sessionSettings, SessionID
112114
sslConfig.setEnabledProtocols(getEnabledProtocols(sessionSettings, sessionID));
113115
sslConfig.setNeedClientAuth(isNeedClientAuth(sessionSettings, sessionID));
114116
sslConfig.setEndpointIdentificationAlgorithm(getEndpointIdentificationAlgorithm(sessionSettings, sessionID));
117+
sslConfig.setUseSNI(isUseSNI(sessionSettings, sessionID));
118+
sslConfig.setSniHostName(getSNIHostName(sessionSettings, sessionID));
115119

116120
return sslConfig;
117121
}
@@ -153,4 +157,12 @@ public static boolean isNeedClientAuth(SessionSettings sessionSettings, SessionI
153157
public static String getEndpointIdentificationAlgorithm(SessionSettings sessionSettings, SessionID sessionID) {
154158
return getString(sessionSettings, sessionID, SETTING_ENDPOINT_IDENTIFICATION_ALGORITHM, null);
155159
}
160+
161+
public static boolean isUseSNI(SessionSettings sessionSettings, SessionID sessionID) {
162+
return "Y".equals(getString(sessionSettings, sessionID, SETTING_USE_SNI, "N"));
163+
}
164+
165+
public static String getSNIHostName(SessionSettings sessionSettings, SessionID sessionID) {
166+
return getString(sessionSettings, sessionID, SETTING_SNI_HOST_NAME, null);
167+
}
156168
}

quickfixj-core/src/test/java/quickfix/MessageTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.junit.Assert.assertNotEquals;
2525
import static org.junit.Assert.assertNotNull;
2626
import static org.junit.Assert.assertNull;
27+
import static org.junit.Assert.assertSame;
2728
import static org.junit.Assert.assertTrue;
2829
import static org.junit.Assert.fail;
2930

@@ -110,6 +111,7 @@
110111
import quickfix.field.StrikePrice;
111112
import quickfix.field.Symbol;
112113
import quickfix.field.TargetCompID;
114+
import quickfix.field.TargetSubID;
113115
import quickfix.field.Text;
114116
import quickfix.field.TotNoOrders;
115117
import quickfix.field.TradeDate;
@@ -132,6 +134,7 @@
132134
import quickfix.fix44.component.Instrument;
133135
import quickfix.fix44.component.Parties;
134136
import quickfix.fix50.MarketDataSnapshotFullRefresh;
137+
import quickfix.fixt11.TestRequest;
135138

136139
/**
137140
* NOTE: There are two MessageTests. One in quickfixj-base, one in
@@ -1509,6 +1512,24 @@ public void testFirstFieldInGroupIsDelimiter() throws Exception {
15091512
assertEquals(600, noml5.getGroup(1, 555).delim());
15101513
}
15111514

1515+
@Test
1516+
public void shouldReturnFixSpecificHeader() throws FieldNotFound {
1517+
NewOrderSingle order = new NewOrderSingle();
1518+
assertSame(quickfix.fix42.Message.Header.class, order.getHeader().getClass());
1519+
1520+
order.getHeader().set(new TargetSubID("foo"));
1521+
assertEquals(order.getHeader().getTargetSubID().getValue(), "foo");
1522+
1523+
quickfix.fixlatest.NewOrderSingle fixLatestOrder = new quickfix.fixlatest.NewOrderSingle();
1524+
assertSame(quickfix.fixlatest.Message.Header.class, fixLatestOrder.getHeader().getClass());
1525+
1526+
quickfix.fix50sp1.NewOrderSingle fix50sp1Order = new quickfix.fix50sp1.NewOrderSingle();
1527+
assertSame(quickfix.fix50sp1.Message.Header.class, fix50sp1Order.getHeader().getClass());
1528+
1529+
TestRequest testRequest = new TestRequest();
1530+
assertSame(quickfix.fixt11.Message.Header.class, testRequest.getHeader().getClass());
1531+
}
1532+
15121533
private void assertHeaderField(Message message, String expectedValue, int field)
15131534
throws FieldNotFound {
15141535
assertEquals(expectedValue, message.getHeader().getString(field));

0 commit comments

Comments
 (0)