blob: e744a6a462139881f2a53b3b562d6c43b8990040 [file] [log] [blame] [view]
Mark Slee54b7ab92007-03-06 00:06:27 +00001Thrift C++ Software Library
2
Roger Meier6370cfd2014-05-04 22:21:58 +02003# License
Bryan Duxburydef30a62009-04-08 00:19:37 +00004
5Licensed to the Apache Software Foundation (ASF) under one
6or more contributor license agreements. See the NOTICE file
7distributed with this work for additional information
8regarding copyright ownership. The ASF licenses this file
9to you under the Apache License, Version 2.0 (the
10"License"); you may not use this file except in compliance
11with the License. You may obtain a copy of the License at
12
13 http://www.apache.org/licenses/LICENSE-2.0
14
15Unless required by applicable law or agreed to in writing,
16software distributed under the License is distributed on an
17"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18KIND, either express or implied. See the License for the
19specific language governing permissions and limitations
20under the License.
Mark Slee54b7ab92007-03-06 00:06:27 +000021
Roger Meier6370cfd2014-05-04 22:21:58 +020022# Using Thrift with C++
Mark Slee54b7ab92007-03-06 00:06:27 +000023
24The Thrift C++ libraries are built using the GNU tools. Follow the instructions
Roger Meier6370cfd2014-05-04 22:21:58 +020025in the top-level README.md
Mark Slee54b7ab92007-03-06 00:06:27 +000026
Roger Meier6370cfd2014-05-04 22:21:58 +020027In case you do not want to open another README.md file, do this thrift src:
28
29 ./bootstrap.sh
30 ./configure (--with-boost=/usr/local)
31 make
32 sudo make install
Mark Slee54b7ab92007-03-06 00:06:27 +000033
34Thrift is divided into two libraries.
35
Roger Meier6370cfd2014-05-04 22:21:58 +020036* libthrift - The core Thrift library contains all the core Thrift code. It requires
Mark Slee54b7ab92007-03-06 00:06:27 +000037 boost shared pointers, pthreads, and librt.
38
Roger Meier6370cfd2014-05-04 22:21:58 +020039* libthriftnb - This library contains the Thrift nonblocking server, which uses libevent.
Mark Slee54b7ab92007-03-06 00:06:27 +000040 To link this library you will also need to link libevent.
41
Roger Meier6370cfd2014-05-04 22:21:58 +020042## Linking Against Thrift
Mark Slee54b7ab92007-03-06 00:06:27 +000043
44After you build and install Thrift the libraries are installed to
45/usr/local/lib by default. Make sure this is in your LDPATH.
46
47On Linux, the best way to do this is to ensure that /usr/local/lib is in
48your /etc/ld.so.conf and then run /sbin/ldconfig.
49
50Depending upon whether you are linking dynamically or statically and how
51your build environment it set up, you may need to include additional
52libraries when linking against thrift, such as librt and/or libpthread. If
53you are using libthriftnb you will also need libevent.
54
Roger Meier6370cfd2014-05-04 22:21:58 +020055## Dependencies
Mark Slee54b7ab92007-03-06 00:06:27 +000056
James E. King, III82ae9572017-08-05 12:23:54 -040057If your C++ environment implements C++11 or later, thrift will automatically use
58std::shared_ptr. Otherwise you will need the boost library to provide a shared_ptr
59implementation for C++ environments pre-C++11. If you are linking against code
60that expects to be using boost::shared_ptr, you can define the preprocessor
61variable FORCE_BOOST_SMART_PTR for your build of thrift to make it use boost instead
62of std for a number of memory related classes. See thrift/stdcxx.h for more.
Mark Slee54b7ab92007-03-06 00:06:27 +000063
64libevent (for libthriftnb only)
65http://monkey.org/~provos/libevent/
Roger Meier6370cfd2014-05-04 22:21:58 +020066
67# Using Thrift with C++ on Windows
68
James E. King, III82ae9572017-08-05 12:23:54 -040069Both the autoconf and cmake build systems are able to automatically detect many
70system configurations without the need to specify library locations, however if
71you run into problems or want to redirect thrift to build and link against your
72own provided third party libraries:
Roger Meier6370cfd2014-05-04 22:21:58 +020073
Roger Meierfaf52db2014-06-09 22:41:06 +020074BOOST_ROOT : For boost, e.g. D:\boost_1_55_0
75OPENSSL_ROOT_DIR : For OpenSSL, e.g. D:\OpenSSL-Win32
76
77only required by libthriftnb:
78
79LIBEVENT_ROOT_DIR : For Libevent e.g. D:\libevent-2.0.21-stable
80
81See /3rdparty.user for more details.
Roger Meier6370cfd2014-05-04 22:21:58 +020082
James E. King, III82ae9572017-08-05 12:23:54 -040083The same linking guidelines described above for libthriftnb apply to windows as well.
Roger Meier6370cfd2014-05-04 22:21:58 +020084
85## Linking Against Thrift
86
87You need to link your project that uses thrift against all the thrift
Roger Meierfaf52db2014-06-09 22:41:06 +020088dependencies; in the case of libthrift, boost and for
Roger Meier6370cfd2014-05-04 22:21:58 +020089libthriftnb, libevent.
90
91In the project properties you must also set HAVE_CONFIG_H as force include
92the config header: "windows/confg.h"
93
94## Dependencies
95
James E. King, III82ae9572017-08-05 12:23:54 -040096The same dependencies for shared_ptr as described above apply to windows as well.
Roger Meier6370cfd2014-05-04 22:21:58 +020097
98boost thread
99http://www.boost.org/doc/libs/release/doc/html/thread.html
100
101libevent (for libthriftnb only)
102http://monkey.org/~provos/libevent/
103
104## Notes on boost thread (static vs shared):
105
106By default lib/cpp/windows/force_inc.h defines:
107
108 #define BOOST_ALL_NO_LIB 1
109 #define BOOST_THREAD_NO_LIB 1
110
111This has for effect to have the host application linking against Thrift
112to have to link with boost thread as a static library.
113
114If you wanted instead to link with boost thread as a shared library,
115you'll need to uncomment those two lines, and recompile.
116
117## Windows version compatibility
118
119The Thrift library targets Windows XP for broadest compatbility. A notable
120difference is in the Windows-specific implementation of the socket poll
121function. To target Vista, Win7 or other versions, comment out the line
122
123 #define TARGET_WIN_XP.
124
125## Named Pipes
126
127Named Pipe transport has been added in the TPipe and TPipeServer classes. This
128is currently Windows-only. Named pipe transport for *NIX has not been
129implemented. Domain sockets are a better choice for local IPC under non-Windows
130OS's. *NIX named pipes only support 1:1 client-server connection.
131
132# Thrift/SSL
133
Roger Meier4fba9d22014-05-04 22:34:44 +0200134## Scope
Roger Meier6370cfd2014-05-04 22:21:58 +0200135
Roger Meier4fba9d22014-05-04 22:34:44 +0200136This SSL only supports blocking mode socket I/O. It can only be used with
137TSimpleServer, TThreadedServer, and TThreadPoolServer.
Roger Meier6370cfd2014-05-04 22:21:58 +0200138
Roger Meier4fba9d22014-05-04 22:34:44 +0200139## Implementation
Roger Meier6370cfd2014-05-04 22:21:58 +0200140
Roger Meier4fba9d22014-05-04 22:34:44 +0200141There're two main classes TSSLSocketFactory and TSSLSocket. Instances of
142TSSLSocket are always created from TSSLSocketFactory.
Roger Meier6370cfd2014-05-04 22:21:58 +0200143
Roger Meier4fba9d22014-05-04 22:34:44 +0200144PosixSSLThreadFactory creates PosixSSLThread. The only difference from the
145PthreadThread type is that it cleanups OpenSSL error queue upon exiting
146the thread. Ideally, OpenSSL APIs should only be called from PosixSSLThread.
Roger Meier6370cfd2014-05-04 22:21:58 +0200147
Roger Meier4fba9d22014-05-04 22:34:44 +0200148## How to use SSL APIs
Roger Meier6370cfd2014-05-04 22:21:58 +0200149
Roger Meier4fba9d22014-05-04 22:34:44 +0200150This is for demo. In real code, typically only one TSSLSocketFactory
151instance is needed.
Roger Meier6370cfd2014-05-04 22:21:58 +0200152
Roger Meier4fba9d22014-05-04 22:34:44 +0200153 shared_ptr<TSSLSocketFactory> getSSLSocketFactory() {
154 shared_ptr<TSSLSocketFactory> factory(new TSSLSocketFactory());
155 // client: load trusted certificates
156 factory->loadTrustedCertificates("my-trusted-ca-certificates.pem");
157 // client: optionally set your own access manager, otherwise,
158 // the default client access manager will be loaded.
159
160 factory->loadCertificate("my-certificate-signed-by-ca.pem");
161 factory->loadPrivateKey("my-private-key.pem");
162 // server: optionally setup access manager
163 // shared_ptr<AccessManager> accessManager(new MyAccessManager);
164 // factory->access(accessManager);
165 ...
166 }
Roger Meier6370cfd2014-05-04 22:21:58 +0200167
168
Roger Meier4fba9d22014-05-04 22:34:44 +0200169client code sample
170
171 shared_ptr<TSSLSocketFactory> factory = getSSLSocketFactory();
172 shared_ptr<TSocket> socket = factory.createSocket(host, port);
173 shared_ptr<TBufferedTransport> transport(new TBufferedTransport(socket));
174 ...
Roger Meier6370cfd2014-05-04 22:21:58 +0200175
176
Roger Meier4fba9d22014-05-04 22:34:44 +0200177server code sample
Roger Meier6370cfd2014-05-04 22:21:58 +0200178
Roger Meier4fba9d22014-05-04 22:34:44 +0200179 shared_ptr<TSSLSocketFactory> factory = getSSLSocketFactory();
180 shared_ptr<TSSLServerSocket> socket(new TSSLServerSocket(port, factory));
181 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory));
182 ...
Roger Meier6370cfd2014-05-04 22:21:58 +0200183
Roger Meier4fba9d22014-05-04 22:34:44 +0200184## AccessManager
Roger Meier6370cfd2014-05-04 22:21:58 +0200185
Roger Meier4fba9d22014-05-04 22:34:44 +0200186AccessManager defines a callback interface. It has three callback methods:
Roger Meier6370cfd2014-05-04 22:21:58 +0200187
Roger Meier4fba9d22014-05-04 22:34:44 +0200188(a) Decision verify(const sockaddr_storage& sa);
Roger Meier6370cfd2014-05-04 22:21:58 +0200189
Roger Meier4fba9d22014-05-04 22:34:44 +0200190(b) Decision verify(const string& host, const char* name, int size);
Roger Meier6370cfd2014-05-04 22:21:58 +0200191
Roger Meier4fba9d22014-05-04 22:34:44 +0200192(c) Decision verify(const sockaddr_storage& sa, const char* data, int size);
Roger Meier6370cfd2014-05-04 22:21:58 +0200193
Roger Meier4fba9d22014-05-04 22:34:44 +0200194After SSL handshake completes, additional checks are conducted. Application
195is given the chance to decide whether or not to continue the conversation
196with the remote. Application is queried through the above three "verify"
197method. They are called at different points of the verification process.
Roger Meier6370cfd2014-05-04 22:21:58 +0200198
Roger Meier4fba9d22014-05-04 22:34:44 +0200199Decisions can be one of ALLOW, DENY, and SKIP. ALLOW and DENY means the
200conversation should be continued or disconnected, respectively. ALLOW and
201DENY decision stops the verification process. SKIP means there's no decision
202based on the given input, continue the verification process.
Roger Meier6370cfd2014-05-04 22:21:58 +0200203
Roger Meier4fba9d22014-05-04 22:34:44 +0200204First, (a) is called with the remote IP. It is called once at the beginning.
205"sa" is the IP address of the remote peer.
Roger Meier6370cfd2014-05-04 22:21:58 +0200206
Roger Meier4fba9d22014-05-04 22:34:44 +0200207Then, the certificate of remote peer is loaded. SubjectAltName extensions
208are extracted and sent to application for verification. When a DNS
209subjectAltName field is extracted, (b) is called. When an IP subjectAltName
210field is extracted, (c) is called.
Roger Meier6370cfd2014-05-04 22:21:58 +0200211
Roger Meier4fba9d22014-05-04 22:34:44 +0200212The "host" in (b) is the value from TSocket::getHost() if this is a client
213side socket, or TSocket::getPeerHost() if this is a server side socket. The
214reason is client side socket initiates the connection. TSocket::getHost()
215is the remote host name. On server side, the remote host name is unknown
216unless it's retrieved through TSocket::getPeerHost(). Either way, "host"
217should be the remote host name. Keep in mind, if TSocket::getPeerHost()
218failed, it would return the remote host name in numeric format.
Roger Meier6370cfd2014-05-04 22:21:58 +0200219
Roger Meier4fba9d22014-05-04 22:34:44 +0200220If all subjectAltName extensions were "skipped", the common name field would
221be checked. It is sent to application through (c), where "sa" is the remote
222IP address. "data" is the IP address extracted from subjectAltName IP
223extension, and "size" is the length of the extension data.
Roger Meier6370cfd2014-05-04 22:21:58 +0200224
Roger Meier4fba9d22014-05-04 22:34:44 +0200225If any of the above "verify" methods returned a decision ALLOW or DENY, the
226verification process would be stopped.
Roger Meier6370cfd2014-05-04 22:21:58 +0200227
Roger Meier4fba9d22014-05-04 22:34:44 +0200228If any of the above "verify" methods returned SKIP, that decision would be
229ignored and the verification process would move on till the last item is
230examined. At that point, if there's still no decision, the connection is
231terminated.
Roger Meier6370cfd2014-05-04 22:21:58 +0200232
Roger Meier4fba9d22014-05-04 22:34:44 +0200233Thread safety, an access manager should not store state information if it's
234to be used by many SSL sockets.
Roger Meier6370cfd2014-05-04 22:21:58 +0200235
Roger Meier4fba9d22014-05-04 22:34:44 +0200236## SIGPIPE signal
Roger Meier6370cfd2014-05-04 22:21:58 +0200237
Roger Meier4fba9d22014-05-04 22:34:44 +0200238Applications running OpenSSL over network connections may crash if SIGPIPE
239is not ignored. This happens when they receive a connection reset by remote
240peer exception, which somehow triggers a SIGPIPE signal. If not handled,
241this signal would kill the application.
Roger Meier6370cfd2014-05-04 22:21:58 +0200242
Roger Meier4fba9d22014-05-04 22:34:44 +0200243## How to run test client/server in SSL mode
Roger Meier6370cfd2014-05-04 22:21:58 +0200244
Roger Meier4fba9d22014-05-04 22:34:44 +0200245The server and client expects the followings from the directory /test/
Roger Meier6370cfd2014-05-04 22:21:58 +0200246
Roger Meier4fba9d22014-05-04 22:34:44 +0200247- keys/server.crt
248- keys/server.key
249- keys/CA.pem
Roger Meier6370cfd2014-05-04 22:21:58 +0200250
Roger Meier4fba9d22014-05-04 22:34:44 +0200251The file names are hard coded in the source code. You need to create these
252certificates before you can run the test code in SSL mode. Make sure at least
253one of the followings is included in "keys/server.crt",
Roger Meier6370cfd2014-05-04 22:21:58 +0200254
Roger Meier4fba9d22014-05-04 22:34:44 +0200255- subjectAltName, DNS localhost
256- subjectAltName, IP 127.0.0.1
257- common name, localhost
Roger Meier6370cfd2014-05-04 22:21:58 +0200258
Roger Meier4fba9d22014-05-04 22:34:44 +0200259Run within /test/ folder,
Roger Meier6370cfd2014-05-04 22:21:58 +0200260
Roger Meier4fba9d22014-05-04 22:34:44 +0200261 ./cpp/TestServer --ssl &
262 ./cpp/TestClient --ssl
Roger Meier6370cfd2014-05-04 22:21:58 +0200263
Roger Meier4fba9d22014-05-04 22:34:44 +0200264If "-h <host>" is used to run client, the above "localhost" in the above
265keys/server.crt has to be replaced with that host name.
266
267## TSSLSocketFactory::randomize()
268
269The default implementation of OpenSSLSocketFactory::randomize() simply calls
270OpenSSL's RAND_poll() when OpenSSL library is first initialized.
271
272The PRNG seed is key to the application security. This method should be
273overridden if it's not strong enough for you.
James E. King, III7bc94312017-03-31 21:25:20 -0400274
275# Breaking Changes
276
277## 0.11.0
278
James E. King, III82ae9572017-08-05 12:23:54 -0400279Older versions of thrift depended on the <boost/smart_ptr.hpp> classes which
280were used in thrift headers to define interfaces. Thrift now detects C++11
281at build time and will prefer to use <memory> classes from C++11 instead.
282You can force the library to build with boost memory classes by defining the
283preprocessor macro `FORCE_BOOST_SMART_PTR`. (THRIFT-2221)
284
James E. King, III7bc94312017-03-31 21:25:20 -0400285In the pthread mutex implementation, the contention profiling code was enabled
286by default in all builds. This changed to be disabled by default. (THRIFT-4151)
James E. King, III7f5a8c22017-04-04 09:36:38 -0400287
288In older releases, if a TSSLSocketFactory's lifetime was not at least as long
289as the TSSLSockets it created, we silently reverted openssl to unsafe multithread behavior
290and so the results were undefined. Changes were made in 0.11.0 that cause either an
291assertion or a core instead of undefined behavior. The lifetime of a TSSLSocketFactory
292*must* be longer than any TSSLSocket that it creates, otherwise openssl will be cleaned
293up too early. If the static boolean is set to disable openssl initialization and
294cleanup and leave it up to the consuming application, this requirement is not needed.
295(THRIFT-4164)
296