Skip to content

Commit

Permalink
lib: add CURLINFO_CONN_ID and CURLINFO_XFER_ID
Browse files Browse the repository at this point in the history
- add an `id` long to Curl_easy, -1 on init
- once added to a multi (or its own multi), it gets
  a non-negative number assigned by the connection cache
- `id` is unique among all transfers using the same
  cache until reaching LONG_MAX where it will wrap
  around. So, not unique eternally.
- CURLINFO_CONN_ID returns the connection id attached to
  data or, if none present, data->state.lastconnect_id
- variables and type declared in tool for write out

Closes #11185
  • Loading branch information
icing authored and bagder committed Jun 12, 2023
1 parent fdda99c commit e024d56
Show file tree
Hide file tree
Showing 31 changed files with 252 additions and 94 deletions.
6 changes: 6 additions & 0 deletions docs/libcurl/curl_easy_getinfo.3
Expand Up @@ -247,6 +247,12 @@ See \fICURLINFO_PROTOCOL(3)\fP
.IP CURLINFO_SCHEME
The scheme used for the connection. (Added in 7.52.0)
See \fICURLINFO_SCHEME(3)\fP
.IP CURLINFO_CONN_ID
The ID of the last connection used by the transfer. (Added in 8.2.0)
See \fICURLINFO_CONN_ID(3)\fP
.IP CURLINFO_XFER_ID
The ID of the transfer. (Added in 8.2.0)
See \fICURLINFO_XFER_ID(3)\fP
.SH TIMES
.nf
An overview of the six time values available from curl_easy_getinfo()
Expand Down
69 changes: 69 additions & 0 deletions docs/libcurl/opts/CURLINFO_CONN_ID.3
@@ -0,0 +1,69 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" * SPDX-License-Identifier: curl
.\" *
.\" **************************************************************************
.\"
.TH CURLINFO_CONN_ID 3 "07 June 2023" "libcurl" "libcurl"
.SH NAME
CURLINFO_CONN_ID \- get the ID of the last connection used by the handle
.SH SYNOPSIS
.nf
#include <curl/curl.h>

CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_CONN_ID,
curl_off_t *conn_id);
.fi
.SH DESCRIPTION
Pass a pointer to a \fIcurl_off_t\fP to receive the connection identifier last
used by the handle. Stores -1 if there was no connection used.

The connection id is unique among all connections using the same
connection cache. This is implicitly the case for all connections in the
same multi handle.

.SH PROTOCOLS
All
.SH EXAMPLE
.nf
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");

/* Perform the request */
res = curl_easy_perform(curl);

if(!res) {
curl_off_t conn_id;
res = curl_easy_getinfo(curl, CURLINFO_CONN_ID, &conn_id);
if(!res) {
printf("Connection used: %" CURL_FORMAT_CURL_OFF_T "\\n", conn_id);
}
}
}
.fi
.SH AVAILABILITY
Added in 8.2.0
.SH RETURN VALUE
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
.SH "SEE ALSO"
.BR curl_easy_getinfo "(3), " curl_easy_setopt "(3), "
.BR CURLINFO_XFER_ID "(3), "
70 changes: 70 additions & 0 deletions docs/libcurl/opts/CURLINFO_XFER_ID.3
@@ -0,0 +1,70 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" * SPDX-License-Identifier: curl
.\" *
.\" **************************************************************************
.\"
.TH CURLINFO_XFER_ID 3 "07 June 2023" "libcurl" "libcurl"
.SH NAME
CURLINFO_XFER_ID \- get the ID of a transfer
.SH SYNOPSIS
.nf
#include <curl/curl.h>

CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_XFER_ID,
curl_off_t *xfer_id);
.fi
.SH DESCRIPTION
Pass a pointer to a \fIcurl_off_t\fP to receive the identifier of the
current/last transfer done with the handle. Stores -1 if no transfer
has been started yet for the handle.

The transfer id is unique among all transfers performed using the same
connection cache. This is implicitly the case for all transfers in the
same multi handle.

.SH PROTOCOLS
All
.SH EXAMPLE
.nf
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");

/* Perform the request */
res = curl_easy_perform(curl);

if(!res) {
curl_off_t xfer_id;
res = curl_easy_getinfo(curl, CURLINFO_XFER_ID, &xfer_id);
if(!res) {
printf("Transfer ID: %" CURL_FORMAT_CURL_OFF_T "\\n", xfer_id);
}
}
}
.fi
.SH AVAILABILITY
Added in 8.2.0
.SH RETURN VALUE
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
.SH "SEE ALSO"
.BR curl_easy_getinfo "(3), " curl_easy_setopt "(3), "
.BR CURLINFO_CONN_ID "(3), "
2 changes: 2 additions & 0 deletions docs/libcurl/symbols-in-versions
Expand Up @@ -421,6 +421,7 @@ CURLINFO_CAINFO 7.84.0
CURLINFO_CAPATH 7.84.0
CURLINFO_CERTINFO 7.19.1
CURLINFO_CONDITION_UNMET 7.19.4
CURLINFO_CONN_ID 8.2.0
CURLINFO_CONNECT_TIME 7.4.1
CURLINFO_CONNECT_TIME_T 7.61.0
CURLINFO_CONTENT_LENGTH_DOWNLOAD 7.6.1 7.55.0
Expand Down Expand Up @@ -503,6 +504,7 @@ CURLINFO_TLS_SSL_PTR 7.48.0
CURLINFO_TOTAL_TIME 7.4.1
CURLINFO_TOTAL_TIME_T 7.61.0
CURLINFO_TYPEMASK 7.4.1
CURLINFO_XFER_ID 8.2.0
CURLIOCMD_NOP 7.12.3
CURLIOCMD_RESTARTREAD 7.12.3
CURLIOE_FAILRESTART 7.12.3
Expand Down
4 changes: 3 additions & 1 deletion include/curl/curl.h
Expand Up @@ -2924,7 +2924,9 @@ typedef enum {
CURLINFO_REFERER = CURLINFO_STRING + 60,
CURLINFO_CAINFO = CURLINFO_STRING + 61,
CURLINFO_CAPATH = CURLINFO_STRING + 62,
CURLINFO_LASTONE = 62
CURLINFO_XFER_ID = CURLINFO_OFF_T + 63,
CURLINFO_CONN_ID = CURLINFO_OFF_T + 64,
CURLINFO_LASTONE = 64
} CURLINFO;

/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
Expand Down
4 changes: 2 additions & 2 deletions lib/cfilters.c
Expand Up @@ -179,7 +179,7 @@ ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
if(cf) {
return cf->cft->do_recv(cf, data, buf, len, code);
}
failf(data, CMSGI(data->conn, num, "recv: no filter connected"));
failf(data, "recv: no filter connected");
*code = CURLE_FAILED_INIT;
return -1;
}
Expand All @@ -198,7 +198,7 @@ ssize_t Curl_conn_send(struct Curl_easy *data, int num,
if(cf) {
return cf->cft->do_send(cf, data, mem, len, code);
}
failf(data, CMSGI(data->conn, num, "send: no filter connected"));
failf(data, "send: no filter connected");
DEBUGASSERT(0);
*code = CURLE_FAILED_INIT;
return -1;
Expand Down
3 changes: 2 additions & 1 deletion lib/conncache.h
Expand Up @@ -39,7 +39,8 @@ struct connectdata;
struct conncache {
struct Curl_hash hash;
size_t num_conn;
long next_connection_id;
curl_off_t next_connection_id;
curl_off_t next_easy_id;
struct curltime last_cleanup;
/* handle used for closing cached connections */
struct Curl_easy *closure_handle;
Expand Down
2 changes: 1 addition & 1 deletion lib/connect.c
Expand Up @@ -253,7 +253,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
}

struct connfind {
long id_tofind;
curl_off_t id_tofind;
struct connectdata *found;
};

Expand Down
4 changes: 1 addition & 3 deletions lib/curl_log.c
Expand Up @@ -134,9 +134,7 @@ void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
va_list ap;
int len;
char buffer[MAXINFO + 2];
len = msnprintf(buffer, MAXINFO, "[CONN-%ld%s-%s] ",
cf->conn->connection_id, cf->sockindex? "/2" : "",
cf->cft->name);
len = msnprintf(buffer, MAXINFO, "[%s] ", cf->cft->name);
va_start(ap, fmt);
len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap);
va_end(ap);
Expand Down
19 changes: 0 additions & 19 deletions lib/curl_log.h
Expand Up @@ -118,23 +118,4 @@ void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,

#define LOG_CF_IS_DEBUG(cf, data) Curl_log_cf_is_debug(cf, data)

/* Macros intended for DEBUGF logging, use like:
* DEBUGF(infof(data, CFMSG(cf, "this filter %s rocks"), "very much"));
* and it will output:
* [CONN-1-0][CF-SSL] this filter very much rocks
* on connection #1 with sockindex 0 for filter of type "SSL". */
#define DMSG(d,msg) \
"[CONN-%ld] "msg, (d)->conn->connection_id
#define DMSGI(d,i,msg) \
"[CONN-%ld-%d] "msg, (d)->conn->connection_id, (i)
#define CMSG(c,msg) \
"[CONN-%ld] "msg, (c)->connection_id
#define CMSGI(c,i,msg) \
"[CONN-%ld-%d] "msg, (c)->connection_id, (i)
#define CFMSG(cf,msg) \
"[CONN-%ld-%d][CF-%s] "msg, (cf)->conn->connection_id, \
(cf)->sockindex, (cf)->cft->name



#endif /* HEADER_CURL_LOG_H */
2 changes: 2 additions & 0 deletions lib/easy.c
Expand Up @@ -893,6 +893,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
/* the connection cache is setup on demand */
outcurl->state.conn_cache = NULL;
outcurl->state.lastconnect_id = -1;
outcurl->state.recent_conn_id = -1;
outcurl->id = -1;

outcurl->progress.flags = data->progress.flags;
outcurl->progress.callback = data->progress.callback;
Expand Down
7 changes: 7 additions & 0 deletions lib/getinfo.c
Expand Up @@ -415,6 +415,13 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
case CURLINFO_RETRY_AFTER:
*param_offt = data->info.retry_after;
break;
case CURLINFO_XFER_ID:
*param_offt = data->id;
break;
case CURLINFO_CONN_ID:
*param_offt = data->conn?
data->conn->connection_id : data->state.recent_conn_id;
break;
default:
return CURLE_UNKNOWN_OPTION;
}
Expand Down
11 changes: 5 additions & 6 deletions lib/http2.c
Expand Up @@ -1947,8 +1947,8 @@ static ssize_t h2_submit(struct stream_ctx **pstream,

h2_pri_spec(data, &pri_spec);

DEBUGF(LOG_CF(data, cf, "send request allowed %d (easy handle %p)",
nghttp2_session_check_request_allowed(ctx->h2), (void *)data));
DEBUGF(LOG_CF(data, cf, "send request allowed %d",
nghttp2_session_check_request_allowed(ctx->h2)));

switch(data->state.httpreq) {
case HTTPREQ_POST:
Expand Down Expand Up @@ -1984,8 +1984,7 @@ static ssize_t h2_submit(struct stream_ctx **pstream,

DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) submit %s",
stream_id, len, data->state.url));
infof(data, "Using Stream ID: %u (easy handle %p)",
stream_id, (void *)data);
infof(data, "Using Stream ID: %u", stream_id);
stream->id = stream_id;
stream->local_window_size = H2_STREAM_WINDOW_SIZE;
if(data->set.max_recv_speed) {
Expand Down Expand Up @@ -2542,7 +2541,7 @@ CURLcode Curl_http2_switch(struct Curl_easy *data,
CURLcode result;

DEBUGASSERT(!Curl_conn_is_http2(data, conn, sockindex));
DEBUGF(infof(data, DMSGI(data, sockindex, "switching to HTTP/2")));
DEBUGF(infof(data, "switching to HTTP/2"));

result = http2_cfilter_add(&cf, data, conn, sockindex);
if(result)
Expand Down Expand Up @@ -2601,7 +2600,7 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data,
CURLcode result;

DEBUGASSERT(!Curl_conn_is_http2(data, conn, sockindex));
DEBUGF(infof(data, DMSGI(data, sockindex, "upgrading to HTTP/2")));
DEBUGF(infof(data, "upgrading to HTTP/2"));
DEBUGASSERT(data->req.upgr101 == UPGR101_RECEIVED);

result = http2_cfilter_add(&cf, data, conn, sockindex);
Expand Down
2 changes: 1 addition & 1 deletion lib/imap.c
Expand Up @@ -1777,7 +1777,7 @@ static CURLcode imap_sendf(struct Curl_easy *data, const char *fmt, ...)

/* Calculate the tag based on the connection ID and command ID */
msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
'A' + curlx_sltosi(data->conn->connection_id % 26),
'A' + curlx_sltosi((long)(data->conn->connection_id % 26)),
++imapc->cmdid);

/* start with a blank buffer */
Expand Down

0 comments on commit e024d56

Please sign in to comment.