quickfix_ruby 1.14.3.1 → 1.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/ext/quickfix/Acceptor.h +2 -0
  3. data/ext/quickfix/AtomicCount.h +82 -12
  4. data/ext/quickfix/DOMDocument.h +9 -7
  5. data/ext/quickfix/DataDictionary.cpp +77 -14
  6. data/ext/quickfix/DataDictionary.h +90 -16
  7. data/ext/quickfix/Dictionary.cpp +1 -2
  8. data/ext/quickfix/Exceptions.h +3 -5
  9. data/ext/quickfix/Field.h +83 -32
  10. data/ext/quickfix/FieldConvertors.cpp +93 -0
  11. data/ext/quickfix/FieldConvertors.h +129 -275
  12. data/ext/quickfix/FieldMap.cpp +53 -13
  13. data/ext/quickfix/FieldMap.h +200 -62
  14. data/ext/quickfix/FieldTypes.cpp +10 -10
  15. data/ext/quickfix/FieldTypes.h +293 -44
  16. data/ext/quickfix/FileLog.cpp +6 -10
  17. data/ext/quickfix/FileLog.h +4 -10
  18. data/ext/quickfix/FileStore.cpp +19 -6
  19. data/ext/quickfix/FileStore.h +4 -0
  20. data/ext/quickfix/FixFieldNumbers.h +1462 -1461
  21. data/ext/quickfix/FixFields.h +1462 -1461
  22. data/ext/quickfix/FixValues.h +3230 -3227
  23. data/ext/quickfix/HttpConnection.cpp +1 -1
  24. data/ext/quickfix/Initiator.cpp +7 -1
  25. data/ext/quickfix/Initiator.h +2 -0
  26. data/ext/quickfix/Log.h +6 -12
  27. data/ext/quickfix/Message.cpp +186 -57
  28. data/ext/quickfix/Message.h +109 -47
  29. data/ext/quickfix/MySQLConnection.h +1 -1
  30. data/ext/quickfix/PostgreSQLConnection.h +1 -1
  31. data/ext/quickfix/QuickfixRuby.cpp +79141 -77959
  32. data/ext/quickfix/QuickfixRuby.h +1 -1
  33. data/ext/quickfix/SSLSocketAcceptor.cpp +410 -0
  34. data/ext/quickfix/SSLSocketAcceptor.h +185 -0
  35. data/ext/quickfix/SSLSocketConnection.cpp +427 -0
  36. data/ext/quickfix/SSLSocketConnection.h +206 -0
  37. data/ext/quickfix/SSLSocketInitiator.cpp +485 -0
  38. data/ext/quickfix/SSLSocketInitiator.h +196 -0
  39. data/ext/quickfix/Session.cpp +113 -20
  40. data/ext/quickfix/Session.h +18 -4
  41. data/ext/quickfix/SessionFactory.cpp +10 -3
  42. data/ext/quickfix/SessionSettings.cpp +5 -3
  43. data/ext/quickfix/SessionSettings.h +97 -5
  44. data/ext/quickfix/Settings.cpp +72 -2
  45. data/ext/quickfix/Settings.h +3 -0
  46. data/ext/quickfix/SharedArray.h +140 -6
  47. data/ext/quickfix/SocketConnection.cpp +2 -2
  48. data/ext/quickfix/SocketConnector.cpp +5 -2
  49. data/ext/quickfix/SocketConnector.h +3 -2
  50. data/ext/quickfix/SocketInitiator.cpp +28 -4
  51. data/ext/quickfix/SocketInitiator.h +1 -1
  52. data/ext/quickfix/SocketMonitor.cpp +5 -5
  53. data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +455 -0
  54. data/ext/quickfix/ThreadedSSLSocketAcceptor.h +217 -0
  55. data/ext/quickfix/ThreadedSSLSocketConnection.cpp +404 -0
  56. data/ext/quickfix/ThreadedSSLSocketConnection.h +189 -0
  57. data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +469 -0
  58. data/ext/quickfix/ThreadedSSLSocketInitiator.h +201 -0
  59. data/ext/quickfix/ThreadedSocketAcceptor.cpp +5 -1
  60. data/ext/quickfix/ThreadedSocketConnection.cpp +8 -2
  61. data/ext/quickfix/ThreadedSocketConnection.h +4 -1
  62. data/ext/quickfix/ThreadedSocketInitiator.cpp +24 -4
  63. data/ext/quickfix/ThreadedSocketInitiator.h +1 -1
  64. data/ext/quickfix/Utility.cpp +23 -1
  65. data/ext/quickfix/Utility.h +28 -2
  66. data/ext/quickfix/UtilitySSL.cpp +1733 -0
  67. data/ext/quickfix/UtilitySSL.h +277 -0
  68. data/ext/quickfix/config-all.h +10 -0
  69. data/ext/quickfix/dirent_windows.h +838 -0
  70. data/ext/quickfix/double-conversion/bignum-dtoa.cc +641 -0
  71. data/ext/quickfix/double-conversion/bignum-dtoa.h +84 -0
  72. data/ext/quickfix/double-conversion/bignum.cc +766 -0
  73. data/ext/quickfix/double-conversion/bignum.h +144 -0
  74. data/ext/quickfix/double-conversion/cached-powers.cc +176 -0
  75. data/ext/quickfix/double-conversion/cached-powers.h +64 -0
  76. data/ext/quickfix/double-conversion/diy-fp.cc +57 -0
  77. data/ext/quickfix/double-conversion/diy-fp.h +118 -0
  78. data/ext/quickfix/double-conversion/double-conversion.cc +994 -0
  79. data/ext/quickfix/double-conversion/double-conversion.h +543 -0
  80. data/ext/quickfix/double-conversion/fast-dtoa.cc +665 -0
  81. data/ext/quickfix/double-conversion/fast-dtoa.h +88 -0
  82. data/ext/quickfix/double-conversion/fixed-dtoa.cc +404 -0
  83. data/ext/quickfix/double-conversion/fixed-dtoa.h +56 -0
  84. data/ext/quickfix/double-conversion/ieee.h +402 -0
  85. data/ext/quickfix/double-conversion/strtod.cc +557 -0
  86. data/ext/quickfix/double-conversion/strtod.h +45 -0
  87. data/ext/quickfix/double-conversion/utils.h +372 -0
  88. data/ext/quickfix/stdint_msvc.h +254 -0
  89. data/lib/quickfix44.rb +3329 -10
  90. data/lib/quickfix50.rb +6649 -81
  91. data/lib/quickfix50sp1.rb +8054 -142
  92. data/lib/quickfix50sp2.rb +10900 -234
  93. data/lib/quickfix_fields.rb +7662 -7649
  94. data/spec/FIX40.xml +28 -28
  95. data/spec/FIX41.xml +29 -29
  96. data/spec/FIX42.xml +47 -47
  97. data/spec/FIX43.xml +148 -148
  98. data/spec/FIX44.xml +1078 -1081
  99. data/spec/FIX50.xml +1292 -1289
  100. data/spec/FIX50SP1.xml +1811 -1802
  101. data/spec/FIX50SP2.xml +1948 -1939
  102. data/spec/FIXT11.xml +5 -8
  103. data/test/test_FieldBaseTestCase.rb +1 -1
  104. data/test/test_MessageTestCase.rb +2 -2
  105. metadata +42 -6
@@ -82,7 +82,7 @@ bool SocketConnection::processQueue()
82
82
 
83
83
  const std::string& msg = m_sendQueue.front();
84
84
 
85
- size_t result = socket_send
85
+ ssize_t result = socket_send
86
86
  ( m_socket, msg.c_str() + m_sendLength, msg.length() - m_sendLength );
87
87
 
88
88
  if( result > 0 )
@@ -197,7 +197,7 @@ bool SocketConnection::isValidSession()
197
197
  void SocketConnection::readFromSocket()
198
198
  throw( SocketRecvFailed )
199
199
  {
200
- ssize_t size = recv( m_socket, m_buffer, sizeof(m_buffer), 0 );
200
+ ssize_t size = socket_recv( m_socket, m_buffer, sizeof(m_buffer) );
201
201
  if( size <= 0 ) throw SocketRecvFailed( size );
202
202
  m_parser.addToStream( m_buffer, size );
203
203
  }
@@ -83,7 +83,8 @@ SocketConnector::SocketConnector( int timeout )
83
83
  : m_monitor( timeout ) {}
84
84
 
85
85
  int SocketConnector::connect( const std::string& address, int port, bool noDelay,
86
- int sendBufSize, int rcvBufSize )
86
+ int sendBufSize, int rcvBufSize,
87
+ const std::string& sourceAddress, int sourcePort)
87
88
  {
88
89
  int socket = socket_createConnector();
89
90
 
@@ -95,6 +96,8 @@ int SocketConnector::connect( const std::string& address, int port, bool noDelay
95
96
  socket_setsockopt( socket, SO_SNDBUF, sendBufSize );
96
97
  if( rcvBufSize )
97
98
  socket_setsockopt( socket, SO_RCVBUF, rcvBufSize );
99
+ if ( !sourceAddress.empty() || sourcePort )
100
+ socket_bind( socket, sourceAddress.c_str(), sourcePort );
98
101
  m_monitor.addConnect( socket );
99
102
  socket_connect( socket, address.c_str(), port );
100
103
  }
@@ -104,7 +107,7 @@ int SocketConnector::connect( const std::string& address, int port, bool noDelay
104
107
  int SocketConnector::connect( const std::string& address, int port, bool noDelay,
105
108
  int sendBufSize, int rcvBufSize, Strategy& strategy )
106
109
  {
107
- int socket = connect( address, port, noDelay, sendBufSize, rcvBufSize );
110
+ int socket = connect( address, port, noDelay, sendBufSize, rcvBufSize, "", 0);
108
111
  return socket;
109
112
  }
110
113
 
@@ -39,8 +39,9 @@ public:
39
39
 
40
40
  SocketConnector( int timeout = 0 );
41
41
 
42
- int connect( const std::string& address, int port, bool noDelay,
43
- int sendBufSize, int rcvBufSize );
42
+ int connect( const std::string& address, int port, bool noDelay,
43
+ int sendBufSize, int rcvBufSize,
44
+ const std::string& sourceAddress = "", int sourcePort = 0);
44
45
  int connect( const std::string& address, int port, bool noDelay,
45
46
  int sendBufSize, int rcvBufSize, Strategy& );
46
47
  void block( Strategy& strategy, bool poll = 0, double timeout = 0.0 );
@@ -134,15 +134,18 @@ void SocketInitiator::doConnect( const SessionID& s, const Dictionary& d )
134
134
  {
135
135
  std::string address;
136
136
  short port = 0;
137
+ std::string sourceAddress;
138
+ short sourcePort = 0;
139
+
137
140
  Session* session = Session::lookupSession( s );
138
141
  if( !session->isSessionTime(UtcTimeStamp()) ) return;
139
142
 
140
143
  Log* log = session->getLog();
141
144
 
142
- getHost( s, d, address, port );
145
+ getHost( s, d, address, port, sourceAddress, sourcePort );
143
146
 
144
- log->onEvent( "Connecting to " + address + " on port " + IntConvertor::convert((unsigned short)port) );
145
- int result = m_connector.connect( address, port, m_noDelay, m_sendBufSize, m_rcvBufSize );
147
+ log->onEvent( "Connecting to " + address + " on port " + IntConvertor::convert((unsigned short)port) + " (Source " + sourceAddress + ":" + IntConvertor::convert((unsigned short)sourcePort) + ")");
148
+ int result = m_connector.connect( address, port, m_noDelay, m_sendBufSize, m_rcvBufSize, sourceAddress, sourcePort );
146
149
  setPending( s );
147
150
 
148
151
  m_pendingConnections[ result ]
@@ -229,7 +232,8 @@ void SocketInitiator::onTimeout( SocketConnector& )
229
232
  }
230
233
 
231
234
  void SocketInitiator::getHost( const SessionID& s, const Dictionary& d,
232
- std::string& address, short& port )
235
+ std::string& address, short& port,
236
+ std::string& sourceAddress, short& sourcePort)
233
237
  {
234
238
  int num = 0;
235
239
  SessionToHostNum::iterator i = m_sessionToHostNum.find( s );
@@ -243,16 +247,36 @@ void SocketInitiator::getHost( const SessionID& s, const Dictionary& d,
243
247
  portStream << SOCKET_CONNECT_PORT << num;
244
248
  std::string portString = portStream.str();
245
249
 
250
+ sourcePort = 0;
251
+ sourceAddress.empty();
252
+
246
253
  if( d.has(hostString) && d.has(portString) )
247
254
  {
248
255
  address = d.getString( hostString );
249
256
  port = ( short ) d.getInt( portString );
257
+
258
+ std::stringstream sourceHostStream;
259
+ sourceHostStream << SOCKET_CONNECT_SOURCE_HOST << num;
260
+ hostString = sourceHostStream.str();
261
+ if( d.has(hostString) )
262
+ sourceAddress = d.getString( hostString );
263
+
264
+ std::stringstream sourcePortStream;
265
+ sourcePortStream << SOCKET_CONNECT_SOURCE_PORT << num;
266
+ portString = sourcePortStream.str();
267
+ if( d.has(portString) )
268
+ sourcePort = ( short ) d.getInt( portString );
250
269
  }
251
270
  else
252
271
  {
253
272
  num = 0;
254
273
  address = d.getString( SOCKET_CONNECT_HOST );
255
274
  port = ( short ) d.getInt( SOCKET_CONNECT_PORT );
275
+
276
+ if( d.has(SOCKET_CONNECT_SOURCE_HOST) )
277
+ sourceAddress = d.getString( SOCKET_CONNECT_SOURCE_HOST );
278
+ if( d.has(SOCKET_CONNECT_SOURCE_PORT) )
279
+ sourcePort = ( short ) d.getInt( SOCKET_CONNECT_SOURCE_PORT );
256
280
  }
257
281
 
258
282
  m_sessionToHostNum[ s ] = ++num;
@@ -62,7 +62,7 @@ private:
62
62
  void onError( SocketConnector& );
63
63
  void onTimeout( SocketConnector& );
64
64
 
65
- void getHost( const SessionID&, const Dictionary&, std::string&, short& );
65
+ void getHost( const SessionID&, const Dictionary&, std::string&, short&, std::string&, short& );
66
66
 
67
67
  SessionSettings m_settings;
68
68
  SessionToHostNum m_sessionToHostNum;
@@ -133,17 +133,17 @@ inline timeval* SocketMonitor::getTimeval( bool poll, double timeout )
133
133
  m_timeval.tv_sec = timeout;
134
134
  return &m_timeval;
135
135
  #else
136
- double elapsed = ( double ) ( clock() - m_ticks ) / ( double ) CLOCKS_PER_SEC;
136
+ double elapsed = ( double ) ( clock() - m_ticks ) / ( double ) CLOCKS_PER_SEC;
137
137
  if ( elapsed >= timeout || elapsed == 0.0 )
138
138
  {
139
139
  m_ticks = clock();
140
140
  m_timeval.tv_sec = 0;
141
- m_timeval.tv_usec = (timeout * 1000000);
141
+ m_timeval.tv_usec = (long)(timeout * 1000000);
142
142
  }
143
143
  else
144
144
  {
145
145
  m_timeval.tv_sec = 0;
146
- m_timeval.tv_usec = ( ( timeout - elapsed ) * 1000000 );
146
+ m_timeval.tv_usec = (long)( ( timeout - elapsed ) * 1000000 );
147
147
  }
148
148
  return &m_timeval;
149
149
  #endif
@@ -233,7 +233,7 @@ void SocketMonitor::processReadSet( Strategy& strategy, fd_set& readSet )
233
233
  if( s == m_interrupt )
234
234
  {
235
235
  int socket = 0;
236
- recv( s, (char*)&socket, sizeof(socket), 0 );
236
+ socket_recv( s, (char*)&socket, sizeof(socket) );
237
237
  addWrite( socket );
238
238
  }
239
239
  else
@@ -252,7 +252,7 @@ void SocketMonitor::processReadSet( Strategy& strategy, fd_set& readSet )
252
252
  if( s == m_interrupt )
253
253
  {
254
254
  int socket = 0;
255
- recv( s, (char*)&socket, sizeof(socket), 0 );
255
+ socket_recv( s, (char*)&socket, sizeof(socket) );
256
256
  addWrite( socket );
257
257
  }
258
258
  else
@@ -0,0 +1,455 @@
1
+ /* ====================================================================
2
+ * Copyright (c) 1998-2006 Ralf S. Engelschall. All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions
6
+ * are met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following
13
+ * disclaimer in the documentation and/or other materials
14
+ * provided with the distribution.
15
+ *
16
+ * 3. All advertising materials mentioning features or use of this
17
+ * software must display the following acknowledgment:
18
+ * "This product includes software developed by
19
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
20
+ * mod_ssl project (http://www.modssl.org/)."
21
+ *
22
+ * 4. The names "mod_ssl" must not be used to endorse or promote
23
+ * products derived from this software without prior written
24
+ * permission. For written permission, please contact
25
+ * rse@engelschall.com.
26
+ *
27
+ * 5. Products derived from this software may not be called "mod_ssl"
28
+ * nor may "mod_ssl" appear in their names without prior
29
+ * written permission of Ralf S. Engelschall.
30
+ *
31
+ * 6. Redistributions of any form whatsoever must retain the following
32
+ * acknowledgment:
33
+ * "This product includes software developed by
34
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
35
+ * mod_ssl project (http://www.modssl.org/)."
36
+ *
37
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
38
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
41
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
49
+ * ====================================================================
50
+ */
51
+
52
+ /* ====================================================================
53
+ * Copyright (c) 1995-1999 Ben Laurie. All rights reserved.
54
+ *
55
+ * Redistribution and use in source and binary forms, with or without
56
+ * modification, are permitted provided that the following conditions
57
+ * are met:
58
+ *
59
+ * 1. Redistributions of source code must retain the above copyright
60
+ * notice, this list of conditions and the following disclaimer.
61
+ *
62
+ * 2. Redistributions in binary form must reproduce the above copyright
63
+ * notice, this list of conditions and the following disclaimer in
64
+ * the documentation and/or other materials provided with the
65
+ * distribution.
66
+ *
67
+ * 3. All advertising materials mentioning features or use of this
68
+ * software must display the following acknowledgment:
69
+ * "This product includes software developed by Ben Laurie
70
+ * for use in the Apache-SSL HTTP server project."
71
+ *
72
+ * 4. The name "Apache-SSL Server" must not be used to
73
+ * endorse or promote products derived from this software without
74
+ * prior written permission.
75
+ *
76
+ * 5. Redistributions of any form whatsoever must retain the following
77
+ * acknowledgment:
78
+ * "This product includes software developed by Ben Laurie
79
+ * for use in the Apache-SSL HTTP server project."
80
+ *
81
+ * THIS SOFTWARE IS PROVIDED BY BEN LAURIE ``AS IS'' AND ANY
82
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
84
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BEN LAURIE OR
85
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
86
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
87
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
89
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
90
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
91
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
92
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
93
+ * ====================================================================
94
+ */
95
+
96
+ /****************************************************************************
97
+ ** Copyright (c) 2001-2014
98
+ **
99
+ ** This file is part of the QuickFIX FIX Engine
100
+ **
101
+ ** This file may be distributed under the terms of the quickfixengine.org
102
+ ** license as defined by quickfixengine.org and appearing in the file
103
+ ** LICENSE included in the packaging of this file.
104
+ **
105
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
106
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
107
+ **
108
+ ** See http://www.quickfixengine.org/LICENSE for licensing information.
109
+ **
110
+ ** Contact ask@quickfixengine.org if any conditions of this licensing are
111
+ ** not clear to you.
112
+ **
113
+ ****************************************************************************/
114
+
115
+ #ifdef _MSC_VER
116
+ #include "stdafx.h"
117
+ #else
118
+ #include "config.h"
119
+ #endif
120
+
121
+ #if (HAVE_SSL > 0)
122
+
123
+ #include "ThreadedSSLSocketAcceptor.h"
124
+ #include "Settings.h"
125
+ #include "Utility.h"
126
+
127
+ namespace FIX
128
+ {
129
+
130
+ FIX::ThreadedSSLSocketAcceptor *acceptObjT = 0;
131
+
132
+ int ThreadedSSLSocketAcceptor::passPhraseHandleCB(char *buf, int bufsize, int verify, void *job)
133
+ {
134
+ return acceptObjT->passwordHandleCallback(buf, bufsize, verify, job);
135
+ }
136
+
137
+ ThreadedSSLSocketAcceptor::ThreadedSSLSocketAcceptor(
138
+ Application &application, MessageStoreFactory &factory,
139
+ const SessionSettings &settings) throw(ConfigError)
140
+ : Acceptor(application, factory, settings), m_sslInit(false),
141
+ m_verify(SSL_CLIENT_VERIFY_NOTSET), m_ctx(0), m_revocationStore(0)
142
+ {
143
+ socket_init();
144
+ acceptObjT = this;
145
+ }
146
+
147
+ ThreadedSSLSocketAcceptor::ThreadedSSLSocketAcceptor(
148
+ Application &application, MessageStoreFactory &factory,
149
+ const SessionSettings &settings, LogFactory &logFactory) throw(ConfigError)
150
+ : Acceptor(application, factory, settings, logFactory), m_sslInit(false),
151
+ m_verify(SSL_CLIENT_VERIFY_NOTSET), m_ctx(0), m_revocationStore(0)
152
+ {
153
+ socket_init();
154
+ acceptObjT = this;
155
+ }
156
+
157
+ ThreadedSSLSocketAcceptor::~ThreadedSSLSocketAcceptor()
158
+ {
159
+ if (m_sslInit)
160
+ {
161
+ SSL_CTX_free(m_ctx);
162
+ m_ctx = 0;
163
+ ssl_term();
164
+ }
165
+
166
+ socket_term();
167
+ }
168
+
169
+ void ThreadedSSLSocketAcceptor::onConfigure(const SessionSettings &s) throw(
170
+ ConfigError)
171
+ {
172
+ std::set< SessionID > sessions = s.getSessions();
173
+ std::set< SessionID >::iterator i;
174
+ for (i = sessions.begin(); i != sessions.end(); ++i)
175
+ {
176
+ const Dictionary &settings = s.get(*i);
177
+ settings.getInt(SOCKET_ACCEPT_PORT);
178
+ if (settings.has(SOCKET_REUSE_ADDRESS))
179
+ settings.getBool(SOCKET_REUSE_ADDRESS);
180
+ if (settings.has(SOCKET_NODELAY))
181
+ settings.getBool(SOCKET_NODELAY);
182
+ }
183
+ }
184
+
185
+ void ThreadedSSLSocketAcceptor::onInitialize(const SessionSettings &s) throw(
186
+ RuntimeError)
187
+ {
188
+ if (!m_sslInit)
189
+ {
190
+
191
+ ssl_init();
192
+
193
+ std::string errStr;
194
+
195
+ /* set up the application context */
196
+ if ((m_ctx = createSSLContext(true, m_settings, errStr)) == 0)
197
+ {
198
+ ssl_term();
199
+ throw RuntimeError(errStr);
200
+ }
201
+
202
+ if (!loadSSLCert(m_ctx, true, m_settings, getLog(), ThreadedSSLSocketAcceptor::passPhraseHandleCB, errStr))
203
+ {
204
+ ssl_term();
205
+ throw RuntimeError(errStr);
206
+ }
207
+
208
+ if (!loadCAInfo(m_ctx, true, m_settings, getLog(), errStr, m_verify))
209
+ {
210
+ ssl_term();
211
+ throw RuntimeError(errStr);
212
+ }
213
+
214
+ m_revocationStore = loadCRLInfo(m_ctx, m_settings, getLog(), errStr);
215
+ if (!m_revocationStore && !errStr.empty())
216
+ {
217
+ ssl_term();
218
+ throw RuntimeError(errStr);
219
+ }
220
+
221
+ m_sslInit = true;
222
+ }
223
+
224
+ short port = 0;
225
+ std::set< int > ports;
226
+
227
+ std::set< SessionID > sessions = s.getSessions();
228
+ std::set< SessionID >::iterator i = sessions.begin();
229
+ for (; i != sessions.end(); ++i)
230
+ {
231
+ const Dictionary &settings = s.get(*i);
232
+ port = (short)settings.getInt(SOCKET_ACCEPT_PORT);
233
+
234
+ m_portToSessions[port].insert(*i);
235
+
236
+ if (ports.find(port) != ports.end())
237
+ continue;
238
+ ports.insert(port);
239
+
240
+ const bool reuseAddress = settings.has(SOCKET_REUSE_ADDRESS)
241
+ ? settings.getBool(SOCKET_REUSE_ADDRESS)
242
+ : true;
243
+
244
+ const bool noDelay =
245
+ settings.has(SOCKET_NODELAY) ? settings.getBool(SOCKET_NODELAY) : false;
246
+
247
+ const int sendBufSize = settings.has(SOCKET_SEND_BUFFER_SIZE)
248
+ ? settings.getInt(SOCKET_SEND_BUFFER_SIZE)
249
+ : 0;
250
+
251
+ const int rcvBufSize = settings.has(SOCKET_RECEIVE_BUFFER_SIZE)
252
+ ? settings.getInt(SOCKET_RECEIVE_BUFFER_SIZE)
253
+ : 0;
254
+
255
+ int socket = socket_createAcceptor(port, reuseAddress);
256
+ if (socket < 0)
257
+ {
258
+ SocketException e;
259
+ socket_close(socket);
260
+ throw RuntimeError("Unable to create, bind, or listen to port " +
261
+ IntConvertor::convert((unsigned short)port) + " (" +
262
+ e.what() + ")");
263
+ }
264
+ if (noDelay)
265
+ socket_setsockopt(socket, TCP_NODELAY);
266
+ if (sendBufSize)
267
+ socket_setsockopt(socket, SO_SNDBUF, sendBufSize);
268
+ if (rcvBufSize)
269
+ socket_setsockopt(socket, SO_RCVBUF, rcvBufSize);
270
+
271
+ m_socketToPort[socket] = port;
272
+ m_sockets.insert(socket);
273
+ }
274
+ }
275
+
276
+ void ThreadedSSLSocketAcceptor::onStart()
277
+ {
278
+ Sockets::iterator i;
279
+ for (i = m_sockets.begin(); i != m_sockets.end(); ++i)
280
+ {
281
+ Locker l(m_mutex);
282
+ int port = m_socketToPort[*i];
283
+ AcceptorThreadInfo *info = new AcceptorThreadInfo(this, *i, port);
284
+ thread_id thread;
285
+ thread_spawn(&socketAcceptorThread, info, thread);
286
+ addThread(SocketKey(*i, 0), thread);
287
+ }
288
+ }
289
+
290
+ bool ThreadedSSLSocketAcceptor::onPoll(double timeout) { return false; }
291
+
292
+ void ThreadedSSLSocketAcceptor::onStop()
293
+ {
294
+ SocketToThread threads;
295
+ SocketToThread::iterator i;
296
+
297
+ {
298
+ Locker l(m_mutex);
299
+
300
+ time_t start = 0;
301
+ time_t now = 0;
302
+
303
+ ::time(&start);
304
+ while (isLoggedOn())
305
+ {
306
+ if (::time(&now) - 5 >= start)
307
+ break;
308
+ }
309
+
310
+ threads = m_threads;
311
+ m_threads.clear();
312
+ }
313
+
314
+ for (i = threads.begin(); i != threads.end(); ++i)
315
+ ssl_socket_close(i->first.first, i->first.second);
316
+ for (i = threads.begin(); i != threads.end(); ++i)
317
+ {
318
+ thread_join(i->second);
319
+ if (i->first.second != 0)
320
+ SSL_free(i->first.second);
321
+ }
322
+ }
323
+
324
+ void ThreadedSSLSocketAcceptor::addThread(SocketKey s, thread_id t)
325
+ {
326
+ Locker l(m_mutex);
327
+
328
+ m_threads[s] = t;
329
+ }
330
+
331
+ void ThreadedSSLSocketAcceptor::removeThread(SocketKey s)
332
+ {
333
+ Locker l(m_mutex);
334
+ SocketToThread::iterator i = m_threads.find(s);
335
+ if (i != m_threads.end())
336
+ {
337
+ thread_detach(i->second);
338
+ if (i->first.second != 0)
339
+ SSL_free(i->first.second);
340
+ m_threads.erase(i);
341
+ }
342
+ }
343
+
344
+ THREAD_PROC ThreadedSSLSocketAcceptor::socketAcceptorThread(void *p)
345
+ {
346
+ AcceptorThreadInfo *info = reinterpret_cast< AcceptorThreadInfo * >(p);
347
+
348
+ ThreadedSSLSocketAcceptor *pAcceptor = info->m_pAcceptor;
349
+ int s = info->m_socket;
350
+ int port = info->m_port;
351
+ delete info;
352
+
353
+ int noDelay = 0;
354
+ int sendBufSize = 0;
355
+ int rcvBufSize = 0;
356
+ socket_getsockopt(s, TCP_NODELAY, noDelay);
357
+ socket_getsockopt(s, SO_SNDBUF, sendBufSize);
358
+ socket_getsockopt(s, SO_RCVBUF, rcvBufSize);
359
+
360
+ int socket = 0;
361
+ while ((!pAcceptor->isStopped() && (socket = socket_accept(s)) >= 0))
362
+ {
363
+ if (noDelay)
364
+ socket_setsockopt(socket, TCP_NODELAY);
365
+ if (sendBufSize)
366
+ socket_setsockopt(socket, SO_SNDBUF, sendBufSize);
367
+ if (rcvBufSize)
368
+ socket_setsockopt(socket, SO_RCVBUF, rcvBufSize);
369
+
370
+ Sessions sessions = pAcceptor->m_portToSessions[port];
371
+
372
+ SSL *ssl = SSL_new(pAcceptor->sslContext());
373
+ ThreadedSSLSocketConnection *pConnection = new ThreadedSSLSocketConnection(
374
+ socket, ssl, sessions, pAcceptor->getLog());
375
+ SSL_clear(ssl);
376
+ BIO *sBio = BIO_new_socket(socket, BIO_CLOSE);
377
+ SSL_set_bio(ssl, sBio, sBio);
378
+ // TODO - check this
379
+ SSL_set_app_data(ssl, pAcceptor->revocationStore());
380
+ SSL_set_verify_result(ssl, X509_V_OK);
381
+
382
+ ConnectionThreadInfo *info =
383
+ new ConnectionThreadInfo(pAcceptor, pConnection);
384
+
385
+ {
386
+ Locker l(pAcceptor->m_mutex);
387
+
388
+ std::stringstream stream;
389
+ stream << "Accepted connection from " << socket_peername(socket)
390
+ << " on port " << port;
391
+
392
+ if (pAcceptor->getLog())
393
+ pAcceptor->getLog()->onEvent(stream.str());
394
+
395
+ thread_id thread;
396
+ if (!thread_spawn(&socketConnectionThread, info, thread))
397
+ {
398
+ delete info;
399
+ delete pConnection;
400
+ SSL_free(ssl);
401
+ }
402
+ else
403
+ pAcceptor->addThread(SocketKey(socket, ssl), thread);
404
+ }
405
+ }
406
+
407
+ if (!pAcceptor->isStopped())
408
+ pAcceptor->removeThread(SocketKey(s, 0));
409
+
410
+ return 0;
411
+ }
412
+
413
+ THREAD_PROC ThreadedSSLSocketAcceptor::socketConnectionThread(void *p)
414
+ {
415
+ ConnectionThreadInfo *info = reinterpret_cast< ConnectionThreadInfo * >(p);
416
+
417
+ ThreadedSSLSocketAcceptor *pAcceptor = info->m_pAcceptor;
418
+ ThreadedSSLSocketConnection *pConnection = info->m_pConnection;
419
+ delete info;
420
+
421
+ int socket = pConnection->getSocket();
422
+
423
+ if (acceptSSLConnection(pConnection->getSocket(), pConnection->sslObject(), pAcceptor->getLog(), pAcceptor->m_verify) != 0)
424
+ {
425
+ if (pAcceptor->getLog())
426
+ pAcceptor->getLog()->onEvent("Failed to accept new SSL connection");
427
+ SSL *ssl = pConnection->sslObject();
428
+ delete pConnection;
429
+ if (!pAcceptor->isStopped())
430
+ pAcceptor->removeThread(SocketKey(socket, ssl));
431
+ return 0;
432
+ }
433
+
434
+ while (pConnection->read())
435
+ {
436
+ }
437
+ SSL *ssl = pConnection->sslObject();
438
+ delete pConnection;
439
+ if (!pAcceptor->isStopped())
440
+ pAcceptor->removeThread(SocketKey(socket, ssl));
441
+ return 0;
442
+ }
443
+
444
+ int ThreadedSSLSocketAcceptor::passwordHandleCallback(char *buf, size_t bufsize,
445
+ int verify, void *job)
446
+ {
447
+ if (m_password.length() > bufsize)
448
+ return -1;
449
+
450
+ std::strcpy(buf, m_password.c_str());
451
+ return m_password.length();
452
+ }
453
+ }
454
+
455
+ #endif