libcouchbase 0.3.3 → 1.0.0
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/CMakeLists.txt +6 -8
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +21 -5
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
- data/ext/libcouchbase/example/users/README +48 -0
- data/ext/libcouchbase/example/users/users.c +147 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
- data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
- data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
- 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 +24 -1146
- 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 +23 -4
- data/ext/libcouchbase/src/auth.cc +51 -43
- data/ext/libcouchbase/src/bootstrap.cc +244 -0
- data/ext/libcouchbase/src/bootstrap.h +58 -38
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +56 -22
- data/ext/libcouchbase/src/connspec.cc +47 -6
- data/ext/libcouchbase/src/connspec.h +27 -0
- data/ext/libcouchbase/src/dns-srv.cc +147 -0
- data/ext/libcouchbase/src/dump.cc +3 -3
- data/ext/libcouchbase/src/errmap.cc +173 -0
- data/ext/libcouchbase/src/errmap.h +198 -0
- data/ext/libcouchbase/src/getconfig.cc +7 -33
- data/ext/libcouchbase/src/handler.cc +118 -7
- data/ext/libcouchbase/src/hostlist.cc +0 -36
- data/ext/libcouchbase/src/hostlist.h +44 -62
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +27 -35
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +28 -36
- data/ext/libcouchbase/src/instance.cc +131 -34
- data/ext/libcouchbase/src/internal.h +58 -26
- data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
- data/ext/libcouchbase/src/jsparse/parser.h +84 -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 +569 -0
- data/ext/libcouchbase/src/lcbio/connect.h +16 -7
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
- data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
- data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
- data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
- data/ext/libcouchbase/src/lcbio/manager.h +133 -96
- data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.c +11 -2
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
- data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
- data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
- 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 +74 -42
- data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- 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.cc +6 -26
- data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
- 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.cc +3 -8
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +30 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/rdb/rope.c +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
- data/ext/libcouchbase/src/retryq.cc +52 -14
- data/ext/libcouchbase/src/retryq.h +3 -3
- data/ext/libcouchbase/src/settings.c +5 -0
- data/ext/libcouchbase/src/settings.h +11 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
- 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/tests/basic/t_connstr.cc +88 -50
- data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
- data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
- data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
- data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
- data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
- data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
- data/ext/libcouchbase/tools/cbc.cc +143 -10
- data/ext/libcouchbase/tools/docgen/loc.h +1 -1
- data/lib/libcouchbase/connection.rb +4 -3
- data/lib/libcouchbase/version.rb +1 -1
- metadata +37 -28
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- 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/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/lcbio/manager.c +0 -584
- data/ext/libcouchbase/src/packetutils.c +0 -37
- 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
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2014 Couchbase, Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
#include "lcbht.h"
|
|
19
|
-
#include "sllist-inl.h"
|
|
20
|
-
#include "contrib/http_parser/http_parser.h"
|
|
21
|
-
#include "settings.h"
|
|
22
|
-
enum last_call_type {
|
|
23
|
-
CB_NONE,
|
|
24
|
-
CB_HDR_KEY,
|
|
25
|
-
CB_HDR_VALUE,
|
|
26
|
-
CB_HDR_DONE,
|
|
27
|
-
CB_BODY,
|
|
28
|
-
CB_MSG_DONE
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
struct lcbht_PARSER {
|
|
32
|
-
http_parser parser;
|
|
33
|
-
lcbht_RESPONSE resp; /**< Current response being processed */
|
|
34
|
-
lcb_settings *settings;
|
|
35
|
-
enum last_call_type lastcall;
|
|
36
|
-
|
|
37
|
-
/* this stuff for parse_ex() */
|
|
38
|
-
const char *last_body;
|
|
39
|
-
unsigned last_bodylen;
|
|
40
|
-
char paused;
|
|
41
|
-
char is_ex;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
static int
|
|
45
|
-
on_hdr_key(http_parser *pb, const char *s, size_t n)
|
|
46
|
-
{
|
|
47
|
-
lcbht_pPARSER p = (void *)pb;
|
|
48
|
-
lcbht_MIMEHDR *hdr;
|
|
49
|
-
lcbht_RESPONSE *resp = &p->resp;
|
|
50
|
-
|
|
51
|
-
if (p->lastcall != CB_HDR_KEY) {
|
|
52
|
-
/* new key */
|
|
53
|
-
hdr = calloc(1, sizeof *hdr);
|
|
54
|
-
sllist_append(&resp->headers, &hdr->slnode);
|
|
55
|
-
lcb_string_init(&hdr->buf_);
|
|
56
|
-
} else {
|
|
57
|
-
hdr = SLLIST_ITEM(resp->headers.last, lcbht_MIMEHDR, slnode);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/* append key data */
|
|
61
|
-
lcb_string_append(&hdr->buf_, s, n);
|
|
62
|
-
p->lastcall = CB_HDR_KEY;
|
|
63
|
-
return 0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
static int
|
|
67
|
-
on_hdr_value(http_parser *pb, const char *s, size_t n)
|
|
68
|
-
{
|
|
69
|
-
lcbht_pPARSER p = (void *)pb;
|
|
70
|
-
lcbht_MIMEHDR *hdr;
|
|
71
|
-
lcbht_RESPONSE *resp = &p->resp;
|
|
72
|
-
|
|
73
|
-
hdr = SLLIST_ITEM(resp->headers.last, lcbht_MIMEHDR, slnode);
|
|
74
|
-
if (p->lastcall == CB_HDR_KEY) {
|
|
75
|
-
lcb_string_appendz(&hdr->buf_, ":");
|
|
76
|
-
}
|
|
77
|
-
lcb_string_append(&hdr->buf_, s, n);
|
|
78
|
-
p->lastcall = CB_HDR_VALUE;
|
|
79
|
-
return 0;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
static int
|
|
83
|
-
on_hdr_done(http_parser *pb)
|
|
84
|
-
{
|
|
85
|
-
lcbht_pPARSER p = (void *)pb;
|
|
86
|
-
lcbht_RESPONSE *resp = &p->resp;
|
|
87
|
-
sllist_iterator iter;
|
|
88
|
-
resp->state |= LCBHT_S_HTSTATUS|LCBHT_S_HEADER;
|
|
89
|
-
|
|
90
|
-
/* extract the status */
|
|
91
|
-
resp->status = pb->status_code;
|
|
92
|
-
p->lastcall = CB_HDR_DONE;
|
|
93
|
-
|
|
94
|
-
/** Iterate through all the headers and do proper formatting */
|
|
95
|
-
SLLIST_ITERFOR(&resp->headers, &iter) {
|
|
96
|
-
char *delim;
|
|
97
|
-
lcbht_MIMEHDR *hdr = SLLIST_ITEM(iter.cur, lcbht_MIMEHDR, slnode);
|
|
98
|
-
|
|
99
|
-
delim = strstr(hdr->buf_.base, ":");
|
|
100
|
-
hdr->key = hdr->buf_.base;
|
|
101
|
-
|
|
102
|
-
if (delim) {
|
|
103
|
-
*delim = '\0';
|
|
104
|
-
hdr->value = delim + 1;
|
|
105
|
-
} else {
|
|
106
|
-
hdr->value = "";
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return 0;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
static int
|
|
113
|
-
on_body(http_parser *pb, const char *s, size_t n)
|
|
114
|
-
{
|
|
115
|
-
lcbht_pPARSER p = (void *)pb;
|
|
116
|
-
lcbht_RESPONSE *resp = &p->resp;
|
|
117
|
-
if (p->is_ex) {
|
|
118
|
-
p->last_body = s;
|
|
119
|
-
p->last_bodylen = n;
|
|
120
|
-
p->paused = 1;
|
|
121
|
-
_lcb_http_parser_pause(pb, 1);
|
|
122
|
-
} else {
|
|
123
|
-
lcb_string_append(&resp->body, s, n);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
p->lastcall = CB_BODY;
|
|
127
|
-
resp->state |= LCBHT_S_BODY;
|
|
128
|
-
return 0;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
static int
|
|
132
|
-
on_msg_done(http_parser *pb)
|
|
133
|
-
{
|
|
134
|
-
lcbht_pPARSER p = (void *)pb;
|
|
135
|
-
lcbht_RESPONSE *resp = &p->resp;
|
|
136
|
-
resp->state |= LCBHT_S_DONE;
|
|
137
|
-
return 0;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
static struct http_parser_settings Parser_Settings = {
|
|
142
|
-
NULL, /* msg_begin */
|
|
143
|
-
NULL, /* on_url */
|
|
144
|
-
on_hdr_key,
|
|
145
|
-
on_hdr_value,
|
|
146
|
-
on_hdr_done,
|
|
147
|
-
on_body,
|
|
148
|
-
on_msg_done
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
lcbht_pPARSER
|
|
152
|
-
lcbht_new(lcb_settings *settings)
|
|
153
|
-
{
|
|
154
|
-
lcbht_pPARSER ret = calloc(1, sizeof *ret);
|
|
155
|
-
lcbht_reset(ret);
|
|
156
|
-
ret->settings = settings;
|
|
157
|
-
lcb_settings_ref(settings);
|
|
158
|
-
return ret;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
void
|
|
162
|
-
lcbht_free(lcbht_pPARSER parser)
|
|
163
|
-
{
|
|
164
|
-
lcbht_clear_response(&parser->resp);
|
|
165
|
-
lcb_settings_unref(parser->settings);
|
|
166
|
-
free(parser);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
lcbht_RESPSTATE
|
|
170
|
-
lcbht_parse(lcbht_pPARSER parser, const void *data, unsigned ndata)
|
|
171
|
-
{
|
|
172
|
-
size_t nb;
|
|
173
|
-
parser->is_ex = 0;
|
|
174
|
-
nb = _lcb_http_parser_execute(&parser->parser, &Parser_Settings, data, ndata);
|
|
175
|
-
if (nb != ndata) {
|
|
176
|
-
parser->resp.state |= LCBHT_S_ERROR;
|
|
177
|
-
}
|
|
178
|
-
return parser->resp.state;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
lcbht_RESPSTATE
|
|
182
|
-
lcbht_parse_ex(lcbht_pPARSER parser, const void *data, unsigned ndata,
|
|
183
|
-
unsigned *nused, unsigned *nbody, const char **pbody)
|
|
184
|
-
{
|
|
185
|
-
size_t nb;
|
|
186
|
-
parser->is_ex = 1;
|
|
187
|
-
nb = _lcb_http_parser_execute(&parser->parser, &Parser_Settings, data, ndata);
|
|
188
|
-
if (nb != ndata) {
|
|
189
|
-
if (parser->paused) {
|
|
190
|
-
_lcb_http_parser_pause(&parser->parser, 0);
|
|
191
|
-
parser->paused = 0;
|
|
192
|
-
} else {
|
|
193
|
-
parser->resp.state |= LCBHT_S_ERROR;
|
|
194
|
-
return parser->resp.state;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
*nused = nb;
|
|
199
|
-
*nbody = parser->last_bodylen;
|
|
200
|
-
*pbody = parser->last_body;
|
|
201
|
-
|
|
202
|
-
parser->last_body = NULL;
|
|
203
|
-
parser->last_bodylen = 0;
|
|
204
|
-
return parser->resp.state;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
lcbht_RESPONSE *
|
|
208
|
-
lcbht_get_response(lcbht_pPARSER parser)
|
|
209
|
-
{
|
|
210
|
-
return &parser->resp;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
int
|
|
214
|
-
lcbht_can_keepalive(lcbht_pPARSER parser)
|
|
215
|
-
{
|
|
216
|
-
if (!(parser->resp.state & LCBHT_S_DONE)) {
|
|
217
|
-
return 0;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (parser->resp.state & LCBHT_S_ERROR) {
|
|
221
|
-
return 0;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return _lcb_http_should_keep_alive(&parser->parser);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
void
|
|
228
|
-
lcbht_clear_response(lcbht_RESPONSE *resp)
|
|
229
|
-
{
|
|
230
|
-
sllist_iterator iter;
|
|
231
|
-
SLLIST_ITERFOR(&resp->headers, &iter) {
|
|
232
|
-
lcbht_MIMEHDR *hdr = SLLIST_ITEM(iter.cur, lcbht_MIMEHDR, slnode);
|
|
233
|
-
lcb_string_release(&hdr->buf_);
|
|
234
|
-
sllist_iter_remove(&resp->headers, &iter);
|
|
235
|
-
free(hdr);
|
|
236
|
-
}
|
|
237
|
-
lcb_string_release(&resp->body);
|
|
238
|
-
resp->state = 0;
|
|
239
|
-
resp->status = 0;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
void
|
|
243
|
-
lcbht_reset(lcbht_pPARSER parser)
|
|
244
|
-
{
|
|
245
|
-
lcbht_clear_response(&parser->resp);
|
|
246
|
-
_lcb_http_parser_init(&parser->parser, HTTP_RESPONSE);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const char *
|
|
250
|
-
lcbht_get_resphdr(const lcbht_RESPONSE *resp, const char *key)
|
|
251
|
-
{
|
|
252
|
-
sllist_node *curnode;
|
|
253
|
-
SLLIST_ITERBASIC(&resp->headers, curnode) {
|
|
254
|
-
lcbht_MIMEHDR *hdr = SLLIST_ITEM(curnode, lcbht_MIMEHDR, slnode);
|
|
255
|
-
if (!strcmp(hdr->key, key)) {
|
|
256
|
-
return hdr->value;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return NULL;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
char **
|
|
263
|
-
lcbht_make_resphdrlist(lcbht_RESPONSE *response)
|
|
264
|
-
{
|
|
265
|
-
char **ret;
|
|
266
|
-
unsigned nhdrs = 0;
|
|
267
|
-
unsigned curix = 0;
|
|
268
|
-
sllist_node *curnode;
|
|
269
|
-
SLLIST_ITERBASIC(&response->headers, curnode) {
|
|
270
|
-
nhdrs++;
|
|
271
|
-
}
|
|
272
|
-
ret = malloc(sizeof(*ret) * (nhdrs + 1) * 2);
|
|
273
|
-
|
|
274
|
-
SLLIST_ITERBASIC(&response->headers, curnode) {
|
|
275
|
-
lcbht_MIMEHDR *hdr = SLLIST_ITEM(curnode, lcbht_MIMEHDR, slnode);
|
|
276
|
-
ret[curix++] = strdup(hdr->key);
|
|
277
|
-
ret[curix++] = strdup(hdr->value);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
ret[curix] = NULL;
|
|
281
|
-
return ret;
|
|
282
|
-
}
|
|
@@ -1,557 +0,0 @@
|
|
|
1
|
-
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2014 Couchbase, Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
#include "config.h"
|
|
19
|
-
#include "connect.h"
|
|
20
|
-
#include "ioutils.h"
|
|
21
|
-
#include "iotable.h"
|
|
22
|
-
#include "settings.h"
|
|
23
|
-
#include "timer-ng.h"
|
|
24
|
-
#include <errno.h>
|
|
25
|
-
|
|
26
|
-
/* win32 lacks EAI_SYSTEM */
|
|
27
|
-
#ifndef EAI_SYSTEM
|
|
28
|
-
#define EAI_SYSTEM 0
|
|
29
|
-
#endif
|
|
30
|
-
#define LOGARGS(conn, lvl) conn->settings, "connection", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
31
|
-
static const lcb_host_t *get_loghost(lcbio_SOCKET *s) {
|
|
32
|
-
static lcb_host_t host = { "NOHOST", "NOPORT" };
|
|
33
|
-
if (!s) { return &host; }
|
|
34
|
-
if (!s->info) { return &host; }
|
|
35
|
-
return &s->info->ep;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Format string arguments for %p%s:%s */
|
|
39
|
-
#define CSLOGID(sock) get_loghost(sock)->host, get_loghost(sock)->port, (void*)s
|
|
40
|
-
#define CSLOGFMT "<%s:%s> (SOCK=%p) "
|
|
41
|
-
|
|
42
|
-
typedef enum {
|
|
43
|
-
CS_PENDING = 0,
|
|
44
|
-
CS_CANCELLED,
|
|
45
|
-
CS_TIMEDOUT,
|
|
46
|
-
CS_CONNECTED,
|
|
47
|
-
CS_ERROR
|
|
48
|
-
} connect_state;
|
|
49
|
-
|
|
50
|
-
typedef struct lcbio_CONNSTART {
|
|
51
|
-
lcbio_CONNDONE_cb handler;
|
|
52
|
-
lcbio_SOCKET *sock;
|
|
53
|
-
lcbio_OSERR syserr;
|
|
54
|
-
void *arg;
|
|
55
|
-
void *event;
|
|
56
|
-
short ev_active; /* whether the event pointer is active (Event only) */
|
|
57
|
-
short in_uhandler; /* Whether we're inside the user-defined handler */
|
|
58
|
-
struct addrinfo *ai_root;
|
|
59
|
-
struct addrinfo *ai;
|
|
60
|
-
connect_state state;
|
|
61
|
-
lcb_error_t pending;
|
|
62
|
-
lcbio_ASYNC *async;
|
|
63
|
-
char *hoststr;
|
|
64
|
-
} lcbio_CONNSTART;
|
|
65
|
-
|
|
66
|
-
static void
|
|
67
|
-
cs_unwatch(lcbio_CONNSTART *cs)
|
|
68
|
-
{
|
|
69
|
-
lcbio_SOCKET *s = cs->sock;
|
|
70
|
-
if (s && cs->ev_active) {
|
|
71
|
-
lcb_assert(s->u.fd != INVALID_SOCKET);
|
|
72
|
-
IOT_V0EV(s->io).cancel(IOT_ARG(s->io), s->u.fd, cs->event);
|
|
73
|
-
cs->ev_active = 0;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Handler invoked to deliver final status for a connection. This will invoke
|
|
79
|
-
* the user supplied callback with the relevant status (if it has not been
|
|
80
|
-
* cancelled) and then free the CONNSTART object.
|
|
81
|
-
*/
|
|
82
|
-
static void
|
|
83
|
-
cs_handler(void *cookie)
|
|
84
|
-
{
|
|
85
|
-
lcbio_CONNSTART *cs = cookie;
|
|
86
|
-
lcb_error_t err;
|
|
87
|
-
lcbio_SOCKET *s = cs->sock;
|
|
88
|
-
|
|
89
|
-
if (s && cs->event) {
|
|
90
|
-
cs_unwatch(cs);
|
|
91
|
-
IOT_V0EV(s->io).destroy(IOT_ARG(s->io), cs->event);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (cs->state == CS_PENDING) {
|
|
95
|
-
/* state was not changed since initial scheduling */
|
|
96
|
-
err = LCB_ETIMEDOUT;
|
|
97
|
-
} else if (cs->state == CS_CONNECTED) {
|
|
98
|
-
/* clear pending error */
|
|
99
|
-
err = LCB_SUCCESS;
|
|
100
|
-
} else {
|
|
101
|
-
if (s != NULL && cs->pending == LCB_CONNECT_ERROR) {
|
|
102
|
-
err = lcbio_mklcberr(cs->syserr, s->settings);
|
|
103
|
-
} else {
|
|
104
|
-
err = cs->pending;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (cs->state == CS_CANCELLED) {
|
|
109
|
-
/* ignore everything. Clean up resources */
|
|
110
|
-
goto GT_DTOR;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (s) {
|
|
114
|
-
lcbio__load_socknames(s);
|
|
115
|
-
if (err == LCB_SUCCESS) {
|
|
116
|
-
lcb_log(LOGARGS(s, INFO), CSLOGFMT "Connected ", CSLOGID(s));
|
|
117
|
-
|
|
118
|
-
if (s->settings->tcp_nodelay) {
|
|
119
|
-
lcb_error_t ndrc = lcbio_disable_nagle(s);
|
|
120
|
-
if (ndrc != LCB_SUCCESS) {
|
|
121
|
-
lcb_log(LOGARGS(s, INFO), CSLOGFMT "Couldn't set TCP_NODELAY", CSLOGID(s));
|
|
122
|
-
} else {
|
|
123
|
-
lcb_log(LOGARGS(s, DEBUG), CSLOGFMT "Successfuly set TCP_NODELAY", CSLOGID(s));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
} else {
|
|
127
|
-
lcb_log(LOGARGS(s, ERR), CSLOGFMT "Failed: lcb_err=0x%x, os_errno=%u", CSLOGID(s), err, cs->syserr);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/** Handler section */
|
|
132
|
-
cs->in_uhandler = 1;
|
|
133
|
-
cs->handler(err == LCB_SUCCESS ? s : NULL, cs->arg, err, cs->syserr);
|
|
134
|
-
|
|
135
|
-
GT_DTOR:
|
|
136
|
-
if (cs->async) {
|
|
137
|
-
lcbio_timer_destroy(cs->async);
|
|
138
|
-
}
|
|
139
|
-
if (cs->sock) {
|
|
140
|
-
lcbio_unref(cs->sock);
|
|
141
|
-
}
|
|
142
|
-
if (cs->ai_root) {
|
|
143
|
-
freeaddrinfo(cs->ai_root);
|
|
144
|
-
}
|
|
145
|
-
free(cs);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
static void
|
|
149
|
-
cs_state_signal(lcbio_CONNSTART *cs, connect_state state, lcb_error_t err)
|
|
150
|
-
{
|
|
151
|
-
if (cs->state != CS_PENDING) {
|
|
152
|
-
/** State already set */
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (state == CS_CONNECTED) {
|
|
158
|
-
/* clear last errors if we're successful */
|
|
159
|
-
cs->pending = LCB_SUCCESS;
|
|
160
|
-
} else if (cs->pending == LCB_SUCCESS) {
|
|
161
|
-
/* set error code only if previous code was not a failure */
|
|
162
|
-
cs->pending = err;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
cs->state = state;
|
|
166
|
-
lcbio_async_signal(cs->async);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** Cancels and mutes any pending event */
|
|
170
|
-
void
|
|
171
|
-
lcbio_connect_cancel(lcbio_pCONNSTART cs)
|
|
172
|
-
{
|
|
173
|
-
if (cs->in_uhandler) {
|
|
174
|
-
/* already inside user-defined handler */
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
cs->state = CS_CANCELLED;
|
|
178
|
-
cs_handler(cs);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
static int
|
|
183
|
-
ensure_sock(lcbio_CONNSTART *cs)
|
|
184
|
-
{
|
|
185
|
-
lcbio_SOCKET *s = cs->sock;
|
|
186
|
-
lcbio_TABLE *io = s->io;
|
|
187
|
-
int errtmp = 0;
|
|
188
|
-
|
|
189
|
-
if (cs->ai == NULL) {
|
|
190
|
-
return -1;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (IOT_IS_EVENT(io)) {
|
|
194
|
-
if (s->u.fd != INVALID_SOCKET) {
|
|
195
|
-
/* already have one? */
|
|
196
|
-
return 0;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
while (s->u.fd == INVALID_SOCKET && cs->ai != NULL) {
|
|
200
|
-
s->u.fd = lcbio_E_ai2sock(io, &cs->ai, &errtmp);
|
|
201
|
-
if (s->u.fd != INVALID_SOCKET) {
|
|
202
|
-
return 0;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
} else {
|
|
206
|
-
if (s->u.sd) {
|
|
207
|
-
return 0;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
while (s->u.sd == NULL && cs->ai != NULL) {
|
|
211
|
-
s->u.sd = lcbio_C_ai2sock(io, &cs->ai, &errtmp);
|
|
212
|
-
if (s->u.sd) {
|
|
213
|
-
s->u.sd->lcbconn = (void *) cs->sock;
|
|
214
|
-
s->u.sd->parent = IOT_ARG(io);
|
|
215
|
-
return 0;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (cs->ai == NULL) {
|
|
221
|
-
lcbio_mksyserr(IOT_ERRNO(io), &cs->syserr);
|
|
222
|
-
return -1;
|
|
223
|
-
}
|
|
224
|
-
return 0;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
static void
|
|
228
|
-
destroy_cursock(lcbio_CONNSTART *cs)
|
|
229
|
-
{
|
|
230
|
-
lcbio_SOCKET *s = cs->sock;
|
|
231
|
-
lcbio_TABLE *iot = s->io;
|
|
232
|
-
if (cs->ai) {
|
|
233
|
-
cs->ai = cs->ai->ai_next;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (!cs->ai) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (IOT_IS_EVENT(iot)) {
|
|
241
|
-
if (cs->ev_active) {
|
|
242
|
-
lcb_assert(s->u.fd != INVALID_SOCKET);
|
|
243
|
-
IOT_V0EV(iot).cancel(IOT_ARG(iot), s->u.fd, cs->event);
|
|
244
|
-
cs->ev_active = 0;
|
|
245
|
-
}
|
|
246
|
-
IOT_V0IO(iot).close(IOT_ARG(iot), s->u.fd);
|
|
247
|
-
s->u.fd = INVALID_SOCKET;
|
|
248
|
-
} else {
|
|
249
|
-
if (s->u.sd) {
|
|
250
|
-
IOT_V1(iot).close(IOT_ARG(iot), s->u.sd);
|
|
251
|
-
s->u.sd = NULL;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
static void
|
|
257
|
-
E_connect(lcb_socket_t sock, short events, void *arg)
|
|
258
|
-
{
|
|
259
|
-
lcbio_CONNSTART *cs = arg;
|
|
260
|
-
lcbio_SOCKET *s = cs->sock;
|
|
261
|
-
lcbio_TABLE *io = s->io;
|
|
262
|
-
int retry_once = 0;
|
|
263
|
-
lcbio_CSERR connstatus;
|
|
264
|
-
|
|
265
|
-
(void)sock;
|
|
266
|
-
|
|
267
|
-
lcb_log(LOGARGS(s, TRACE), CSLOGFMT "Got event handler for new connection", CSLOGID(s));
|
|
268
|
-
|
|
269
|
-
GT_NEXTSOCK:
|
|
270
|
-
if (ensure_sock(cs) == -1) {
|
|
271
|
-
cs_state_signal(cs, CS_ERROR, LCB_CONNECT_ERROR);
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (events & LCB_ERROR_EVENT) {
|
|
276
|
-
socklen_t errlen = sizeof(int);
|
|
277
|
-
int sockerr = 0;
|
|
278
|
-
lcb_log(LOGARGS(s, TRACE), CSLOGFMT "Received ERROR_EVENT", CSLOGID(s));
|
|
279
|
-
getsockopt(s->u.fd, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &errlen);
|
|
280
|
-
lcbio_mksyserr(sockerr, &cs->syserr);
|
|
281
|
-
destroy_cursock(cs);
|
|
282
|
-
goto GT_NEXTSOCK;
|
|
283
|
-
|
|
284
|
-
} else {
|
|
285
|
-
int rv = 0;
|
|
286
|
-
struct addrinfo *ai = cs->ai;
|
|
287
|
-
|
|
288
|
-
GT_CONNECT:
|
|
289
|
-
rv = IOT_V0IO(io).connect0(
|
|
290
|
-
IOT_ARG(io), s->u.fd, ai->ai_addr, (unsigned)ai->ai_addrlen);
|
|
291
|
-
|
|
292
|
-
if (rv == 0) {
|
|
293
|
-
cs_unwatch(cs);
|
|
294
|
-
cs_state_signal(cs, CS_CONNECTED, LCB_SUCCESS);
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
connstatus = lcbio_mkcserr(IOT_ERRNO(io));
|
|
300
|
-
lcbio_mksyserr(IOT_ERRNO(io), &cs->syserr);
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
switch (connstatus) {
|
|
304
|
-
|
|
305
|
-
case LCBIO_CSERR_INTR:
|
|
306
|
-
goto GT_CONNECT;
|
|
307
|
-
|
|
308
|
-
case LCBIO_CSERR_CONNECTED:
|
|
309
|
-
cs_unwatch(cs);
|
|
310
|
-
cs_state_signal(cs, CS_CONNECTED, LCB_SUCCESS);
|
|
311
|
-
return;
|
|
312
|
-
|
|
313
|
-
case LCBIO_CSERR_BUSY:
|
|
314
|
-
lcb_log(LOGARGS(s, TRACE), CSLOGFMT "Scheduling asynchronous watch for socket.", CSLOGID(s));
|
|
315
|
-
IOT_V0EV(io).watch(
|
|
316
|
-
IOT_ARG(io), s->u.fd, cs->event, LCB_WRITE_EVENT, cs, E_connect);
|
|
317
|
-
cs->ev_active = 1;
|
|
318
|
-
return;
|
|
319
|
-
|
|
320
|
-
case LCBIO_CSERR_EINVAL:
|
|
321
|
-
if (!retry_once) {
|
|
322
|
-
retry_once = 1;
|
|
323
|
-
goto GT_CONNECT;
|
|
324
|
-
}
|
|
325
|
-
/* fallthrough */
|
|
326
|
-
|
|
327
|
-
case LCBIO_CSERR_EFAIL:
|
|
328
|
-
default:
|
|
329
|
-
/* close the current socket and try again */
|
|
330
|
-
lcb_log(LOGARGS(s, TRACE), CSLOGFMT "connect() failed. os_error=%d [%s]", CSLOGID(s), IOT_ERRNO(io), strerror(IOT_ERRNO(io)));
|
|
331
|
-
destroy_cursock(cs);
|
|
332
|
-
goto GT_NEXTSOCK;
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
static void C_connect(lcbio_CONNSTART *cs);
|
|
337
|
-
|
|
338
|
-
static void
|
|
339
|
-
C_conncb(lcb_sockdata_t *sock, int status)
|
|
340
|
-
{
|
|
341
|
-
lcbio_SOCKET *s = (void *)sock->lcbconn;
|
|
342
|
-
lcbio_CONNSTART *cs = (void *)s->ctx;
|
|
343
|
-
|
|
344
|
-
lcb_log(LOGARGS(s, TRACE), CSLOGFMT "Received completion handler. Status=%d. errno=%d", CSLOGID(s), status, IOT_ERRNO(s->io));
|
|
345
|
-
|
|
346
|
-
if (!--s->refcount) {
|
|
347
|
-
lcbio__destroy(s);
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
if (!status) {
|
|
352
|
-
if (cs->state == CS_PENDING) {
|
|
353
|
-
cs->state = CS_CONNECTED;
|
|
354
|
-
}
|
|
355
|
-
cs_handler(cs);
|
|
356
|
-
} else {
|
|
357
|
-
lcbio_mksyserr(IOT_ERRNO(s->io), &cs->syserr);
|
|
358
|
-
destroy_cursock(cs);
|
|
359
|
-
C_connect(cs);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
static void
|
|
364
|
-
C_connect(lcbio_CONNSTART *cs)
|
|
365
|
-
{
|
|
366
|
-
int rv;
|
|
367
|
-
lcbio_SOCKET *s = cs->sock;
|
|
368
|
-
int retry_once = 0;
|
|
369
|
-
lcbio_CSERR status;
|
|
370
|
-
lcbio_TABLE *io = s->io;
|
|
371
|
-
|
|
372
|
-
GT_NEXTSOCK:
|
|
373
|
-
if (ensure_sock(cs) != 0) {
|
|
374
|
-
lcbio_mksyserr(IOT_ERRNO(io), &cs->syserr);
|
|
375
|
-
cs_state_signal(cs, CS_ERROR, LCB_CONNECT_ERROR);
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
GT_CONNECT:
|
|
380
|
-
rv = IOT_V1(io).connect(IOT_ARG(io), s->u.sd, cs->ai->ai_addr,
|
|
381
|
-
(unsigned)cs->ai->ai_addrlen, C_conncb);
|
|
382
|
-
if (rv == 0) {
|
|
383
|
-
lcbio_ref(s);
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
lcbio_mksyserr(IOT_ERRNO(io), &cs->syserr);
|
|
388
|
-
status = lcbio_mkcserr(IOT_ERRNO(io));
|
|
389
|
-
switch (status) {
|
|
390
|
-
|
|
391
|
-
case LCBIO_CSERR_INTR:
|
|
392
|
-
goto GT_CONNECT;
|
|
393
|
-
|
|
394
|
-
case LCBIO_CSERR_CONNECTED:
|
|
395
|
-
cs_state_signal(cs, CS_CONNECTED, LCB_SUCCESS);
|
|
396
|
-
return;
|
|
397
|
-
|
|
398
|
-
case LCBIO_CSERR_BUSY:
|
|
399
|
-
return;
|
|
400
|
-
|
|
401
|
-
case LCBIO_CSERR_EINVAL:
|
|
402
|
-
if (!retry_once) {
|
|
403
|
-
retry_once = 1;
|
|
404
|
-
goto GT_CONNECT;
|
|
405
|
-
}
|
|
406
|
-
/* fallthrough */
|
|
407
|
-
|
|
408
|
-
case LCBIO_CSERR_EFAIL:
|
|
409
|
-
default:
|
|
410
|
-
destroy_cursock(cs);
|
|
411
|
-
goto GT_NEXTSOCK;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
struct lcbio_CONNSTART *
|
|
416
|
-
lcbio_connect(lcbio_TABLE *iot, lcb_settings *settings, const lcb_host_t *dest,
|
|
417
|
-
uint32_t timeout, lcbio_CONNDONE_cb handler, void *arg)
|
|
418
|
-
{
|
|
419
|
-
lcbio_SOCKET *s;
|
|
420
|
-
lcbio_CONNSTART *ret;
|
|
421
|
-
struct addrinfo hints;
|
|
422
|
-
int rv;
|
|
423
|
-
|
|
424
|
-
s = calloc(1, sizeof(*s));
|
|
425
|
-
ret = calloc(1, sizeof(*ret));
|
|
426
|
-
|
|
427
|
-
/** Initialize the socket first */
|
|
428
|
-
s->io = iot;
|
|
429
|
-
s->settings = settings;
|
|
430
|
-
s->ctx = ret;
|
|
431
|
-
s->refcount = 1;
|
|
432
|
-
s->info = calloc(1, sizeof(*s->info));
|
|
433
|
-
s->info->ep = *dest;
|
|
434
|
-
lcbio_table_ref(s->io);
|
|
435
|
-
lcb_settings_ref(s->settings);
|
|
436
|
-
lcb_list_init(&s->protos);
|
|
437
|
-
|
|
438
|
-
if (IOT_IS_EVENT(iot)) {
|
|
439
|
-
s->u.fd = INVALID_SOCKET;
|
|
440
|
-
ret->event = IOT_V0EV(iot).create(IOT_ARG(iot));
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
/** Initialize the connstart structure */
|
|
444
|
-
ret->handler = handler;
|
|
445
|
-
ret->arg = arg;
|
|
446
|
-
ret->sock = s;
|
|
447
|
-
ret->async = lcbio_timer_new(iot, ret, cs_handler);
|
|
448
|
-
|
|
449
|
-
lcbio_timer_rearm(ret->async, timeout);
|
|
450
|
-
lcb_log(LOGARGS(s, INFO), CSLOGFMT "Starting. Timeout=%uus", CSLOGID(s), timeout);
|
|
451
|
-
|
|
452
|
-
/** Hostname lookup: */
|
|
453
|
-
memset(&hints, 0, sizeof(hints));
|
|
454
|
-
hints.ai_flags = AI_PASSIVE;
|
|
455
|
-
hints.ai_socktype = SOCK_STREAM;
|
|
456
|
-
if (settings->ipv6 == LCB_IPV6_DISABLED) {
|
|
457
|
-
hints.ai_family = AF_INET;
|
|
458
|
-
} else if (settings->ipv6 == LCB_IPV6_ONLY) {
|
|
459
|
-
hints.ai_family = AF_INET6;
|
|
460
|
-
} else {
|
|
461
|
-
hints.ai_family = AF_UNSPEC;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if ((rv = getaddrinfo(dest->host, dest->port, &hints, &ret->ai_root))) {
|
|
465
|
-
const char *errstr = rv != EAI_SYSTEM ? gai_strerror(rv) : "";
|
|
466
|
-
lcb_log(LOGARGS(s, ERR), CSLOGFMT "Couldn't look up %s (%s) [EAI=%d]", CSLOGID(s), dest->host, errstr, rv);
|
|
467
|
-
cs_state_signal(ret, CS_ERROR, LCB_UNKNOWN_HOST);
|
|
468
|
-
} else {
|
|
469
|
-
ret->ai = ret->ai_root;
|
|
470
|
-
|
|
471
|
-
/** Figure out how to connect */
|
|
472
|
-
if (IOT_IS_EVENT(iot)) {
|
|
473
|
-
E_connect(-1, LCB_WRITE_EVENT, ret);
|
|
474
|
-
} else {
|
|
475
|
-
C_connect(ret);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
return ret;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
lcbio_CONNSTART *
|
|
482
|
-
lcbio_connect_hl(lcbio_TABLE *iot, lcb_settings *settings,
|
|
483
|
-
hostlist_t hl, int rollover, uint32_t timeout,
|
|
484
|
-
lcbio_CONNDONE_cb handler, void *arg)
|
|
485
|
-
{
|
|
486
|
-
const lcb_host_t *cur;
|
|
487
|
-
unsigned ii, hlmax;
|
|
488
|
-
ii = 0;
|
|
489
|
-
hlmax = hostlist_size(hl);
|
|
490
|
-
|
|
491
|
-
while ( (cur = hostlist_shift_next(hl, rollover)) && ii++ < hlmax) {
|
|
492
|
-
lcbio_CONNSTART *ret = lcbio_connect(
|
|
493
|
-
iot, settings, cur, timeout, handler, arg);
|
|
494
|
-
if (ret) {
|
|
495
|
-
return ret;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
return NULL;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
lcbio_SOCKET *
|
|
503
|
-
lcbio_wrap_fd(lcbio_pTABLE iot, lcb_settings *settings, lcb_socket_t fd)
|
|
504
|
-
{
|
|
505
|
-
lcbio_SOCKET *ret = calloc(1, sizeof(*ret));
|
|
506
|
-
lcbio_CONNDONE_cb *ci = calloc(1, sizeof(*ci));
|
|
507
|
-
|
|
508
|
-
if (ret == NULL || ci == NULL) {
|
|
509
|
-
free(ret);
|
|
510
|
-
free(ci);
|
|
511
|
-
return NULL;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
assert(iot->model = LCB_IOMODEL_EVENT);
|
|
515
|
-
|
|
516
|
-
lcb_list_init(&ret->protos);
|
|
517
|
-
ret->settings = settings;
|
|
518
|
-
ret->io = iot;
|
|
519
|
-
ret->refcount = 1;
|
|
520
|
-
ret->u.fd = fd;
|
|
521
|
-
|
|
522
|
-
lcbio_table_ref(ret->io);
|
|
523
|
-
lcb_settings_ref(ret->settings);
|
|
524
|
-
lcbio__load_socknames(ret);
|
|
525
|
-
return ret;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
void
|
|
529
|
-
lcbio_shutdown(lcbio_SOCKET *s)
|
|
530
|
-
{
|
|
531
|
-
lcbio_TABLE *io = s->io;
|
|
532
|
-
|
|
533
|
-
lcbio__protoctx_delall(s);
|
|
534
|
-
if (IOT_IS_EVENT(io)) {
|
|
535
|
-
if (s->u.fd != INVALID_SOCKET) {
|
|
536
|
-
IOT_V0IO(io).close(IOT_ARG(io), s->u.fd);
|
|
537
|
-
s->u.fd = INVALID_SOCKET;
|
|
538
|
-
}
|
|
539
|
-
} else {
|
|
540
|
-
if (s->u.sd) {
|
|
541
|
-
IOT_V1(io).close(IOT_ARG(io), s->u.sd);
|
|
542
|
-
s->u.sd = NULL;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
void
|
|
548
|
-
lcbio__destroy(lcbio_SOCKET *s)
|
|
549
|
-
{
|
|
550
|
-
lcbio_shutdown(s);
|
|
551
|
-
if (s->info) {
|
|
552
|
-
free(s->info);
|
|
553
|
-
}
|
|
554
|
-
lcbio_table_unref(s->io);
|
|
555
|
-
lcb_settings_unref(s->settings);
|
|
556
|
-
free(s);
|
|
557
|
-
}
|