1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 #ifndef INCLUDE_transports_smart_h__
8 #define INCLUDE_transports_smart_h__
9 
10 #include "common.h"
11 
12 #include "git2.h"
13 #include "vector.h"
14 #include "netops.h"
15 #include "buffer.h"
16 #include "push.h"
17 #include "git2/sys/transport.h"
18 
19 #define GIT_SIDE_BAND_DATA     1
20 #define GIT_SIDE_BAND_PROGRESS 2
21 #define GIT_SIDE_BAND_ERROR    3
22 
23 #define GIT_CAP_OFS_DELTA "ofs-delta"
24 #define GIT_CAP_MULTI_ACK "multi_ack"
25 #define GIT_CAP_MULTI_ACK_DETAILED "multi_ack_detailed"
26 #define GIT_CAP_SIDE_BAND "side-band"
27 #define GIT_CAP_SIDE_BAND_64K "side-band-64k"
28 #define GIT_CAP_INCLUDE_TAG "include-tag"
29 #define GIT_CAP_DELETE_REFS "delete-refs"
30 #define GIT_CAP_REPORT_STATUS "report-status"
31 #define GIT_CAP_THIN_PACK "thin-pack"
32 #define GIT_CAP_SYMREF "symref"
33 
34 extern bool git_smart__ofs_delta_enabled;
35 
36 typedef enum {
37 	GIT_PKT_CMD,
38 	GIT_PKT_FLUSH,
39 	GIT_PKT_REF,
40 	GIT_PKT_HAVE,
41 	GIT_PKT_ACK,
42 	GIT_PKT_NAK,
43 	GIT_PKT_COMMENT,
44 	GIT_PKT_ERR,
45 	GIT_PKT_DATA,
46 	GIT_PKT_PROGRESS,
47 	GIT_PKT_OK,
48 	GIT_PKT_NG,
49 	GIT_PKT_UNPACK,
50 } git_pkt_type;
51 
52 /* Used for multi_ack and multi_ack_detailed */
53 enum git_ack_status {
54 	GIT_ACK_NONE,
55 	GIT_ACK_CONTINUE,
56 	GIT_ACK_COMMON,
57 	GIT_ACK_READY
58 };
59 
60 /* This would be a flush pkt */
61 typedef struct {
62 	git_pkt_type type;
63 } git_pkt;
64 
65 struct git_pkt_cmd {
66 	git_pkt_type type;
67 	char *cmd;
68 	char *path;
69 	char *host;
70 };
71 
72 /* This is a pkt-line with some info in it */
73 typedef struct {
74 	git_pkt_type type;
75 	git_remote_head head;
76 	char *capabilities;
77 } git_pkt_ref;
78 
79 /* Useful later */
80 typedef struct {
81 	git_pkt_type type;
82 	git_oid oid;
83 	enum git_ack_status status;
84 } git_pkt_ack;
85 
86 typedef struct {
87 	git_pkt_type type;
88 	char comment[GIT_FLEX_ARRAY];
89 } git_pkt_comment;
90 
91 typedef struct {
92 	git_pkt_type type;
93 	size_t len;
94 	char data[GIT_FLEX_ARRAY];
95 } git_pkt_data;
96 
97 typedef git_pkt_data git_pkt_progress;
98 
99 typedef struct {
100 	git_pkt_type type;
101 	size_t len;
102 	char error[GIT_FLEX_ARRAY];
103 } git_pkt_err;
104 
105 typedef struct {
106 	git_pkt_type type;
107 	char *ref;
108 } git_pkt_ok;
109 
110 typedef struct {
111 	git_pkt_type type;
112 	char *ref;
113 	char *msg;
114 } git_pkt_ng;
115 
116 typedef struct {
117 	git_pkt_type type;
118 	int unpack_ok;
119 } git_pkt_unpack;
120 
121 typedef struct transport_smart_caps {
122 	int common:1,
123 		ofs_delta:1,
124 		multi_ack: 1,
125 		multi_ack_detailed: 1,
126 		side_band:1,
127 		side_band_64k:1,
128 		include_tag:1,
129 		delete_refs:1,
130 		report_status:1,
131 		thin_pack:1;
132 } transport_smart_caps;
133 
134 typedef int (*packetsize_cb)(size_t received, void *payload);
135 
136 typedef struct {
137 	git_transport parent;
138 	git_remote *owner;
139 	char *url;
140 	git_credential_acquire_cb cred_acquire_cb;
141 	void *cred_acquire_payload;
142 	git_proxy_options proxy;
143 	int direction;
144 	int flags;
145 	git_transport_message_cb progress_cb;
146 	git_transport_message_cb error_cb;
147 	git_transport_certificate_check_cb certificate_check_cb;
148 	void *message_cb_payload;
149 	git_strarray custom_headers;
150 	git_smart_subtransport *wrapped;
151 	git_smart_subtransport_stream *current_stream;
152 	transport_smart_caps caps;
153 	git_vector refs;
154 	git_vector heads;
155 	git_vector common;
156 	git_atomic32 cancelled;
157 	packetsize_cb packetsize_cb;
158 	void *packetsize_payload;
159 	unsigned rpc : 1,
160 		have_refs : 1,
161 		connected : 1;
162 	gitno_buffer buffer;
163 	char buffer_data[65536];
164 } transport_smart;
165 
166 /* smart_protocol.c */
167 int git_smart__store_refs(transport_smart *t, int flushes);
168 int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vector *symrefs);
169 int git_smart__push(git_transport *transport, git_push *push, const git_remote_callbacks *cbs);
170 
171 int git_smart__negotiate_fetch(
172 	git_transport *transport,
173 	git_repository *repo,
174 	const git_remote_head * const *refs,
175 	size_t count);
176 
177 int git_smart__download_pack(
178 	git_transport *transport,
179 	git_repository *repo,
180 	git_indexer_progress *stats,
181 	git_indexer_progress_cb progress_cb,
182 	void *progress_payload);
183 
184 /* smart.c */
185 int git_smart__negotiation_step(git_transport *transport, void *data, size_t len);
186 int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream **out);
187 
188 int git_smart__update_heads(transport_smart *t, git_vector *symrefs);
189 
190 /* smart_pkt.c */
191 int git_pkt_parse_line(git_pkt **head, const char **endptr, const char *line, size_t linelen);
192 int git_pkt_buffer_flush(git_buf *buf);
193 int git_pkt_send_flush(GIT_SOCKET s);
194 int git_pkt_buffer_done(git_buf *buf);
195 int git_pkt_buffer_wants(const git_remote_head * const *refs, size_t count, transport_smart_caps *caps, git_buf *buf);
196 int git_pkt_buffer_have(git_oid *oid, git_buf *buf);
197 void git_pkt_free(git_pkt *pkt);
198 
199 #endif
200