quickfix_ruby_ud 2.0.7-x86_64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. checksums.yaml +7 -0
  2. data/ext/quickfix/Acceptor.cpp +257 -0
  3. data/ext/quickfix/Acceptor.h +127 -0
  4. data/ext/quickfix/Allocator.h +9 -0
  5. data/ext/quickfix/Application.h +137 -0
  6. data/ext/quickfix/DOMDocument.h +70 -0
  7. data/ext/quickfix/DataDictionary.cpp +679 -0
  8. data/ext/quickfix/DataDictionary.h +607 -0
  9. data/ext/quickfix/DataDictionaryProvider.cpp +66 -0
  10. data/ext/quickfix/DataDictionaryProvider.h +67 -0
  11. data/ext/quickfix/DatabaseConnectionID.h +98 -0
  12. data/ext/quickfix/DatabaseConnectionPool.h +84 -0
  13. data/ext/quickfix/Dictionary.cpp +157 -0
  14. data/ext/quickfix/Dictionary.h +89 -0
  15. data/ext/quickfix/Event.h +89 -0
  16. data/ext/quickfix/Except.h +39 -0
  17. data/ext/quickfix/Exceptions.h +257 -0
  18. data/ext/quickfix/Field.h +654 -0
  19. data/ext/quickfix/FieldConvertors.cpp +86 -0
  20. data/ext/quickfix/FieldConvertors.h +800 -0
  21. data/ext/quickfix/FieldMap.cpp +254 -0
  22. data/ext/quickfix/FieldMap.h +327 -0
  23. data/ext/quickfix/FieldNumbers.h +44 -0
  24. data/ext/quickfix/FieldTypes.cpp +62 -0
  25. data/ext/quickfix/FieldTypes.h +817 -0
  26. data/ext/quickfix/Fields.h +30 -0
  27. data/ext/quickfix/FileLog.cpp +176 -0
  28. data/ext/quickfix/FileLog.h +110 -0
  29. data/ext/quickfix/FileStore.cpp +369 -0
  30. data/ext/quickfix/FileStore.h +131 -0
  31. data/ext/quickfix/FixCommonFields.h +13 -0
  32. data/ext/quickfix/FixFieldNumbers.h +6132 -0
  33. data/ext/quickfix/FixFields.h +6133 -0
  34. data/ext/quickfix/FixValues.h +5790 -0
  35. data/ext/quickfix/Group.cpp +44 -0
  36. data/ext/quickfix/Group.h +78 -0
  37. data/ext/quickfix/HostDetailsProvider.cpp +79 -0
  38. data/ext/quickfix/HostDetailsProvider.h +44 -0
  39. data/ext/quickfix/HtmlBuilder.h +178 -0
  40. data/ext/quickfix/HttpConnection.cpp +914 -0
  41. data/ext/quickfix/HttpConnection.h +74 -0
  42. data/ext/quickfix/HttpMessage.cpp +229 -0
  43. data/ext/quickfix/HttpMessage.h +112 -0
  44. data/ext/quickfix/HttpParser.cpp +49 -0
  45. data/ext/quickfix/HttpParser.h +49 -0
  46. data/ext/quickfix/HttpServer.cpp +152 -0
  47. data/ext/quickfix/HttpServer.h +76 -0
  48. data/ext/quickfix/Initiator.cpp +310 -0
  49. data/ext/quickfix/Initiator.h +151 -0
  50. data/ext/quickfix/Log.cpp +71 -0
  51. data/ext/quickfix/Log.h +254 -0
  52. data/ext/quickfix/Message.cpp +617 -0
  53. data/ext/quickfix/Message.h +419 -0
  54. data/ext/quickfix/MessageCracker.h +171 -0
  55. data/ext/quickfix/MessageSorters.cpp +101 -0
  56. data/ext/quickfix/MessageSorters.h +185 -0
  57. data/ext/quickfix/MessageStore.cpp +182 -0
  58. data/ext/quickfix/MessageStore.h +164 -0
  59. data/ext/quickfix/Mutex.h +120 -0
  60. data/ext/quickfix/MySQLConnection.h +187 -0
  61. data/ext/quickfix/MySQLLog.cpp +262 -0
  62. data/ext/quickfix/MySQLLog.h +158 -0
  63. data/ext/quickfix/MySQLStore.cpp +323 -0
  64. data/ext/quickfix/MySQLStore.h +161 -0
  65. data/ext/quickfix/MySQLStubs.h +203 -0
  66. data/ext/quickfix/NullStore.cpp +40 -0
  67. data/ext/quickfix/NullStore.h +89 -0
  68. data/ext/quickfix/OdbcConnection.h +241 -0
  69. data/ext/quickfix/OdbcLog.cpp +230 -0
  70. data/ext/quickfix/OdbcLog.h +109 -0
  71. data/ext/quickfix/OdbcStore.cpp +313 -0
  72. data/ext/quickfix/OdbcStore.h +124 -0
  73. data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
  74. data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
  75. data/ext/quickfix/Parser.cpp +111 -0
  76. data/ext/quickfix/Parser.h +50 -0
  77. data/ext/quickfix/PostgreSQLConnection.h +163 -0
  78. data/ext/quickfix/PostgreSQLLog.cpp +263 -0
  79. data/ext/quickfix/PostgreSQLLog.h +157 -0
  80. data/ext/quickfix/PostgreSQLStore.cpp +327 -0
  81. data/ext/quickfix/PostgreSQLStore.h +160 -0
  82. data/ext/quickfix/PostgreSQLStubs.h +203 -0
  83. data/ext/quickfix/Queue.h +66 -0
  84. data/ext/quickfix/QuickfixRuby.cpp +131900 -0
  85. data/ext/quickfix/QuickfixRuby.h +56 -0
  86. data/ext/quickfix/Responder.h +41 -0
  87. data/ext/quickfix/SSLSocketAcceptor.cpp +409 -0
  88. data/ext/quickfix/SSLSocketAcceptor.h +186 -0
  89. data/ext/quickfix/SSLSocketConnection.cpp +434 -0
  90. data/ext/quickfix/SSLSocketConnection.h +221 -0
  91. data/ext/quickfix/SSLSocketInitiator.cpp +558 -0
  92. data/ext/quickfix/SSLSocketInitiator.h +203 -0
  93. data/ext/quickfix/SSLStubs.h +129 -0
  94. data/ext/quickfix/Session.cpp +1437 -0
  95. data/ext/quickfix/Session.h +343 -0
  96. data/ext/quickfix/SessionFactory.cpp +314 -0
  97. data/ext/quickfix/SessionFactory.h +84 -0
  98. data/ext/quickfix/SessionID.h +136 -0
  99. data/ext/quickfix/SessionSettings.cpp +165 -0
  100. data/ext/quickfix/SessionSettings.h +283 -0
  101. data/ext/quickfix/SessionState.h +260 -0
  102. data/ext/quickfix/Settings.cpp +160 -0
  103. data/ext/quickfix/Settings.h +56 -0
  104. data/ext/quickfix/SharedArray.h +274 -0
  105. data/ext/quickfix/SocketAcceptor.cpp +216 -0
  106. data/ext/quickfix/SocketAcceptor.h +77 -0
  107. data/ext/quickfix/SocketConnection.cpp +256 -0
  108. data/ext/quickfix/SocketConnection.h +102 -0
  109. data/ext/quickfix/SocketConnector.cpp +112 -0
  110. data/ext/quickfix/SocketConnector.h +76 -0
  111. data/ext/quickfix/SocketInitiator.cpp +241 -0
  112. data/ext/quickfix/SocketInitiator.h +76 -0
  113. data/ext/quickfix/SocketMonitor.h +26 -0
  114. data/ext/quickfix/SocketMonitor_UNIX.cpp +238 -0
  115. data/ext/quickfix/SocketMonitor_UNIX.h +101 -0
  116. data/ext/quickfix/SocketMonitor_WIN32.cpp +248 -0
  117. data/ext/quickfix/SocketMonitor_WIN32.h +99 -0
  118. data/ext/quickfix/SocketServer.cpp +163 -0
  119. data/ext/quickfix/SocketServer.h +100 -0
  120. data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +436 -0
  121. data/ext/quickfix/ThreadedSSLSocketAcceptor.h +209 -0
  122. data/ext/quickfix/ThreadedSSLSocketConnection.cpp +364 -0
  123. data/ext/quickfix/ThreadedSSLSocketConnection.h +191 -0
  124. data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +434 -0
  125. data/ext/quickfix/ThreadedSSLSocketInitiator.h +193 -0
  126. data/ext/quickfix/ThreadedSocketAcceptor.cpp +242 -0
  127. data/ext/quickfix/ThreadedSocketAcceptor.h +95 -0
  128. data/ext/quickfix/ThreadedSocketConnection.cpp +227 -0
  129. data/ext/quickfix/ThreadedSocketConnection.h +89 -0
  130. data/ext/quickfix/ThreadedSocketInitiator.cpp +238 -0
  131. data/ext/quickfix/ThreadedSocketInitiator.h +78 -0
  132. data/ext/quickfix/TimeRange.cpp +227 -0
  133. data/ext/quickfix/TimeRange.h +215 -0
  134. data/ext/quickfix/Utility.cpp +639 -0
  135. data/ext/quickfix/Utility.h +255 -0
  136. data/ext/quickfix/UtilitySSL.cpp +1612 -0
  137. data/ext/quickfix/UtilitySSL.h +274 -0
  138. data/ext/quickfix/Values.h +63 -0
  139. data/ext/quickfix/config-all.h +10 -0
  140. data/ext/quickfix/config.h +10 -0
  141. data/ext/quickfix/config_unix.h +178 -0
  142. data/ext/quickfix/config_windows.h +0 -0
  143. data/ext/quickfix/dirent_windows.h +838 -0
  144. data/ext/quickfix/double-conversion/bignum-dtoa.cc +641 -0
  145. data/ext/quickfix/double-conversion/bignum-dtoa.h +84 -0
  146. data/ext/quickfix/double-conversion/bignum.cc +766 -0
  147. data/ext/quickfix/double-conversion/bignum.h +144 -0
  148. data/ext/quickfix/double-conversion/cached-powers.cc +176 -0
  149. data/ext/quickfix/double-conversion/cached-powers.h +64 -0
  150. data/ext/quickfix/double-conversion/diy-fp.cc +57 -0
  151. data/ext/quickfix/double-conversion/diy-fp.h +118 -0
  152. data/ext/quickfix/double-conversion/double-conversion.cc +994 -0
  153. data/ext/quickfix/double-conversion/double-conversion.h +543 -0
  154. data/ext/quickfix/double-conversion/fast-dtoa.cc +665 -0
  155. data/ext/quickfix/double-conversion/fast-dtoa.h +88 -0
  156. data/ext/quickfix/double-conversion/fixed-dtoa.cc +404 -0
  157. data/ext/quickfix/double-conversion/fixed-dtoa.h +56 -0
  158. data/ext/quickfix/double-conversion/ieee.h +402 -0
  159. data/ext/quickfix/double-conversion/strtod.cc +557 -0
  160. data/ext/quickfix/double-conversion/strtod.h +45 -0
  161. data/ext/quickfix/double-conversion/utils.h +374 -0
  162. data/ext/quickfix/extconf.rb +76 -0
  163. data/ext/quickfix/index.h +37 -0
  164. data/ext/quickfix/pugiconfig.hpp +77 -0
  165. data/ext/quickfix/pugixml.cpp +13237 -0
  166. data/ext/quickfix/pugixml.hpp +1516 -0
  167. data/ext/quickfix/scope_guard.hpp +215 -0
  168. data/ext/quickfix/stdint_msvc.h +254 -0
  169. data/ext/quickfix/strptime.h +7 -0
  170. data/lib/2.4/quickfix.so +0 -0
  171. data/lib/2.5/quickfix.so +0 -0
  172. data/lib/2.6/quickfix.so +0 -0
  173. data/lib/2.7/quickfix.so +0 -0
  174. data/lib/3.0/quickfix.so +0 -0
  175. data/lib/3.1/quickfix.so +0 -0
  176. data/lib/3.2/quickfix.so +0 -0
  177. data/lib/3.3/quickfix.so +0 -0
  178. data/lib/3.4/quickfix.so +0 -0
  179. data/lib/quickfix40.rb +274 -0
  180. data/lib/quickfix41.rb +351 -0
  181. data/lib/quickfix42.rb +1184 -0
  182. data/lib/quickfix43.rb +3504 -0
  183. data/lib/quickfix44.rb +14040 -0
  184. data/lib/quickfix50.rb +20051 -0
  185. data/lib/quickfix50sp1.rb +23596 -0
  186. data/lib/quickfix50sp2.rb +412444 -0
  187. data/lib/quickfix_fields.rb +79393 -0
  188. data/lib/quickfix_ruby.rb +82 -0
  189. data/lib/quickfixt11.rb +65 -0
  190. data/spec/FIX40.xml +862 -0
  191. data/spec/FIX41.xml +1282 -0
  192. data/spec/FIX42.xml +2743 -0
  193. data/spec/FIX43.xml +4230 -0
  194. data/spec/FIX44.xml +6600 -0
  195. data/spec/FIX50.xml +8142 -0
  196. data/spec/FIX50SP1.xml +9506 -0
  197. data/spec/FIX50SP2.xml +26069 -0
  198. data/spec/FIXT11.xml +252 -0
  199. data/test/DataDictionaryTestCase.rb +268 -0
  200. data/test/DictionaryTestCase.rb +112 -0
  201. data/test/FieldBaseTestCase.rb +24 -0
  202. data/test/MessageStoreTestCase.rb +19 -0
  203. data/test/MessageTestCase.rb +368 -0
  204. data/test/SessionSettingsTestCase.rb +41 -0
  205. metadata +247 -0
@@ -0,0 +1,242 @@
1
+ /****************************************************************************
2
+ ** Copyright (c) 2001-2014
3
+ **
4
+ ** This file is part of the QuickFIX FIX Engine
5
+ **
6
+ ** This file may be distributed under the terms of the quickfixengine.org
7
+ ** license as defined by quickfixengine.org and appearing in the file
8
+ ** LICENSE included in the packaging of this file.
9
+ **
10
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12
+ **
13
+ ** See http://www.quickfixengine.org/LICENSE for licensing information.
14
+ **
15
+ ** Contact ask@quickfixengine.org if any conditions of this licensing are
16
+ ** not clear to you.
17
+ **
18
+ ****************************************************************************/
19
+
20
+ #ifdef _MSC_VER
21
+ #include "stdafx.h"
22
+ #else
23
+ #include "config.h"
24
+ #endif
25
+
26
+ #include "Settings.h"
27
+ #include "ThreadedSocketAcceptor.h"
28
+ #include "Utility.h"
29
+
30
+ namespace FIX {
31
+ ThreadedSocketAcceptor::ThreadedSocketAcceptor(
32
+ Application &application,
33
+ MessageStoreFactory &factory,
34
+ const SessionSettings &settings) EXCEPT(ConfigError)
35
+ : Acceptor(application, factory, settings) {
36
+ socket_init();
37
+ }
38
+
39
+ ThreadedSocketAcceptor::ThreadedSocketAcceptor(
40
+ Application &application,
41
+ MessageStoreFactory &factory,
42
+ const SessionSettings &settings,
43
+ LogFactory &logFactory) EXCEPT(ConfigError)
44
+ : Acceptor(application, factory, settings, logFactory) {
45
+ socket_init();
46
+ }
47
+
48
+ ThreadedSocketAcceptor::~ThreadedSocketAcceptor() { socket_term(); }
49
+
50
+ void ThreadedSocketAcceptor::onConfigure(const SessionSettings &sessionSettings) EXCEPT(ConfigError) {
51
+ for (const SessionID &sessionID : sessionSettings.getSessions()) {
52
+ const Dictionary &settings = sessionSettings.get(sessionID);
53
+ settings.getInt(SOCKET_ACCEPT_PORT);
54
+ if (settings.has(SOCKET_REUSE_ADDRESS)) {
55
+ settings.getBool(SOCKET_REUSE_ADDRESS);
56
+ }
57
+ if (settings.has(SOCKET_NODELAY)) {
58
+ settings.getBool(SOCKET_NODELAY);
59
+ }
60
+ }
61
+ }
62
+
63
+ void ThreadedSocketAcceptor::onInitialize(const SessionSettings &sessionSettings) EXCEPT(RuntimeError) {
64
+ short port = 0;
65
+ std::set<int> ports;
66
+
67
+ for (const SessionID &sessionID : sessionSettings.getSessions()) {
68
+ const Dictionary &settings = sessionSettings.get(sessionID);
69
+ port = (short)settings.getInt(SOCKET_ACCEPT_PORT);
70
+
71
+ m_portToSessions[port].insert(sessionID);
72
+
73
+ if (ports.find(port) != ports.end()) {
74
+ continue;
75
+ }
76
+ ports.insert(port);
77
+
78
+ const bool reuseAddress = settings.has(SOCKET_REUSE_ADDRESS) ? settings.getBool(SOCKET_REUSE_ADDRESS) : true;
79
+
80
+ const bool noDelay = settings.has(SOCKET_NODELAY) ? settings.getBool(SOCKET_NODELAY) : false;
81
+
82
+ const int sendBufSize = settings.has(SOCKET_SEND_BUFFER_SIZE) ? settings.getInt(SOCKET_SEND_BUFFER_SIZE) : 0;
83
+
84
+ const int rcvBufSize = settings.has(SOCKET_RECEIVE_BUFFER_SIZE) ? settings.getInt(SOCKET_RECEIVE_BUFFER_SIZE) : 0;
85
+
86
+ socket_handle socket = socket_createAcceptor(port, reuseAddress);
87
+ if (socket == INVALID_SOCKET_HANDLE) {
88
+ SocketException e;
89
+ socket_close(socket);
90
+ throw RuntimeError(
91
+ "Unable to create, bind, or listen to port " + IntConvertor::convert((unsigned short)port) + " (" + e.what()
92
+ + ")");
93
+ }
94
+ if (noDelay) {
95
+ socket_setsockopt(socket, TCP_NODELAY);
96
+ }
97
+ if (sendBufSize) {
98
+ socket_setsockopt(socket, SO_SNDBUF, sendBufSize);
99
+ }
100
+ if (rcvBufSize) {
101
+ socket_setsockopt(socket, SO_RCVBUF, rcvBufSize);
102
+ }
103
+
104
+ m_socketToPort[socket] = port;
105
+ m_sockets.insert(socket);
106
+ }
107
+ }
108
+
109
+ void ThreadedSocketAcceptor::onStart() {
110
+ for (const Sockets::value_type &socket : m_sockets) {
111
+ Locker l(m_mutex);
112
+ int port = m_socketToPort[socket];
113
+ AcceptorThreadInfo *info = new AcceptorThreadInfo(this, socket, port);
114
+ thread_id thread;
115
+ thread_spawn(&socketAcceptorThread, info, thread);
116
+ addThread(socket, thread);
117
+ }
118
+ }
119
+
120
+ bool ThreadedSocketAcceptor::onPoll() { return false; }
121
+
122
+ void ThreadedSocketAcceptor::onStop() {
123
+ SocketToThread threads;
124
+ SocketToThread::iterator i;
125
+
126
+ {
127
+ Locker l(m_mutex);
128
+
129
+ time_t start = 0;
130
+ time_t now = 0;
131
+
132
+ ::time(&start);
133
+ while (isLoggedOn()) {
134
+ if (::time(&now) - 5 >= start) {
135
+ break;
136
+ }
137
+ }
138
+
139
+ threads = m_threads;
140
+ m_threads.clear();
141
+ }
142
+
143
+ for (i = threads.begin(); i != threads.end(); ++i) {
144
+ socket_close(i->first);
145
+ }
146
+ for (i = threads.begin(); i != threads.end(); ++i) {
147
+ thread_join(i->second);
148
+ }
149
+ }
150
+
151
+ void ThreadedSocketAcceptor::addThread(socket_handle s, thread_id t) {
152
+ Locker l(m_mutex);
153
+
154
+ m_threads[s] = t;
155
+ }
156
+
157
+ void ThreadedSocketAcceptor::removeThread(socket_handle s) {
158
+ Locker l(m_mutex);
159
+ SocketToThread::iterator i = m_threads.find(s);
160
+ if (i != m_threads.end()) {
161
+ thread_detach(i->second);
162
+ m_threads.erase(i);
163
+ }
164
+ }
165
+
166
+ THREAD_PROC ThreadedSocketAcceptor::socketAcceptorThread(void *p) {
167
+ AcceptorThreadInfo *info = reinterpret_cast<AcceptorThreadInfo *>(p);
168
+
169
+ ThreadedSocketAcceptor *pAcceptor = info->m_pAcceptor;
170
+ socket_handle s = info->m_socket;
171
+ int port = info->m_port;
172
+ delete info;
173
+
174
+ int noDelay = 0;
175
+ int sendBufSize = 0;
176
+ int rcvBufSize = 0;
177
+ socket_getsockopt(s, TCP_NODELAY, noDelay);
178
+ socket_getsockopt(s, SO_SNDBUF, sendBufSize);
179
+ socket_getsockopt(s, SO_RCVBUF, rcvBufSize);
180
+
181
+ socket_handle socket = 0;
182
+ while ((!pAcceptor->isStopped() && (socket = socket_accept(s)) != INVALID_SOCKET_HANDLE)) {
183
+ if (noDelay) {
184
+ socket_setsockopt(socket, TCP_NODELAY);
185
+ }
186
+ if (sendBufSize) {
187
+ socket_setsockopt(socket, SO_SNDBUF, sendBufSize);
188
+ }
189
+ if (rcvBufSize) {
190
+ socket_setsockopt(socket, SO_RCVBUF, rcvBufSize);
191
+ }
192
+
193
+ Sessions sessions = pAcceptor->m_portToSessions[port];
194
+
195
+ ThreadedSocketConnection *pConnection = new ThreadedSocketConnection(socket, sessions, pAcceptor->getLog());
196
+
197
+ ConnectionThreadInfo *info = new ConnectionThreadInfo(pAcceptor, pConnection);
198
+
199
+ {
200
+ Locker l(pAcceptor->m_mutex);
201
+
202
+ std::stringstream stream;
203
+ stream << "Accepted connection from " << socket_peername(socket) << " on port " << port;
204
+
205
+ if (pAcceptor->getLog()) {
206
+ pAcceptor->getLog()->onEvent(stream.str());
207
+ }
208
+
209
+ thread_id thread;
210
+ if (!thread_spawn(&socketConnectionThread, info, thread)) {
211
+ delete info;
212
+ delete pConnection;
213
+ } else {
214
+ pAcceptor->addThread(socket, thread);
215
+ }
216
+ }
217
+ }
218
+
219
+ if (!pAcceptor->isStopped()) {
220
+ pAcceptor->removeThread(s);
221
+ }
222
+
223
+ return 0;
224
+ }
225
+
226
+ THREAD_PROC ThreadedSocketAcceptor::socketConnectionThread(void *p) {
227
+ ConnectionThreadInfo *info = reinterpret_cast<ConnectionThreadInfo *>(p);
228
+
229
+ ThreadedSocketAcceptor *pAcceptor = info->m_pAcceptor;
230
+ ThreadedSocketConnection *pConnection = info->m_pConnection;
231
+ delete info;
232
+
233
+ socket_handle socket = pConnection->getSocket();
234
+
235
+ while (pConnection->read()) {}
236
+ delete pConnection;
237
+ if (!pAcceptor->isStopped()) {
238
+ pAcceptor->removeThread(socket);
239
+ }
240
+ return 0;
241
+ }
242
+ } // namespace FIX
@@ -0,0 +1,95 @@
1
+ /* -*- C++ -*- */
2
+
3
+ /****************************************************************************
4
+ ** Copyright (c) 2001-2014
5
+ **
6
+ ** This file is part of the QuickFIX FIX Engine
7
+ **
8
+ ** This file may be distributed under the terms of the quickfixengine.org
9
+ ** license as defined by quickfixengine.org and appearing in the file
10
+ ** LICENSE included in the packaging of this file.
11
+ **
12
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14
+ **
15
+ ** See http://www.quickfixengine.org/LICENSE for licensing information.
16
+ **
17
+ ** Contact ask@quickfixengine.org if any conditions of this licensing are
18
+ ** not clear to you.
19
+ **
20
+ ****************************************************************************/
21
+
22
+ #ifndef FIX_THREADEDSOCKETACCEPTOR_H
23
+ #define FIX_THREADEDSOCKETACCEPTOR_H
24
+
25
+ #ifdef _MSC_VER
26
+ #pragma warning(disable : 4503 4355 4786 4290)
27
+ #endif
28
+
29
+ #include "Acceptor.h"
30
+ #include "Mutex.h"
31
+ #include "ThreadedSocketConnection.h"
32
+
33
+ namespace FIX {
34
+ /// Threaded Socket implementation of Acceptor.
35
+ class ThreadedSocketAcceptor : public Acceptor {
36
+ friend class SocketConnection;
37
+
38
+ public:
39
+ ThreadedSocketAcceptor(Application &, MessageStoreFactory &, const SessionSettings &) EXCEPT(ConfigError);
40
+ ThreadedSocketAcceptor(Application &, MessageStoreFactory &, const SessionSettings &, LogFactory &)
41
+ EXCEPT(ConfigError);
42
+
43
+ virtual ~ThreadedSocketAcceptor();
44
+
45
+ private:
46
+ struct AcceptorThreadInfo {
47
+ AcceptorThreadInfo(ThreadedSocketAcceptor *pAcceptor, socket_handle socket, int port)
48
+ : m_pAcceptor(pAcceptor),
49
+ m_socket(socket),
50
+ m_port(port) {}
51
+
52
+ ThreadedSocketAcceptor *m_pAcceptor;
53
+ socket_handle m_socket;
54
+ int m_port;
55
+ };
56
+
57
+ struct ConnectionThreadInfo {
58
+ ConnectionThreadInfo(ThreadedSocketAcceptor *pAcceptor, ThreadedSocketConnection *pConnection)
59
+ : m_pAcceptor(pAcceptor),
60
+ m_pConnection(pConnection) {}
61
+
62
+ ThreadedSocketAcceptor *m_pAcceptor;
63
+ ThreadedSocketConnection *m_pConnection;
64
+ };
65
+
66
+ bool readSettings(const SessionSettings &);
67
+
68
+ typedef std::set<socket_handle> Sockets;
69
+ typedef std::set<SessionID> Sessions;
70
+ typedef std::map<int, Sessions> PortToSessions;
71
+ typedef std::map<socket_handle, int> SocketToPort;
72
+ typedef std::map<socket_handle, thread_id> SocketToThread;
73
+
74
+ void onConfigure(const SessionSettings &) EXCEPT(ConfigError);
75
+ void onInitialize(const SessionSettings &) EXCEPT(RuntimeError);
76
+
77
+ void onStart();
78
+ bool onPoll();
79
+ void onStop();
80
+
81
+ void addThread(socket_handle s, thread_id t);
82
+ void removeThread(socket_handle s);
83
+ static THREAD_PROC socketAcceptorThread(void *p);
84
+ static THREAD_PROC socketConnectionThread(void *p);
85
+
86
+ Sockets m_sockets;
87
+ PortToSessions m_portToSessions;
88
+ SocketToPort m_socketToPort;
89
+ SocketToThread m_threads;
90
+ Mutex m_mutex;
91
+ };
92
+ /*! @} */
93
+ } // namespace FIX
94
+
95
+ #endif // FIX_THREADEDSOCKETACCEPTOR_H
@@ -0,0 +1,227 @@
1
+ /****************************************************************************
2
+ ** Copyright (c) 2001-2014
3
+ **
4
+ ** This file is part of the QuickFIX FIX Engine
5
+ **
6
+ ** This file may be distributed under the terms of the quickfixengine.org
7
+ ** license as defined by quickfixengine.org and appearing in the file
8
+ ** LICENSE included in the packaging of this file.
9
+ **
10
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12
+ **
13
+ ** See http://www.quickfixengine.org/LICENSE for licensing information.
14
+ **
15
+ ** Contact ask@quickfixengine.org if any conditions of this licensing are
16
+ ** not clear to you.
17
+ **
18
+ ****************************************************************************/
19
+
20
+ #ifdef _MSC_VER
21
+ #include "stdafx.h"
22
+ #else
23
+ #include "config.h"
24
+ #include <poll.h>
25
+ #endif
26
+
27
+ #include "Session.h"
28
+ #include "ThreadedSocketAcceptor.h"
29
+ #include "ThreadedSocketConnection.h"
30
+ #include "ThreadedSocketInitiator.h"
31
+ #include "Utility.h"
32
+
33
+ namespace FIX {
34
+ ThreadedSocketConnection::ThreadedSocketConnection(socket_handle s, Sessions sessions, Log *pLog)
35
+ : m_socket(s),
36
+ m_pLog(pLog),
37
+ m_sessions(sessions),
38
+ m_pSession(0),
39
+ m_disconnect(false) {
40
+ #if _MSC_VER
41
+ FD_ZERO(&m_fds);
42
+ FD_SET(m_socket, &m_fds);
43
+ #endif
44
+ }
45
+
46
+ ThreadedSocketConnection::ThreadedSocketConnection(
47
+ const SessionID &sessionID,
48
+ socket_handle s,
49
+ const std::string &address,
50
+ short port,
51
+ Log *pLog,
52
+ const std::string &sourceAddress,
53
+ short sourcePort)
54
+ : m_socket(s),
55
+ m_address(address),
56
+ m_port(port),
57
+ m_sourceAddress(sourceAddress),
58
+ m_sourcePort(sourcePort),
59
+ m_pLog(pLog),
60
+ m_pSession(Session::lookupSession(sessionID)),
61
+ m_disconnect(false) {
62
+ #if _MSC_VER
63
+ FD_ZERO(&m_fds);
64
+ FD_SET(m_socket, &m_fds);
65
+ #endif
66
+ if (m_pSession) {
67
+ m_pSession->setResponder(this);
68
+ }
69
+ }
70
+
71
+ ThreadedSocketConnection::~ThreadedSocketConnection() {
72
+ if (m_pSession) {
73
+ m_pSession->setResponder(0);
74
+ Session::unregisterSession(m_pSession->getSessionID());
75
+ }
76
+ }
77
+
78
+ bool ThreadedSocketConnection::send(const std::string &msg) {
79
+ ssize_t totalSent = 0;
80
+ while (totalSent < (int)msg.length()) {
81
+ ssize_t sent = socket_send(m_socket, msg.c_str() + totalSent, msg.length());
82
+ if (sent < 0) {
83
+ return false;
84
+ }
85
+ totalSent += sent;
86
+ }
87
+
88
+ return true;
89
+ }
90
+
91
+ bool ThreadedSocketConnection::connect() {
92
+ // do the bind in the thread as name resolution may block
93
+ if (!m_sourceAddress.empty() || m_sourcePort) {
94
+ socket_bind(m_socket, m_sourceAddress.c_str(), m_sourcePort);
95
+ }
96
+
97
+ return socket_connect(getSocket(), m_address.c_str(), m_port) >= 0;
98
+ }
99
+
100
+ void ThreadedSocketConnection::disconnect() {
101
+ m_disconnect = true;
102
+ socket_close(m_socket);
103
+ }
104
+
105
+ bool ThreadedSocketConnection::read() {
106
+ #if _MSC_VER
107
+ struct timeval timeout = {1, 0};
108
+ fd_set readset = m_fds;
109
+ #else
110
+ int timeout = 1000; // 1000ms = 1 second
111
+ struct pollfd pfd = {m_socket, POLLIN | POLLPRI, 0};
112
+ #endif
113
+
114
+ try {
115
+ // Wait for input (1 second timeout)
116
+ #if _MSC_VER
117
+ int result = select(0, &readset, 0, 0, &timeout);
118
+ #else
119
+ int result = poll(&pfd, 1, timeout);
120
+ #endif
121
+
122
+ if (result > 0) // Something to read
123
+ {
124
+ // We can read without blocking
125
+ ssize_t size = socket_recv(m_socket, m_buffer, sizeof(m_buffer));
126
+ if (size <= 0) {
127
+ throw SocketRecvFailed(size);
128
+ }
129
+ m_parser.addToStream(m_buffer, size);
130
+ } else if (result == 0 && m_pSession) // Timeout
131
+ {
132
+ m_pSession->next(UtcTimeStamp::now());
133
+ } else if (result < 0) // Error
134
+ {
135
+ throw SocketRecvFailed(result);
136
+ }
137
+
138
+ processStream();
139
+ return true;
140
+ } catch (SocketRecvFailed &e) {
141
+ if (m_disconnect) {
142
+ return false;
143
+ }
144
+
145
+ if (m_pSession) {
146
+ m_pSession->getLog()->onEvent(e.what());
147
+ m_pSession->disconnect();
148
+ } else {
149
+ disconnect();
150
+ }
151
+
152
+ return false;
153
+ }
154
+ }
155
+
156
+ bool ThreadedSocketConnection::readMessage(std::string &msg) EXCEPT(SocketRecvFailed) {
157
+ try {
158
+ return m_parser.readFixMessage(msg);
159
+ } catch (MessageParseError &) {}
160
+ return true;
161
+ }
162
+
163
+ void ThreadedSocketConnection::processStream() {
164
+ std::string msg;
165
+ while (readMessage(msg)) {
166
+ if (!m_pSession) {
167
+ if (!setSession(msg)) {
168
+ disconnect();
169
+ continue;
170
+ }
171
+ }
172
+ try {
173
+ m_pSession->next(msg, UtcTimeStamp::now());
174
+ } catch (InvalidMessage &) {
175
+ if (!m_pSession->isLoggedOn()) {
176
+ disconnect();
177
+ return;
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ bool ThreadedSocketConnection::setSession(const std::string &msg) {
184
+ m_pSession = Session::lookupSession(msg, true);
185
+ if (!m_pSession) {
186
+ if (m_pLog) {
187
+ m_pLog->onEvent("Session not found for incoming message: " + msg);
188
+ m_pLog->onIncoming(msg);
189
+ }
190
+ return false;
191
+ }
192
+
193
+ SessionID sessionID = m_pSession->getSessionID();
194
+ m_pSession = 0;
195
+
196
+ // see if the session frees up within 5 seconds
197
+ for (int i = 1; i <= 5; i++) {
198
+ if (!Session::isSessionRegistered(sessionID)) {
199
+ m_pSession = Session::registerSession(sessionID);
200
+ }
201
+ if (m_pSession) {
202
+ break;
203
+ }
204
+ process_sleep(1);
205
+ }
206
+
207
+ if (!m_pSession) {
208
+ return false;
209
+ }
210
+ if (m_sessions.find(m_pSession->getSessionID()) == m_sessions.end()) {
211
+ return false;
212
+ }
213
+
214
+ if (m_pSession->isAcceptor()) {
215
+ std::string remote_address = socket_peername(m_socket);
216
+ if (!m_pSession->getAllowedRemoteAddresses().empty() && !m_pSession->inAllowedRemoteAddresses(remote_address)) {
217
+ m_pSession->getLog()->onEvent("Deny connections to the acceptor from " + remote_address);
218
+ return false;
219
+ }
220
+ m_pSession->getLog()->onEvent("Allows connections to the acceptor from " + remote_address);
221
+ }
222
+
223
+ m_pSession->setResponder(this);
224
+ return true;
225
+ }
226
+
227
+ } // namespace FIX
@@ -0,0 +1,89 @@
1
+ /* -*- C++ -*- */
2
+
3
+ /****************************************************************************
4
+ ** Copyright (c) 2001-2014
5
+ **
6
+ ** This file is part of the QuickFIX FIX Engine
7
+ **
8
+ ** This file may be distributed under the terms of the quickfixengine.org
9
+ ** license as defined by quickfixengine.org and appearing in the file
10
+ ** LICENSE included in the packaging of this file.
11
+ **
12
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14
+ **
15
+ ** See http://www.quickfixengine.org/LICENSE for licensing information.
16
+ **
17
+ ** Contact ask@quickfixengine.org if any conditions of this licensing are
18
+ ** not clear to you.
19
+ **
20
+ ****************************************************************************/
21
+
22
+ #ifndef FIX_THREADEDSOCKETCONNECTION_H
23
+ #define FIX_THREADEDSOCKETCONNECTION_H
24
+
25
+ #ifdef _MSC_VER
26
+ #pragma warning(disable : 4503 4355 4786 4290)
27
+ #endif
28
+
29
+ #include "Parser.h"
30
+ #include "Responder.h"
31
+ #include "SessionID.h"
32
+ #include <map>
33
+ #include <set>
34
+
35
+ namespace FIX {
36
+ class ThreadedSocketAcceptor;
37
+ class ThreadedSocketInitiator;
38
+ class Session;
39
+ class Application;
40
+ class Log;
41
+
42
+ /// Encapsulates a socket file descriptor (multi-threaded).
43
+ class ThreadedSocketConnection : Responder {
44
+ public:
45
+ typedef std::set<SessionID> Sessions;
46
+
47
+ ThreadedSocketConnection(socket_handle s, Sessions sessions, Log *pLog);
48
+ ThreadedSocketConnection(
49
+ const SessionID &,
50
+ socket_handle s,
51
+ const std::string &address,
52
+ short port,
53
+ Log *pLog,
54
+ const std::string &sourceAddress = "",
55
+ short sourcePort = 0);
56
+ virtual ~ThreadedSocketConnection();
57
+
58
+ Session *getSession() const { return m_pSession; }
59
+ socket_handle getSocket() const { return m_socket; }
60
+ bool connect();
61
+ void disconnect();
62
+ bool read();
63
+
64
+ private:
65
+ bool readMessage(std::string &msg) EXCEPT(SocketRecvFailed);
66
+ void processStream();
67
+ bool send(const std::string &);
68
+ bool setSession(const std::string &msg);
69
+
70
+ socket_handle m_socket;
71
+ char m_buffer[BUFSIZ];
72
+
73
+ std::string m_address;
74
+ int m_port;
75
+ std::string m_sourceAddress;
76
+ int m_sourcePort;
77
+
78
+ Log *m_pLog;
79
+ Parser m_parser;
80
+ Sessions m_sessions;
81
+ Session *m_pSession;
82
+ bool m_disconnect;
83
+ #if _MSC_VER
84
+ fd_set m_fds;
85
+ #endif
86
+ };
87
+ } // namespace FIX
88
+
89
+ #endif // FIX_THREADEDSOCKETCONNECTION_H