Skip to content

Commit 01b8886

Browse files
committed
Merge branch 'js/trace2-session-id'
The transport layer was taught to optionally exchange the session ID assigned by the trace2 subsystem during fetch/push transactions. * js/trace2-session-id: receive-pack: log received client session ID send-pack: advertise session ID in capabilities upload-pack, serve: log received client session ID fetch-pack: advertise session ID in capabilities transport: log received server session ID serve: advertise session ID in v2 capabilities receive-pack: advertise session ID in v0 capabilities upload-pack: advertise session ID in v0 capabilities trace2: add a public function for getting the SID docs: new transfer.advertiseSID option docs: new capability to advertise session IDs
2 parents 9b3b4ad + a2a066d commit 01b8886

File tree

12 files changed

+198
-3
lines changed

12 files changed

+198
-3
lines changed

Documentation/config/transfer.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,7 @@ transfer.unpackLimit::
6969
When `fetch.unpackLimit` or `receive.unpackLimit` are
7070
not set, the value of this variable is used instead.
7171
The default value is 100.
72+
73+
transfer.advertiseSID::
74+
Boolean. When true, client and server processes will advertise their
75+
unique session IDs to their remote counterpart. Defaults to false.

Documentation/technical/protocol-capabilities.txt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ and 'push-cert' capabilities are sent and recognized by the receive-pack
2727
(push to server) process.
2828

2929
The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
30-
by both upload-pack and receive-pack protocols. The 'agent' capability
31-
may optionally be sent in both protocols.
30+
by both upload-pack and receive-pack protocols. The 'agent' and 'session-id'
31+
capabilities may optionally be sent in both protocols.
3232

3333
All other capabilities are only recognized by the upload-pack (fetch
3434
from server) process.
@@ -365,3 +365,16 @@ If the upload-pack server advertises the 'filter' capability,
365365
fetch-pack may send "filter" commands to request a partial clone
366366
or partial fetch and request that the server omit various objects
367367
from the packfile.
368+
369+
session-id=<session id>
370+
-----------------------
371+
372+
The server may advertise a session ID that can be used to identify this process
373+
across multiple requests. The client may advertise its own session ID back to
374+
the server as well.
375+
376+
Session IDs should be unique to a given process. They must fit within a
377+
packet-line, and must not contain non-printable or whitespace characters. The
378+
current implementation uses trace2 session IDs (see
379+
link:api-trace2.html[api-trace2] for details), but this may change and users of
380+
the session ID should not rely on this fact.

Documentation/technical/protocol-v2.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,3 +492,16 @@ form `object-format=X`) to notify the client that the server is able to deal
492492
with objects using hash algorithm X. If not specified, the server is assumed to
493493
only handle SHA-1. If the client would like to use a hash algorithm other than
494494
SHA-1, it should specify its object-format string.
495+
496+
session-id=<session id>
497+
~~~~~~~~~~~~~~~~~~~~~~~
498+
499+
The server may advertise a session ID that can be used to identify this process
500+
across multiple requests. The client may advertise its own session ID back to
501+
the server as well.
502+
503+
Session IDs should be unique to a given process. They must fit within a
504+
packet-line, and must not contain non-printable or whitespace characters. The
505+
current implementation uses trace2 session IDs (see
506+
link:api-trace2.html[api-trace2] for details), but this may change and users of
507+
the session ID should not rely on this fact.

builtin/receive-pack.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static int receive_unpack_limit = -1;
5454
static int transfer_unpack_limit = -1;
5555
static int advertise_atomic_push = 1;
5656
static int advertise_push_options;
57+
static int advertise_sid;
5758
static int unpack_limit = 100;
5859
static off_t max_input_size;
5960
static int report_status;
@@ -248,6 +249,11 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
248249
return 0;
249250
}
250251

252+
if (strcmp(var, "transfer.advertisesid") == 0) {
253+
advertise_sid = git_config_bool(var, value);
254+
return 0;
255+
}
256+
251257
return git_default_config(var, value, cb);
252258
}
253259

@@ -268,6 +274,8 @@ static void show_ref(const char *path, const struct object_id *oid)
268274
strbuf_addf(&cap, " push-cert=%s", push_cert_nonce);
269275
if (advertise_push_options)
270276
strbuf_addstr(&cap, " push-options");
277+
if (advertise_sid)
278+
strbuf_addf(&cap, " session-id=%s", trace2_session_id());
271279
strbuf_addf(&cap, " object-format=%s", the_hash_algo->name);
272280
strbuf_addf(&cap, " agent=%s", git_user_agent_sanitized());
273281
packet_write_fmt(1, "%s %s%c%s\n",
@@ -2075,6 +2083,7 @@ static struct command *read_head_info(struct packet_reader *reader,
20752083
if (linelen < reader->pktlen) {
20762084
const char *feature_list = reader->line + linelen + 1;
20772085
const char *hash = NULL;
2086+
const char *client_sid;
20782087
int len = 0;
20792088
if (parse_feature_request(feature_list, "report-status"))
20802089
report_status = 1;
@@ -2097,6 +2106,12 @@ static struct command *read_head_info(struct packet_reader *reader,
20972106
}
20982107
if (xstrncmpz(the_hash_algo->name, hash, len))
20992108
die("error: unsupported object format '%s'", hash);
2109+
client_sid = parse_feature_value(feature_list, "session-id", &len, NULL);
2110+
if (client_sid) {
2111+
char *sid = xstrndup(client_sid, len);
2112+
trace2_data_string("transfer", NULL, "client-sid", client_sid);
2113+
free(sid);
2114+
}
21002115
}
21012116

21022117
if (!strcmp(reader->line, "push-cert")) {

fetch-pack.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ static int fetch_fsck_objects = -1;
3535
static int transfer_fsck_objects = -1;
3636
static int agent_supported;
3737
static int server_supports_filtering;
38+
static int advertise_sid;
3839
static struct shallow_lock shallow_lock;
3940
static const char *alternate_shallow_file;
4041
static struct strbuf fsck_msg_types = STRBUF_INIT;
@@ -326,6 +327,8 @@ static int find_common(struct fetch_negotiator *negotiator,
326327
if (deepen_not_ok) strbuf_addstr(&c, " deepen-not");
327328
if (agent_supported) strbuf_addf(&c, " agent=%s",
328329
git_user_agent_sanitized());
330+
if (advertise_sid)
331+
strbuf_addf(&c, " session-id=%s", trace2_session_id());
329332
if (args->filter_options.choice)
330333
strbuf_addstr(&c, " filter");
331334
packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
@@ -979,6 +982,9 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
979982
agent_len, agent_feature);
980983
}
981984

985+
if (!server_supports("session-id"))
986+
advertise_sid = 0;
987+
982988
if (server_supports("shallow"))
983989
print_verbose(args, _("Server supports %s"), "shallow");
984990
else if (args->depth > 0 || is_repository_shallow(r))
@@ -1191,6 +1197,8 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
11911197
packet_buf_write(&req_buf, "command=fetch");
11921198
if (server_supports_v2("agent", 0))
11931199
packet_buf_write(&req_buf, "agent=%s", git_user_agent_sanitized());
1200+
if (advertise_sid && server_supports_v2("session-id", 0))
1201+
packet_buf_write(&req_buf, "session-id=%s", trace2_session_id());
11941202
if (args->server_options && args->server_options->nr &&
11951203
server_supports_v2("server-option", 1)) {
11961204
int i;
@@ -1711,6 +1719,7 @@ static void fetch_pack_config(void)
17111719
git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
17121720
git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
17131721
git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
1722+
git_config_get_bool("transfer.advertisesid", &advertise_sid);
17141723
if (!uri_protocols.nr) {
17151724
char *str;
17161725

send-pack.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ int send_pack(struct send_pack_args *args,
425425
int use_sideband = 0;
426426
int quiet_supported = 0;
427427
int agent_supported = 0;
428+
int advertise_sid = 0;
428429
int use_atomic = 0;
429430
int atomic_supported = 0;
430431
int use_push_options = 0;
@@ -436,6 +437,8 @@ int send_pack(struct send_pack_args *args,
436437
const char *push_cert_nonce = NULL;
437438
struct packet_reader reader;
438439

440+
git_config_get_bool("transfer.advertisesid", &advertise_sid);
441+
439442
/* Does the other end support the reporting? */
440443
if (server_supports("report-status-v2"))
441444
status_report = 2;
@@ -451,6 +454,8 @@ int send_pack(struct send_pack_args *args,
451454
quiet_supported = 1;
452455
if (server_supports("agent"))
453456
agent_supported = 1;
457+
if (!server_supports("session-id"))
458+
advertise_sid = 0;
454459
if (server_supports("no-thin"))
455460
args->use_thin_pack = 0;
456461
if (server_supports("atomic"))
@@ -507,6 +512,8 @@ int send_pack(struct send_pack_args *args,
507512
strbuf_addf(&cap_buf, " object-format=%s", the_hash_algo->name);
508513
if (agent_supported)
509514
strbuf_addf(&cap_buf, " agent=%s", git_user_agent_sanitized());
515+
if (advertise_sid)
516+
strbuf_addf(&cap_buf, " session-id=%s", trace2_session_id());
510517

511518
/*
512519
* NEEDSWORK: why does delete-refs have to be so specific to

serve.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include "serve.h"
99
#include "upload-pack.h"
1010

11+
static int advertise_sid;
12+
1113
static int always_advertise(struct repository *r,
1214
struct strbuf *value)
1315
{
@@ -30,6 +32,15 @@ static int object_format_advertise(struct repository *r,
3032
return 1;
3133
}
3234

35+
static int session_id_advertise(struct repository *r, struct strbuf *value)
36+
{
37+
if (!advertise_sid)
38+
return 0;
39+
if (value)
40+
strbuf_addstr(value, trace2_session_id());
41+
return 1;
42+
}
43+
3344
struct protocol_capability {
3445
/*
3546
* The name of the capability. The server uses this name when
@@ -66,6 +77,7 @@ static struct protocol_capability capabilities[] = {
6677
{ "fetch", upload_pack_advertise, upload_pack_v2 },
6778
{ "server-option", always_advertise, NULL },
6879
{ "object-format", object_format_advertise, NULL },
80+
{ "session-id", session_id_advertise, NULL },
6981
};
7082

7183
static void advertise_capabilities(void)
@@ -189,6 +201,7 @@ static int process_request(void)
189201
struct packet_reader reader;
190202
struct strvec keys = STRVEC_INIT;
191203
struct protocol_capability *command = NULL;
204+
const char *client_sid;
192205

193206
packet_reader_init(&reader, 0, NULL, 0,
194207
PACKET_READ_CHOMP_NEWLINE |
@@ -252,6 +265,9 @@ static int process_request(void)
252265

253266
check_algorithm(the_repository, &keys);
254267

268+
if (has_capability(&keys, "session-id", &client_sid))
269+
trace2_data_string("transfer", NULL, "client-sid", client_sid);
270+
255271
command->command(the_repository, &keys, &reader);
256272

257273
strvec_clear(&keys);
@@ -261,6 +277,8 @@ static int process_request(void)
261277
/* Main serve loop for protocol version 2 */
262278
void serve(struct serve_options *options)
263279
{
280+
git_config_get_bool("transfer.advertisesid", &advertise_sid);
281+
264282
if (options->advertise_capabilities || !options->stateless_rpc) {
265283
/* serve by default supports v2 */
266284
packet_write_fmt(1, "version 2\n");

t/t5705-session-id-in-capabilities.sh

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/bin/sh
2+
3+
test_description='session ID in capabilities'
4+
5+
. ./test-lib.sh
6+
7+
REPO="$(pwd)/repo"
8+
LOCAL_PRISTINE="$(pwd)/local_pristine"
9+
10+
test_expect_success 'setup repos for session ID capability tests' '
11+
git init "$REPO" &&
12+
test_commit -C "$REPO" a &&
13+
git clone "file://$REPO" "$LOCAL_PRISTINE" &&
14+
test_commit -C "$REPO" b
15+
'
16+
17+
for PROTO in 0 1 2
18+
do
19+
test_expect_success "session IDs not advertised by default (fetch v${PROTO})" '
20+
test_when_finished "rm -rf local tr2-client-events tr2-server-events" &&
21+
cp -r "$LOCAL_PRISTINE" local &&
22+
GIT_TRACE2_EVENT="$(pwd)/tr2-client-events" \
23+
git -c protocol.version=$PROTO -C local fetch \
24+
--upload-pack "GIT_TRACE2_EVENT=\"$(pwd)/tr2-server-events\" git-upload-pack" \
25+
origin &&
26+
test -z "$(grep \"key\":\"server-sid\" tr2-client-events)" &&
27+
test -z "$(grep \"key\":\"client-sid\" tr2-server-events)"
28+
'
29+
30+
test_expect_success "session IDs not advertised by default (push v${PROTO})" '
31+
test_when_finished "rm -rf local tr2-client-events tr2-server-events" &&
32+
test_when_finished "git -C local push --delete origin new-branch" &&
33+
cp -r "$LOCAL_PRISTINE" local &&
34+
git -C local pull --no-rebase origin &&
35+
GIT_TRACE2_EVENT_NESTING=5 \
36+
GIT_TRACE2_EVENT="$(pwd)/tr2-client-events" \
37+
git -c protocol.version=$PROTO -C local push \
38+
--receive-pack "GIT_TRACE2_EVENT=\"$(pwd)/tr2-server-events\" git-receive-pack" \
39+
origin HEAD:new-branch &&
40+
test -z "$(grep \"key\":\"server-sid\" tr2-client-events)" &&
41+
test -z "$(grep \"key\":\"client-sid\" tr2-server-events)"
42+
'
43+
done
44+
45+
test_expect_success 'enable SID advertisement' '
46+
git -C "$REPO" config transfer.advertiseSID true &&
47+
git -C "$LOCAL_PRISTINE" config transfer.advertiseSID true
48+
'
49+
50+
for PROTO in 0 1 2
51+
do
52+
test_expect_success "session IDs advertised (fetch v${PROTO})" '
53+
test_when_finished "rm -rf local tr2-client-events tr2-server-events" &&
54+
cp -r "$LOCAL_PRISTINE" local &&
55+
GIT_TRACE2_EVENT="$(pwd)/tr2-client-events" \
56+
git -c protocol.version=$PROTO -C local fetch \
57+
--upload-pack "GIT_TRACE2_EVENT=\"$(pwd)/tr2-server-events\" git-upload-pack" \
58+
origin &&
59+
grep \"key\":\"server-sid\" tr2-client-events &&
60+
grep \"key\":\"client-sid\" tr2-server-events
61+
'
62+
63+
test_expect_success "session IDs advertised (push v${PROTO})" '
64+
test_when_finished "rm -rf local tr2-client-events tr2-server-events" &&
65+
test_when_finished "git -C local push --delete origin new-branch" &&
66+
cp -r "$LOCAL_PRISTINE" local &&
67+
git -C local pull --no-rebase origin &&
68+
GIT_TRACE2_EVENT_NESTING=5 \
69+
GIT_TRACE2_EVENT="$(pwd)/tr2-client-events" \
70+
git -c protocol.version=$PROTO -C local push \
71+
--receive-pack "GIT_TRACE2_EVENT=\"$(pwd)/tr2-server-events\" git-receive-pack" \
72+
origin HEAD:new-branch &&
73+
grep \"key\":\"server-sid\" tr2-client-events &&
74+
grep \"key\":\"client-sid\" tr2-server-events
75+
'
76+
done
77+
78+
test_done

trace2.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,3 +792,8 @@ void trace2_printf(const char *fmt, ...)
792792
va_end(ap);
793793
}
794794
#endif
795+
796+
const char *trace2_session_id(void)
797+
{
798+
return tr2_sid_get();
799+
}

trace2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,4 +500,6 @@ void trace2_collect_process_info(enum trace2_process_info_reason reason);
500500
} while (0)
501501
#endif
502502

503+
const char *trace2_session_id(void);
504+
503505
#endif /* TRACE2_H */

0 commit comments

Comments
 (0)