libcouchbase 0.0.7 → 0.0.8
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.
- checksums.yaml +4 -4
- data/ext/libcouchbase/.gitignore +2 -0
- data/ext/libcouchbase/CMakeLists.txt +5 -7
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +49 -0
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +2 -1
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +2 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +34 -14
- data/ext/libcouchbase/configure.pl +1 -1
- data/ext/libcouchbase/contrib/genhash/genhash.h +6 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +10 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +7 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +13 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +9 -0
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +21 -1132
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +1 -0
- data/ext/libcouchbase/src/auth.cc +10 -0
- data/ext/libcouchbase/src/bootstrap.cc +216 -0
- data/ext/libcouchbase/src/bootstrap.h +50 -39
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +455 -0
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +528 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +115 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +407 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +378 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +24 -24
- data/ext/libcouchbase/src/connspec.cc +30 -1
- data/ext/libcouchbase/src/connspec.h +17 -0
- data/ext/libcouchbase/src/dns-srv.cc +143 -0
- data/ext/libcouchbase/src/{dump.c → dump.cc} +8 -11
- data/ext/libcouchbase/src/getconfig.cc +73 -0
- data/ext/libcouchbase/src/handler.cc +84 -85
- data/ext/libcouchbase/src/hostlist.cc +0 -1
- data/ext/libcouchbase/src/hostlist.h +6 -1
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +9 -29
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +22 -26
- data/ext/libcouchbase/src/instance.cc +102 -28
- data/ext/libcouchbase/src/internal.h +47 -29
- data/ext/libcouchbase/src/jsparse/parser.cc +146 -202
- data/ext/libcouchbase/src/jsparse/parser.h +91 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +562 -0
- data/ext/libcouchbase/src/lcbio/connect.h +9 -2
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +61 -16
- data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
- data/ext/libcouchbase/src/lcbio/manager.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +723 -0
- data/ext/libcouchbase/src/mcserver/mcserver.h +160 -70
- data/ext/libcouchbase/src/mcserver/negotiate.cc +118 -152
- data/ext/libcouchbase/src/mcserver/negotiate.h +85 -74
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +56 -32
- data/ext/libcouchbase/src/{newconfig.c → newconfig.cc} +42 -70
- data/ext/libcouchbase/src/nodeinfo.cc +4 -8
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/{durability-cas.c → durability-cas.cc} +92 -76
- data/ext/libcouchbase/src/operations/{durability-seqno.c → durability-seqno.cc} +55 -49
- data/ext/libcouchbase/src/operations/durability.cc +643 -0
- data/ext/libcouchbase/src/operations/durability_internal.h +212 -124
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe-seqno.c → observe-seqno.cc} +5 -8
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +69 -94
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/{stats.c → stats.cc} +66 -78
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +38 -18
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +200 -137
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +3 -4
- data/ext/libcouchbase/src/retryq.cc +394 -0
- data/ext/libcouchbase/src/retryq.h +116 -104
- data/ext/libcouchbase/src/settings.h +2 -1
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/trace.h +8 -8
- data/ext/libcouchbase/src/vbucket/vbucket.c +0 -1
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/src/{wait.c → wait.cc} +12 -17
- data/ext/libcouchbase/tests/basic/t_connstr.cc +89 -50
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -78
- data/ext/libcouchbase/tests/basic/t_packet.cc +35 -42
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +94 -111
- data/ext/libcouchbase/tests/iotests/t_sched.cc +1 -2
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
- data/lib/libcouchbase/version.rb +1 -1
- metadata +36 -39
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +0 -495
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/getconfig.c +0 -100
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/mcserver/mcserver.c +0 -784
- data/ext/libcouchbase/src/operations/durability.c +0 -668
- data/ext/libcouchbase/src/packetutils.c +0 -60
- data/ext/libcouchbase/src/retryq.c +0 -424
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
|
@@ -24,98 +24,188 @@
|
|
|
24
24
|
#include <netbuf/netbuf.h>
|
|
25
25
|
|
|
26
26
|
#ifdef __cplusplus
|
|
27
|
-
|
|
28
|
-
#endif
|
|
27
|
+
namespace lcb {
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
struct
|
|
29
|
+
class RetryQueue;
|
|
30
|
+
struct RetryOp;
|
|
32
31
|
|
|
33
32
|
/**
|
|
34
33
|
* The structure representing each couchbase server
|
|
35
34
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
class Server : public mc_PIPELINE {
|
|
36
|
+
public:
|
|
37
|
+
/**
|
|
38
|
+
* Allocate and initialize a new server object. The object will not be
|
|
39
|
+
* connected
|
|
40
|
+
* @param instance the instance to which the server belongs
|
|
41
|
+
* @param ix the server index in the configuration
|
|
42
|
+
*/
|
|
43
|
+
Server(lcb_t, int);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Close the server. The resources of the server may still continue to persist
|
|
47
|
+
* internally for a bit until all callbacks have been delivered and all buffers
|
|
48
|
+
* flushed and/or failed.
|
|
49
|
+
*/
|
|
50
|
+
void close();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Schedule a flush and potentially flush some immediate data on the server.
|
|
54
|
+
* This is safe to call multiple times, however performance considerations
|
|
55
|
+
* should be taken into account
|
|
56
|
+
*/
|
|
57
|
+
void flush();
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Wrapper around mcreq_pipeline_timeout() and/or mcreq_pipeline_fail(). This
|
|
61
|
+
* function will purge all pending requests within the server and invoke
|
|
62
|
+
* their callbacks with the given error code passed as `err`. Depending on
|
|
63
|
+
* the error code, some operations may be retried.
|
|
64
|
+
*
|
|
65
|
+
* @param err the error code by which to fail the commands
|
|
66
|
+
*
|
|
67
|
+
* @note This function does not modify the server's socket or state in itself,
|
|
68
|
+
* but rather simply wipes the commands from its queue
|
|
69
|
+
*/
|
|
70
|
+
void purge(lcb_error_t err) {
|
|
71
|
+
purge(err, 0, NULL, Server::REFRESH_NEVER);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Callback for mc_pipeline_fail_chain */
|
|
75
|
+
inline void purge_single(mc_PACKET*, lcb_error_t);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Returns true or false depending on whether there are pending commands on
|
|
79
|
+
* this server
|
|
80
|
+
*/
|
|
81
|
+
bool has_pending() const {
|
|
82
|
+
return !SLLIST_IS_EMPTY(&requests);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
int get_index() const {
|
|
86
|
+
return mc_PIPELINE::index;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
lcb_t get_instance() const {
|
|
90
|
+
return instance;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const lcb_settings* get_settings() const {
|
|
94
|
+
return settings;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
void set_new_index(int new_index) {
|
|
98
|
+
mc_PIPELINE::index = new_index;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const lcb_host_t& get_host() const {
|
|
102
|
+
return *curhost;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
bool supports_mutation_tokens() const {
|
|
106
|
+
return mutation_tokens;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
bool supports_compression() const {
|
|
110
|
+
return compsupport;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
bool is_connected() const {
|
|
114
|
+
return connctx != NULL;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** "Temporary" constructor. Only for use in retry queue */
|
|
118
|
+
Server();
|
|
119
|
+
~Server();
|
|
120
|
+
|
|
121
|
+
enum State {
|
|
122
|
+
/* There are no known errored commands on this server */
|
|
123
|
+
S_CLEAN,
|
|
124
|
+
|
|
125
|
+
/* In the process of draining remaining commands to be flushed. The commands
|
|
126
|
+
* being drained may have already been rescheduled to another server or
|
|
127
|
+
* placed inside the error queue, but are pending being flushed. This will
|
|
128
|
+
* only happen in completion-style I/O plugins. When this state is in effect,
|
|
129
|
+
* subsequent attempts to connect will be blocked until all commands have
|
|
130
|
+
* been properly drained.
|
|
131
|
+
*/
|
|
132
|
+
S_ERRDRAIN,
|
|
133
|
+
|
|
134
|
+
/* The server object has been closed, either because it has been removed
|
|
135
|
+
* from the cluster or because the related lcb_t has been destroyed.
|
|
136
|
+
*/
|
|
137
|
+
S_CLOSED,
|
|
138
|
+
|
|
139
|
+
/*
|
|
140
|
+
* Server has been temporarily constructed.
|
|
141
|
+
*/
|
|
142
|
+
S_TEMPORARY
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
static Server* get(lcbio_CTX *ctx) {
|
|
146
|
+
return reinterpret_cast<Server*>(lcbio_ctx_data(ctx));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
uint32_t default_timeout() const {
|
|
150
|
+
return settings->operation_timeout;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
uint32_t next_timeout() const;
|
|
154
|
+
|
|
155
|
+
bool check_closed();
|
|
156
|
+
void start_errored_ctx(State next_state);
|
|
157
|
+
void finalize_errored_ctx();
|
|
158
|
+
void socket_failed(lcb_error_t);
|
|
159
|
+
void io_timeout();
|
|
160
|
+
|
|
161
|
+
enum RefreshPolicy {
|
|
162
|
+
REFRESH_ALWAYS,
|
|
163
|
+
REFRESH_ONFAILED,
|
|
164
|
+
REFRESH_NEVER
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
int purge(lcb_error_t error, hrtime_t thresh, hrtime_t *next,
|
|
168
|
+
RefreshPolicy policy);
|
|
169
|
+
|
|
170
|
+
void connect();
|
|
171
|
+
|
|
172
|
+
void handle_connected(lcbio_SOCKET *socket, lcb_error_t err, lcbio_OSERR syserr);
|
|
173
|
+
|
|
174
|
+
enum ReadState {
|
|
175
|
+
PKT_READ_COMPLETE,
|
|
176
|
+
PKT_READ_PARTIAL
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
ReadState try_read(lcbio_CTX *ctx, rdb_IOROPE *ior);
|
|
180
|
+
bool handle_nmv(MemcachedResponse& resinfo, mc_PACKET *oldpkt);
|
|
181
|
+
bool maybe_retry_packet(mc_PACKET *pkt, lcb_error_t err);
|
|
182
|
+
bool maybe_reconnect_on_fake_timeout(lcb_error_t received_error);
|
|
183
|
+
|
|
184
|
+
/** Disable */
|
|
185
|
+
Server(const Server&);
|
|
186
|
+
|
|
187
|
+
State state;
|
|
188
|
+
|
|
189
|
+
/** IO/Operation timer */
|
|
190
|
+
lcbio_pTIMER io_timer;
|
|
39
191
|
|
|
40
192
|
/** Pointer back to the instance */
|
|
41
193
|
lcb_t instance;
|
|
42
194
|
|
|
43
195
|
lcb_settings *settings;
|
|
44
196
|
|
|
45
|
-
/* Defined in mcserver.c */
|
|
46
|
-
int state;
|
|
47
|
-
|
|
48
197
|
/** Whether compression is supported */
|
|
49
198
|
short compsupport;
|
|
50
199
|
|
|
51
200
|
/** Whether extended 'UUID' and 'seqno' are available for each mutation */
|
|
52
201
|
short mutation_tokens;
|
|
53
202
|
|
|
54
|
-
/** IO/Operation timer */
|
|
55
|
-
lcbio_pTIMER io_timer;
|
|
56
|
-
|
|
57
203
|
lcbio_CTX *connctx;
|
|
58
204
|
lcbio_CONNREQ connreq;
|
|
59
205
|
|
|
60
206
|
/** Request for current connection */
|
|
61
207
|
lcb_host_t *curhost;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
#define MCSERVER_TIMEOUT(c) (c)->settings->operation_timeout
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Allocate and initialize a new server object. The object will not be
|
|
68
|
-
* connected
|
|
69
|
-
* @param instance the instance to which the server belongs
|
|
70
|
-
* @param ix the server index in the configuration
|
|
71
|
-
* @return the new object or NULL on allocation failure.
|
|
72
|
-
*/
|
|
73
|
-
mc_SERVER *
|
|
74
|
-
mcserver_alloc(lcb_t instance, int ix);
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Close the server. The resources of the server may still continue to persist
|
|
78
|
-
* internally for a bit until all callbacks have been delivered and all buffers
|
|
79
|
-
* flushed and/or failed.
|
|
80
|
-
* @param server the server to release
|
|
81
|
-
*/
|
|
82
|
-
void
|
|
83
|
-
mcserver_close(mc_SERVER *server);
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Schedule a flush and potentially flush some immediate data on the server.
|
|
87
|
-
* This is safe to call multiple times, however performance considerations
|
|
88
|
-
* should be taken into account
|
|
89
|
-
*/
|
|
90
|
-
void
|
|
91
|
-
mcserver_flush(mc_SERVER *server);
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Wrapper around mcreq_pipeline_timeout() and/or mcreq_pipeline_fail(). This
|
|
95
|
-
* function will purge all pending requests within the server and invoke
|
|
96
|
-
* their callbacks with the given error code passed as `err`. Depending on
|
|
97
|
-
* the error code, some operations may be retried.
|
|
98
|
-
* @param server the server to fail
|
|
99
|
-
* @param err the error code by which to fail the commands
|
|
100
|
-
*
|
|
101
|
-
* @note This function does not modify the server's socket or state in itself,
|
|
102
|
-
* but rather simply wipes the commands from its queue
|
|
103
|
-
*/
|
|
104
|
-
void
|
|
105
|
-
mcserver_fail_chain(mc_SERVER *server, lcb_error_t err);
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Returns true or false depending on whether there are pending commands on
|
|
109
|
-
* this server
|
|
110
|
-
*/
|
|
111
|
-
LCB_INTERNAL_API
|
|
112
|
-
int
|
|
113
|
-
mcserver_has_pending(mc_SERVER *server);
|
|
114
|
-
|
|
115
|
-
#define mcserver_get_host(server) (server)->curhost->host
|
|
116
|
-
#define mcserver_get_port(server) (server)->curhost->port
|
|
117
|
-
|
|
118
|
-
#ifdef __cplusplus
|
|
208
|
+
};
|
|
119
209
|
}
|
|
120
210
|
#endif /* __cplusplus */
|
|
121
211
|
#endif /* LCB_MCSERVER_H */
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
#include <algorithm>
|
|
18
19
|
#include "packetutils.h"
|
|
19
20
|
#include "mcserver.h"
|
|
20
21
|
#include "logging.h"
|
|
@@ -26,47 +27,13 @@
|
|
|
26
27
|
#include "negotiate.h"
|
|
27
28
|
#include "ctx-log-inl.h"
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
#include <sstream>
|
|
31
|
-
#include <vector>
|
|
30
|
+
using namespace lcb;
|
|
32
31
|
|
|
33
|
-
#define LOGARGS(ctx, lvl) ctx->
|
|
34
|
-
static void cleanup_negotiated(
|
|
32
|
+
#define LOGARGS(ctx, lvl) ctx->settings, "negotiation", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
33
|
+
static void cleanup_negotiated(SessionInfo* info);
|
|
35
34
|
static void handle_ioerr(lcbio_CTX *ctx, lcb_error_t err);
|
|
36
|
-
static void handle_read(lcbio_CTX *ioctx, unsigned);
|
|
37
35
|
#define SESSREQ_LOGFMT "<%s:%s> (SASLREQ=%p) "
|
|
38
36
|
|
|
39
|
-
/**
|
|
40
|
-
* Inner negotiation structure which is maintained as part of a 'protocol
|
|
41
|
-
* context'.
|
|
42
|
-
*/
|
|
43
|
-
struct mc_SESSINFO : public lcbio_PROTOCTX {
|
|
44
|
-
union {
|
|
45
|
-
cbsasl_secret_t secret;
|
|
46
|
-
char buffer[256];
|
|
47
|
-
} u_auth;
|
|
48
|
-
|
|
49
|
-
static mc_SESSINFO *get(void *arg) {
|
|
50
|
-
return reinterpret_cast<mc_SESSINFO*>(arg);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
mc_SESSINFO(lcb_settings *settings_);
|
|
54
|
-
bool setup(const lcbio_NAMEINFO& nistrs, const lcb_host_t& host,
|
|
55
|
-
const lcb::Authenticator& auth);
|
|
56
|
-
|
|
57
|
-
~mc_SESSINFO() {
|
|
58
|
-
if (sasl_client != NULL) {
|
|
59
|
-
cbsasl_dispose(&sasl_client);
|
|
60
|
-
sasl_client = NULL;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
cbsasl_conn_t *sasl_client;
|
|
65
|
-
std::string mech;
|
|
66
|
-
std::vector<uint16_t> server_features;
|
|
67
|
-
lcb_settings *settings;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
37
|
static void timeout_handler(void *arg);
|
|
71
38
|
|
|
72
39
|
#define SESSREQ_LOGID(s) get_ctx_host(s->ctx), get_ctx_port(s->ctx), (void*)s
|
|
@@ -84,28 +51,37 @@ close_cb(lcbio_SOCKET *s, int reusable, void *arg)
|
|
|
84
51
|
* of the request for negotiation and is deleted once negotiation has
|
|
85
52
|
* completed (or failed).
|
|
86
53
|
*/
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
54
|
+
class lcb::SessionRequestImpl : public SessionRequest {
|
|
55
|
+
public:
|
|
56
|
+
static SessionRequestImpl *get(void *arg) {
|
|
57
|
+
return reinterpret_cast<SessionRequestImpl*>(arg);
|
|
90
58
|
}
|
|
91
59
|
|
|
92
|
-
|
|
60
|
+
bool setup(const lcbio_NAMEINFO& nistrs, const lcb_host_t& host,
|
|
61
|
+
const lcb::Authenticator& auth);
|
|
62
|
+
void start(lcbio_SOCKET *sock);
|
|
93
63
|
bool send_hello();
|
|
94
64
|
bool send_step(const lcb::MemcachedResponse& packet);
|
|
95
65
|
bool read_hello(const lcb::MemcachedResponse& packet);
|
|
66
|
+
void send_auth(const char *sasl_data, unsigned ndata);
|
|
67
|
+
void handle_read(lcbio_CTX *ioctx);
|
|
68
|
+
|
|
69
|
+
enum MechStatus { MECH_UNAVAILABLE, MECH_NOT_NEEDED, MECH_OK };
|
|
70
|
+
MechStatus set_chosen_mech(std::string& mechlist, const char **data, unsigned int *ndata);
|
|
96
71
|
|
|
97
|
-
|
|
98
|
-
lcbio_TABLE *iot)
|
|
72
|
+
SessionRequestImpl(lcbio_CONNDONE_cb callback, void *data, uint32_t timeout, lcbio_TABLE *iot, lcb_settings* settings_)
|
|
99
73
|
: ctx(NULL), cb(callback), cbdata(data),
|
|
100
74
|
timer(lcbio_timer_new(iot, this, timeout_handler)),
|
|
101
|
-
last_err(LCB_SUCCESS),
|
|
75
|
+
last_err(LCB_SUCCESS), info(NULL),
|
|
76
|
+
settings(settings_) {
|
|
102
77
|
|
|
103
78
|
if (timeout) {
|
|
104
79
|
lcbio_timer_rearm(timer, timeout);
|
|
105
80
|
}
|
|
81
|
+
memset(&u_auth, 0, sizeof(u_auth));
|
|
106
82
|
}
|
|
107
83
|
|
|
108
|
-
~
|
|
84
|
+
virtual ~SessionRequestImpl();
|
|
109
85
|
|
|
110
86
|
void cancel() {
|
|
111
87
|
cb = NULL;
|
|
@@ -132,8 +108,8 @@ struct mc_SESSREQ {
|
|
|
132
108
|
lcbio_ctx_close(ctx, close_cb, &s);
|
|
133
109
|
ctx = NULL;
|
|
134
110
|
|
|
135
|
-
lcbio_protoctx_add(s,
|
|
136
|
-
|
|
111
|
+
lcbio_protoctx_add(s, info);
|
|
112
|
+
info = NULL;
|
|
137
113
|
|
|
138
114
|
/** Invoke the callback, marking it a success */
|
|
139
115
|
cb(s, cbdata, LCB_SUCCESS, 0);
|
|
@@ -153,19 +129,29 @@ struct mc_SESSREQ {
|
|
|
153
129
|
return last_err != LCB_SUCCESS;
|
|
154
130
|
}
|
|
155
131
|
|
|
132
|
+
union {
|
|
133
|
+
cbsasl_secret_t secret;
|
|
134
|
+
char buffer[256];
|
|
135
|
+
} u_auth;
|
|
136
|
+
|
|
156
137
|
lcbio_CTX *ctx;
|
|
157
138
|
lcbio_CONNDONE_cb cb;
|
|
158
139
|
void *cbdata;
|
|
159
140
|
lcbio_pTIMER timer;
|
|
160
141
|
lcb_error_t last_err;
|
|
161
|
-
|
|
142
|
+
cbsasl_conn_t *sasl_client;
|
|
143
|
+
SessionInfo* info;
|
|
144
|
+
lcb_settings *settings;
|
|
162
145
|
};
|
|
163
146
|
|
|
147
|
+
static void handle_read(lcbio_CTX *ioctx, unsigned) {
|
|
148
|
+
SessionRequestImpl::get(lcbio_ctx_data(ioctx))->handle_read(ioctx);
|
|
149
|
+
}
|
|
164
150
|
|
|
165
151
|
static int
|
|
166
152
|
sasl_get_username(void *context, int id, const char **result, unsigned int *len)
|
|
167
153
|
{
|
|
168
|
-
|
|
154
|
+
SessionRequestImpl *ctx = SessionRequestImpl::get(context);
|
|
169
155
|
const char *u = NULL, *p = NULL;
|
|
170
156
|
if (!context || !result || (id != CBSASL_CB_USER && id != CBSASL_CB_AUTHNAME)) {
|
|
171
157
|
return SASL_BADPARAM;
|
|
@@ -184,7 +170,7 @@ static int
|
|
|
184
170
|
sasl_get_password(cbsasl_conn_t *conn, void *context, int id,
|
|
185
171
|
cbsasl_secret_t **psecret)
|
|
186
172
|
{
|
|
187
|
-
|
|
173
|
+
SessionRequestImpl *ctx = SessionRequestImpl::get(context);
|
|
188
174
|
if (!conn || ! psecret || id != CBSASL_CB_PASS || ctx == NULL) {
|
|
189
175
|
return SASL_BADPARAM;
|
|
190
176
|
}
|
|
@@ -193,19 +179,14 @@ sasl_get_password(cbsasl_conn_t *conn, void *context, int id,
|
|
|
193
179
|
return SASL_OK;
|
|
194
180
|
}
|
|
195
181
|
|
|
196
|
-
|
|
182
|
+
SessionInfo::SessionInfo()
|
|
197
183
|
{
|
|
198
|
-
sasl_client = NULL;
|
|
199
|
-
memset(&u_auth, 0, sizeof(u_auth));
|
|
200
|
-
|
|
201
184
|
lcbio_PROTOCTX::id = LCBIO_PROTOCTX_SESSINFO;
|
|
202
|
-
lcbio_PROTOCTX::dtor = (void (*)(
|
|
203
|
-
|
|
204
|
-
settings = settings_;
|
|
185
|
+
lcbio_PROTOCTX::dtor = (void (*)(lcbio_PROTOCTX *))cleanup_negotiated;
|
|
205
186
|
}
|
|
206
187
|
|
|
207
188
|
bool
|
|
208
|
-
|
|
189
|
+
SessionRequestImpl::setup(const lcbio_NAMEINFO& nistrs, const lcb_host_t& host,
|
|
209
190
|
const lcb::Authenticator& auth)
|
|
210
191
|
{
|
|
211
192
|
cbsasl_callback_t sasl_callbacks[4];
|
|
@@ -251,7 +232,7 @@ mc_SESSINFO::setup(const lcbio_NAMEINFO& nistrs, const lcb_host_t& host,
|
|
|
251
232
|
static void
|
|
252
233
|
timeout_handler(void *arg)
|
|
253
234
|
{
|
|
254
|
-
|
|
235
|
+
SessionRequestImpl *sreq = SessionRequestImpl::get(arg);
|
|
255
236
|
sreq->fail(LCB_ETIMEDOUT, "Negotiation timed out");
|
|
256
237
|
}
|
|
257
238
|
|
|
@@ -260,66 +241,62 @@ timeout_handler(void *arg)
|
|
|
260
241
|
* @return 0 to continue authentication, 1 if no authentication needed, or
|
|
261
242
|
* -1 on error.
|
|
262
243
|
*/
|
|
263
|
-
|
|
264
|
-
set_chosen_mech(
|
|
244
|
+
SessionRequestImpl::MechStatus
|
|
245
|
+
SessionRequestImpl::set_chosen_mech(std::string& mechlist,
|
|
265
246
|
const char **data, unsigned int *ndata)
|
|
266
247
|
{
|
|
267
248
|
cbsasl_error_t saslerr;
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (ctx->settings->sasl_mech_force) {
|
|
271
|
-
char *forcemech = ctx->settings->sasl_mech_force;
|
|
249
|
+
if (settings->sasl_mech_force) {
|
|
250
|
+
char *forcemech = settings->sasl_mech_force;
|
|
272
251
|
if (mechlist.find(forcemech) == std::string::npos) {
|
|
273
252
|
/** Requested mechanism not found */
|
|
274
|
-
|
|
275
|
-
return
|
|
253
|
+
set_error(LCB_SASLMECH_UNAVAILABLE, mechlist.c_str());
|
|
254
|
+
return MECH_UNAVAILABLE;
|
|
276
255
|
}
|
|
277
256
|
mechlist.assign(forcemech);
|
|
278
257
|
}
|
|
279
258
|
|
|
280
259
|
const char *chosenmech;
|
|
281
|
-
saslerr = cbsasl_client_start(
|
|
260
|
+
saslerr = cbsasl_client_start(sasl_client, mechlist.c_str(),
|
|
282
261
|
NULL, data, ndata, &chosenmech);
|
|
283
262
|
switch (saslerr) {
|
|
284
263
|
case SASL_OK:
|
|
285
|
-
|
|
286
|
-
return
|
|
264
|
+
info->mech.assign(chosenmech);
|
|
265
|
+
return MECH_OK;
|
|
287
266
|
case SASL_NOMECH:
|
|
288
|
-
lcb_log(LOGARGS(
|
|
289
|
-
return
|
|
267
|
+
lcb_log(LOGARGS(this, INFO), SESSREQ_LOGFMT "Server does not support SASL (no mechanisms supported)", SESSREQ_LOGID(this));
|
|
268
|
+
return MECH_NOT_NEEDED;
|
|
290
269
|
break;
|
|
291
270
|
default:
|
|
292
|
-
lcb_log(LOGARGS(
|
|
293
|
-
|
|
294
|
-
return
|
|
271
|
+
lcb_log(LOGARGS(this, INFO), SESSREQ_LOGFMT "cbsasl_client_start returned %d", SESSREQ_LOGID(this), saslerr);
|
|
272
|
+
set_error(LCB_EINTERNAL, "Couldn't start SASL client");
|
|
273
|
+
return MECH_UNAVAILABLE;
|
|
295
274
|
}
|
|
296
275
|
}
|
|
297
276
|
|
|
298
277
|
/**
|
|
299
278
|
* Given the specific mechanisms, send the auth packet to the server.
|
|
300
279
|
*/
|
|
301
|
-
|
|
302
|
-
|
|
280
|
+
void
|
|
281
|
+
SessionRequestImpl::send_auth(const char *sasl_data, unsigned ndata)
|
|
303
282
|
{
|
|
304
|
-
mc_pSESSINFO ctx = pend->sasl;
|
|
305
283
|
lcb::MemcachedRequest hdr(PROTOCOL_BINARY_CMD_SASL_AUTH);
|
|
306
|
-
hdr.sizes(0,
|
|
284
|
+
hdr.sizes(0, info->mech.size(), ndata);
|
|
307
285
|
|
|
308
|
-
lcbio_ctx_put(
|
|
309
|
-
lcbio_ctx_put(
|
|
310
|
-
lcbio_ctx_put(
|
|
311
|
-
lcbio_ctx_rwant(
|
|
312
|
-
return 0;
|
|
286
|
+
lcbio_ctx_put(ctx, hdr.data(), hdr.size());
|
|
287
|
+
lcbio_ctx_put(ctx, info->mech.c_str(), info->mech.size());
|
|
288
|
+
lcbio_ctx_put(ctx, sasl_data, ndata);
|
|
289
|
+
lcbio_ctx_rwant(ctx, 24);
|
|
313
290
|
}
|
|
314
291
|
|
|
315
292
|
bool
|
|
316
|
-
|
|
293
|
+
SessionRequestImpl::send_step(const lcb::MemcachedResponse& packet)
|
|
317
294
|
{
|
|
318
295
|
cbsasl_error_t saslerr;
|
|
319
296
|
const char *step_data;
|
|
320
297
|
unsigned int ndata;
|
|
321
298
|
|
|
322
|
-
saslerr = cbsasl_client_step(
|
|
299
|
+
saslerr = cbsasl_client_step(sasl_client,
|
|
323
300
|
packet.body<const char*>(), packet.bodylen(), NULL, &step_data, &ndata);
|
|
324
301
|
|
|
325
302
|
if (saslerr != SASL_CONTINUE) {
|
|
@@ -328,9 +305,9 @@ mc_SESSREQ::send_step(const lcb::MemcachedResponse& packet)
|
|
|
328
305
|
}
|
|
329
306
|
|
|
330
307
|
lcb::MemcachedRequest hdr(PROTOCOL_BINARY_CMD_SASL_STEP);
|
|
331
|
-
hdr.sizes(0,
|
|
308
|
+
hdr.sizes(0, info->mech.size(), ndata);
|
|
332
309
|
lcbio_ctx_put(ctx, hdr.data(), hdr.size());
|
|
333
|
-
lcbio_ctx_put(ctx,
|
|
310
|
+
lcbio_ctx_put(ctx, info->mech.c_str(), info->mech.size());
|
|
334
311
|
lcbio_ctx_put(ctx, step_data, ndata);
|
|
335
312
|
lcbio_ctx_rwant(ctx, 24);
|
|
336
313
|
return true;
|
|
@@ -340,13 +317,13 @@ mc_SESSREQ::send_step(const lcb::MemcachedResponse& packet)
|
|
|
340
317
|
#define LCB_HELLO_DEFL_LENGTH (sizeof(LCB_HELLO_DEFL_STRING)-1)
|
|
341
318
|
|
|
342
319
|
bool
|
|
343
|
-
|
|
320
|
+
SessionRequestImpl::send_hello()
|
|
344
321
|
{
|
|
345
|
-
const lcb_settings *settings = sasl->settings;
|
|
346
322
|
lcb_U16 features[MEMCACHED_TOTAL_HELLO_FEATURES];
|
|
347
323
|
|
|
348
324
|
unsigned nfeatures = 0;
|
|
349
325
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TLS;
|
|
326
|
+
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XATTR;
|
|
350
327
|
if (settings->tcp_nodelay) {
|
|
351
328
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TCPNODELAY;
|
|
352
329
|
}
|
|
@@ -388,7 +365,7 @@ mc_SESSREQ::send_hello()
|
|
|
388
365
|
}
|
|
389
366
|
|
|
390
367
|
bool
|
|
391
|
-
|
|
368
|
+
SessionRequestImpl::read_hello(const lcb::MemcachedResponse& resp)
|
|
392
369
|
{
|
|
393
370
|
/* some caps */
|
|
394
371
|
const char *cur;
|
|
@@ -398,8 +375,8 @@ mc_SESSREQ::read_hello(const lcb::MemcachedResponse& resp)
|
|
|
398
375
|
lcb_U16 tmp;
|
|
399
376
|
memcpy(&tmp, cur, sizeof(tmp));
|
|
400
377
|
tmp = ntohs(tmp);
|
|
401
|
-
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "
|
|
402
|
-
|
|
378
|
+
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server supports feature: 0x%x (%s)", SESSREQ_LOGID(this), tmp, protocol_feature_2_text(tmp));
|
|
379
|
+
info->server_features.push_back(tmp);
|
|
403
380
|
}
|
|
404
381
|
return true;
|
|
405
382
|
}
|
|
@@ -415,10 +392,9 @@ typedef enum {
|
|
|
415
392
|
* It's assumed the server buffers will be reset upon close(), so we must make
|
|
416
393
|
* sure to _not_ release the ringbuffer if that happens.
|
|
417
394
|
*/
|
|
418
|
-
|
|
419
|
-
handle_read(lcbio_CTX *ioctx
|
|
395
|
+
void
|
|
396
|
+
SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
420
397
|
{
|
|
421
|
-
mc_pSESSREQ sreq = mc_SESSREQ::get(lcbio_ctx_data(ioctx));
|
|
422
398
|
lcb::MemcachedResponse resp;
|
|
423
399
|
unsigned required;
|
|
424
400
|
sreq_STATE state = SREQ_S_WAIT;
|
|
@@ -433,20 +409,15 @@ handle_read(lcbio_CTX *ioctx, unsigned)
|
|
|
433
409
|
|
|
434
410
|
switch (resp.opcode()) {
|
|
435
411
|
case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS: {
|
|
436
|
-
int mechrc;
|
|
437
412
|
const char *mechlist_data;
|
|
438
413
|
unsigned int nmechlist_data;
|
|
439
414
|
std::string mechs(resp.body<const char*>(), resp.bodylen());
|
|
440
415
|
|
|
441
|
-
mechrc = set_chosen_mech(
|
|
442
|
-
if (mechrc ==
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
state = SREQ_S_ERROR;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
} else if (mechrc < 0) {
|
|
416
|
+
MechStatus mechrc = set_chosen_mech(mechs, &mechlist_data, &nmechlist_data);
|
|
417
|
+
if (mechrc == MECH_OK) {
|
|
418
|
+
send_auth(mechlist_data, nmechlist_data);
|
|
419
|
+
state = SREQ_S_WAIT;
|
|
420
|
+
} else if (mechrc == MECH_UNAVAILABLE) {
|
|
450
421
|
state = SREQ_S_ERROR;
|
|
451
422
|
} else {
|
|
452
423
|
state = SREQ_S_HELLODONE;
|
|
@@ -456,17 +427,17 @@ handle_read(lcbio_CTX *ioctx, unsigned)
|
|
|
456
427
|
|
|
457
428
|
case PROTOCOL_BINARY_CMD_SASL_AUTH: {
|
|
458
429
|
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
459
|
-
|
|
430
|
+
send_hello();
|
|
460
431
|
state = SREQ_S_AUTHDONE;
|
|
461
432
|
break;
|
|
462
433
|
}
|
|
463
434
|
|
|
464
435
|
if (status != PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE) {
|
|
465
|
-
|
|
436
|
+
set_error(LCB_AUTH_ERROR, "SASL AUTH failed");
|
|
466
437
|
state = SREQ_S_ERROR;
|
|
467
438
|
break;
|
|
468
439
|
}
|
|
469
|
-
if (
|
|
440
|
+
if (send_step(resp) && send_hello()) {
|
|
470
441
|
state = SREQ_S_WAIT;
|
|
471
442
|
} else {
|
|
472
443
|
state = SREQ_S_ERROR;
|
|
@@ -476,8 +447,8 @@ handle_read(lcbio_CTX *ioctx, unsigned)
|
|
|
476
447
|
|
|
477
448
|
case PROTOCOL_BINARY_CMD_SASL_STEP: {
|
|
478
449
|
if (status != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
479
|
-
lcb_log(LOGARGS(
|
|
480
|
-
|
|
450
|
+
lcb_log(LOGARGS(this, WARN), SESSREQ_LOGFMT "SASL auth failed with STATUS=0x%x", SESSREQ_LOGID(this), status);
|
|
451
|
+
set_error(LCB_AUTH_ERROR, "SASL Step Failed");
|
|
481
452
|
state = SREQ_S_ERROR;
|
|
482
453
|
} else {
|
|
483
454
|
/* Wait for pipelined HELLO response */
|
|
@@ -489,15 +460,15 @@ handle_read(lcbio_CTX *ioctx, unsigned)
|
|
|
489
460
|
case PROTOCOL_BINARY_CMD_HELLO: {
|
|
490
461
|
state = SREQ_S_HELLODONE;
|
|
491
462
|
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
492
|
-
if (!
|
|
493
|
-
|
|
463
|
+
if (!read_hello(resp)) {
|
|
464
|
+
set_error(LCB_PROTOCOL_ERROR, "Couldn't parse HELLO");
|
|
494
465
|
}
|
|
495
466
|
} else if (status == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND ||
|
|
496
467
|
status == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED) {
|
|
497
|
-
lcb_log(LOGARGS(
|
|
468
|
+
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server does not support HELLO", SESSREQ_LOGID(this));
|
|
498
469
|
/* nothing */
|
|
499
470
|
} else {
|
|
500
|
-
|
|
471
|
+
set_error(LCB_PROTOCOL_ERROR, "Hello response unexpected");
|
|
501
472
|
state = SREQ_S_ERROR;
|
|
502
473
|
}
|
|
503
474
|
break;
|
|
@@ -505,8 +476,8 @@ handle_read(lcbio_CTX *ioctx, unsigned)
|
|
|
505
476
|
|
|
506
477
|
default: {
|
|
507
478
|
state = SREQ_S_ERROR;
|
|
508
|
-
lcb_log(LOGARGS(
|
|
509
|
-
|
|
479
|
+
lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Received unknown response. OP=0x%x. RC=0x%x", SESSREQ_LOGID(this), resp.opcode(), resp.status());
|
|
480
|
+
set_error(LCB_NOT_SUPPORTED, "Received unknown response");
|
|
510
481
|
break;
|
|
511
482
|
}
|
|
512
483
|
}
|
|
@@ -517,12 +488,12 @@ handle_read(lcbio_CTX *ioctx, unsigned)
|
|
|
517
488
|
|
|
518
489
|
// Once there is no more any dependencies on the buffers, we can succeed
|
|
519
490
|
// or fail the request, potentially destroying the underlying connection
|
|
520
|
-
if (
|
|
521
|
-
|
|
491
|
+
if (has_error()) {
|
|
492
|
+
fail();
|
|
522
493
|
} else if (state == SREQ_S_ERROR) {
|
|
523
|
-
|
|
494
|
+
fail(LCB_ERROR, "FIXME: Error code set without description");
|
|
524
495
|
} else if (state == SREQ_S_HELLODONE) {
|
|
525
|
-
|
|
496
|
+
success();
|
|
526
497
|
} else {
|
|
527
498
|
goto GT_NEXT_PACKET;
|
|
528
499
|
}
|
|
@@ -531,17 +502,17 @@ handle_read(lcbio_CTX *ioctx, unsigned)
|
|
|
531
502
|
static void
|
|
532
503
|
handle_ioerr(lcbio_CTX *ctx, lcb_error_t err)
|
|
533
504
|
{
|
|
534
|
-
|
|
505
|
+
SessionRequestImpl* sreq = SessionRequestImpl::get(lcbio_ctx_data(ctx));
|
|
535
506
|
sreq->fail(err, "IO Error");
|
|
536
507
|
}
|
|
537
508
|
|
|
538
|
-
static void cleanup_negotiated(
|
|
509
|
+
static void cleanup_negotiated(SessionInfo* ctx) {
|
|
539
510
|
delete ctx;
|
|
540
511
|
}
|
|
541
512
|
|
|
542
513
|
void
|
|
543
|
-
|
|
544
|
-
|
|
514
|
+
SessionRequestImpl::start(lcbio_SOCKET *sock) {
|
|
515
|
+
info = new SessionInfo();
|
|
545
516
|
|
|
546
517
|
lcb_error_t err = lcbio_sslify_if_needed(sock, settings);
|
|
547
518
|
if (err != LCB_SUCCESS) {
|
|
@@ -551,16 +522,16 @@ mc_SESSREQ::start(lcbio_SOCKET *sock, lcb_settings *settings) {
|
|
|
551
522
|
}
|
|
552
523
|
|
|
553
524
|
lcbio_CTXPROCS procs;
|
|
554
|
-
procs.cb_err = handle_ioerr;
|
|
555
|
-
procs.cb_read = handle_read;
|
|
525
|
+
procs.cb_err = ::handle_ioerr;
|
|
526
|
+
procs.cb_read = ::handle_read;
|
|
556
527
|
ctx = lcbio_ctx_new(sock, this, &procs);
|
|
557
528
|
ctx->subsys = "sasl";
|
|
558
529
|
|
|
559
530
|
const lcb_host_t *curhost = lcbio_get_host(sock);
|
|
560
|
-
|
|
531
|
+
lcbio_NAMEINFO nistrs;
|
|
561
532
|
lcbio_get_nameinfo(sock, &nistrs);
|
|
562
533
|
|
|
563
|
-
if (!
|
|
534
|
+
if (!setup(nistrs, *curhost, *settings->auth)) {
|
|
564
535
|
set_error(LCB_EINTERNAL, "Couldn't start SASL client");
|
|
565
536
|
lcbio_async_signal(timer);
|
|
566
537
|
return;
|
|
@@ -571,11 +542,10 @@ mc_SESSREQ::start(lcbio_SOCKET *sock, lcb_settings *settings) {
|
|
|
571
542
|
LCBIO_CTX_RSCHEDULE(ctx, 24);
|
|
572
543
|
}
|
|
573
544
|
|
|
574
|
-
|
|
575
|
-
mc_SESSREQ::~mc_SESSREQ()
|
|
545
|
+
SessionRequestImpl::~SessionRequestImpl()
|
|
576
546
|
{
|
|
577
|
-
if (
|
|
578
|
-
delete
|
|
547
|
+
if (info) {
|
|
548
|
+
delete info;
|
|
579
549
|
}
|
|
580
550
|
if (timer) {
|
|
581
551
|
lcbio_timer_destroy(timer);
|
|
@@ -583,35 +553,31 @@ mc_SESSREQ::~mc_SESSREQ()
|
|
|
583
553
|
if (ctx) {
|
|
584
554
|
lcbio_ctx_close(ctx, NULL, NULL);
|
|
585
555
|
}
|
|
556
|
+
if (sasl_client) {
|
|
557
|
+
cbsasl_dispose(&sasl_client);
|
|
558
|
+
}
|
|
586
559
|
}
|
|
587
560
|
|
|
588
|
-
void
|
|
561
|
+
void lcb::sessreq_cancel(SessionRequest *sreq) {
|
|
589
562
|
sreq->cancel();
|
|
590
563
|
}
|
|
591
564
|
|
|
592
|
-
|
|
593
|
-
|
|
565
|
+
SessionRequest *
|
|
566
|
+
SessionRequest::start(lcbio_SOCKET *sock, lcb_settings_st *settings,
|
|
594
567
|
uint32_t tmo, lcbio_CONNDONE_cb callback, void *data)
|
|
595
568
|
{
|
|
596
|
-
|
|
597
|
-
sreq->start(sock
|
|
569
|
+
SessionRequestImpl* sreq = new SessionRequestImpl(callback, data, tmo, sock->io, settings);
|
|
570
|
+
sreq->start(sock);
|
|
598
571
|
return sreq;
|
|
599
572
|
}
|
|
600
573
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
const char *mc_sess_get_saslmech(mc_pSESSINFO info) {
|
|
607
|
-
return info->mech.c_str();
|
|
574
|
+
SessionInfo*
|
|
575
|
+
SessionInfo::get(lcbio_SOCKET *sock) {
|
|
576
|
+
return static_cast<SessionInfo*>(lcbio_protoctx_get(sock, LCBIO_PROTOCTX_SESSINFO));
|
|
608
577
|
}
|
|
609
578
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
return 0;
|
|
579
|
+
bool
|
|
580
|
+
SessionInfo::has_feature(uint16_t feature) const {
|
|
581
|
+
return std::find(server_features.begin(), server_features.end(), feature)
|
|
582
|
+
!= server_features.end();
|
|
617
583
|
}
|