Fossil SCM

In the sync protocol, never send a gimme card for a phantom that we know the other side lacks because it has previously sent us the same gimme card.

drh 2020-07-03 20:54 trunk
Commit 405457c1613710562744ca77eb9e5ee84a05c4bd5a48e07404bb96365372fa1b
1 file changed +21 -4
+21 -4
--- src/xfer.c
+++ src/xfer.c
@@ -96,10 +96,22 @@
9696
db_bind_int(&q, ":r", rid);
9797
db_step(&q);
9898
db_reset(&q);
9999
}
100100
}
101
+
102
+/*
103
+** Remember that the other side of the connection lacks a copy of
104
+** the artifact with the given hash.
105
+*/
106
+static void remote_unk(Blob *pHash){
107
+ static Stmt q;
108
+ db_static_prepare(&q, "INSERT OR IGNORE INTO unk VALUES(:h)");
109
+ db_bind_text(&q, ":h", blob_str(pHash));
110
+ db_step(&q);
111
+ db_reset(&q);
112
+}
101113
102114
/*
103115
** The aToken[0..nToken-1] blob array is a parse of a "file" line
104116
** message. This routine finishes parsing that message and does
105117
** a record insert of the file.
@@ -749,11 +761,12 @@
749761
*/
750762
static void request_phantoms(Xfer *pXfer, int maxReq){
751763
Stmt q;
752764
db_prepare(&q,
753765
"SELECT uuid FROM phantom CROSS JOIN blob USING(rid) /*scan*/"
754
- " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
766
+ " WHERE NOT EXISTS(SELECT 1 FROM unk WHERE unk.uuid=blob.uuid)"
767
+ " AND NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
755768
(pXfer->syncPrivate ? "" :
756769
" AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
757770
);
758771
while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
759772
const char *zUuid = db_column_text(&q, 0);
@@ -1203,10 +1216,11 @@
12031216
g.xferPanic = 1;
12041217
12051218
db_begin_transaction();
12061219
db_multi_exec(
12071220
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
1221
+ "CREATE TEMP TABLE unk(uuid TEXT PRIMARY KEY) WITHOUT ROWID;"
12081222
);
12091223
manifest_crosslink_begin();
12101224
rc = xfer_run_common_script();
12111225
if( rc==TH_ERROR ){
12121226
cgi_reset_content();
@@ -1286,10 +1300,11 @@
12861300
if( blob_eq(&xfer.aToken[0], "gimme")
12871301
&& xfer.nToken==2
12881302
&& blob_is_hname(&xfer.aToken[1])
12891303
){
12901304
nGimme++;
1305
+ remote_unk(&xfer.aToken[1]);
12911306
if( isPull ){
12921307
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
12931308
if( rid ){
12941309
send_file(&xfer, rid, &xfer.aToken[1], deltaFlag);
12951310
}
@@ -1724,11 +1739,11 @@
17241739
}else if( isPull ){
17251740
create_cluster();
17261741
send_unclustered(&xfer);
17271742
if( xfer.syncPrivate ) send_private(&xfer);
17281743
}
1729
- db_multi_exec("DROP TABLE onremote");
1744
+ db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
17301745
manifest_crosslink_end(MC_PERMIT_HOOKS);
17311746
17321747
/* Send the server timestamp last, in case prior processing happened
17331748
** to use up a significant fraction of our time window.
17341749
*/
@@ -1964,10 +1979,11 @@
19641979
char *zRandomness;
19651980
db_begin_transaction();
19661981
db_record_repository_filename(0);
19671982
db_multi_exec(
19681983
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
1984
+ "CREATE TEMP TABLE unk(uuid TEXT PRIMARY KEY) WITHOUT ROWID;"
19691985
);
19701986
manifest_crosslink_begin();
19711987
19721988
19731989
/* Client sends the most recently received cookie back to the server.
@@ -2227,10 +2243,11 @@
22272243
*/
22282244
if( blob_eq(&xfer.aToken[0], "gimme")
22292245
&& xfer.nToken==2
22302246
&& blob_is_hname(&xfer.aToken[1])
22312247
){
2248
+ remote_unk(&xfer.aToken[1]);
22322249
if( syncFlags & SYNC_PUSH ){
22332250
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
22342251
if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
22352252
}
22362253
}else
@@ -2603,11 +2620,11 @@
26032620
26042621
/* Continue looping as long as new uvfile cards are being received
26052622
** and uvgimme cards are being sent. */
26062623
if( nUvGimmeSent>0 && (nUvFileRcvd>0 || nCycle<3) ) go = 1;
26072624
2608
- db_multi_exec("DROP TABLE onremote");
2625
+ db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
26092626
if( go ){
26102627
manifest_crosslink_end(MC_PERMIT_HOOKS);
26112628
}else{
26122629
manifest_crosslink_end(MC_PERMIT_HOOKS);
26132630
content_enable_dephantomize(1);
@@ -2630,11 +2647,11 @@
26302647
"%s done, sent: %lld received: %lld ip: %s\n",
26312648
zOpType, nSent, nRcvd, g.zIpAddr);
26322649
transport_close(&g.url);
26332650
transport_global_shutdown(&g.url);
26342651
if( nErr && go==2 ){
2635
- db_multi_exec("DROP TABLE onremote");
2652
+ db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
26362653
manifest_crosslink_end(MC_PERMIT_HOOKS);
26372654
content_enable_dephantomize(1);
26382655
db_end_transaction(0);
26392656
}
26402657
if( nErr && autopushFailed ){
26412658
--- src/xfer.c
+++ src/xfer.c
@@ -96,10 +96,22 @@
96 db_bind_int(&q, ":r", rid);
97 db_step(&q);
98 db_reset(&q);
99 }
100 }
 
 
 
 
 
 
 
 
 
 
 
 
101
102 /*
103 ** The aToken[0..nToken-1] blob array is a parse of a "file" line
104 ** message. This routine finishes parsing that message and does
105 ** a record insert of the file.
@@ -749,11 +761,12 @@
749 */
750 static void request_phantoms(Xfer *pXfer, int maxReq){
751 Stmt q;
752 db_prepare(&q,
753 "SELECT uuid FROM phantom CROSS JOIN blob USING(rid) /*scan*/"
754 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
 
755 (pXfer->syncPrivate ? "" :
756 " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
757 );
758 while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
759 const char *zUuid = db_column_text(&q, 0);
@@ -1203,10 +1216,11 @@
1203 g.xferPanic = 1;
1204
1205 db_begin_transaction();
1206 db_multi_exec(
1207 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
 
1208 );
1209 manifest_crosslink_begin();
1210 rc = xfer_run_common_script();
1211 if( rc==TH_ERROR ){
1212 cgi_reset_content();
@@ -1286,10 +1300,11 @@
1286 if( blob_eq(&xfer.aToken[0], "gimme")
1287 && xfer.nToken==2
1288 && blob_is_hname(&xfer.aToken[1])
1289 ){
1290 nGimme++;
 
1291 if( isPull ){
1292 int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
1293 if( rid ){
1294 send_file(&xfer, rid, &xfer.aToken[1], deltaFlag);
1295 }
@@ -1724,11 +1739,11 @@
1724 }else if( isPull ){
1725 create_cluster();
1726 send_unclustered(&xfer);
1727 if( xfer.syncPrivate ) send_private(&xfer);
1728 }
1729 db_multi_exec("DROP TABLE onremote");
1730 manifest_crosslink_end(MC_PERMIT_HOOKS);
1731
1732 /* Send the server timestamp last, in case prior processing happened
1733 ** to use up a significant fraction of our time window.
1734 */
@@ -1964,10 +1979,11 @@
1964 char *zRandomness;
1965 db_begin_transaction();
1966 db_record_repository_filename(0);
1967 db_multi_exec(
1968 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
 
1969 );
1970 manifest_crosslink_begin();
1971
1972
1973 /* Client sends the most recently received cookie back to the server.
@@ -2227,10 +2243,11 @@
2227 */
2228 if( blob_eq(&xfer.aToken[0], "gimme")
2229 && xfer.nToken==2
2230 && blob_is_hname(&xfer.aToken[1])
2231 ){
 
2232 if( syncFlags & SYNC_PUSH ){
2233 int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
2234 if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
2235 }
2236 }else
@@ -2603,11 +2620,11 @@
2603
2604 /* Continue looping as long as new uvfile cards are being received
2605 ** and uvgimme cards are being sent. */
2606 if( nUvGimmeSent>0 && (nUvFileRcvd>0 || nCycle<3) ) go = 1;
2607
2608 db_multi_exec("DROP TABLE onremote");
2609 if( go ){
2610 manifest_crosslink_end(MC_PERMIT_HOOKS);
2611 }else{
2612 manifest_crosslink_end(MC_PERMIT_HOOKS);
2613 content_enable_dephantomize(1);
@@ -2630,11 +2647,11 @@
2630 "%s done, sent: %lld received: %lld ip: %s\n",
2631 zOpType, nSent, nRcvd, g.zIpAddr);
2632 transport_close(&g.url);
2633 transport_global_shutdown(&g.url);
2634 if( nErr && go==2 ){
2635 db_multi_exec("DROP TABLE onremote");
2636 manifest_crosslink_end(MC_PERMIT_HOOKS);
2637 content_enable_dephantomize(1);
2638 db_end_transaction(0);
2639 }
2640 if( nErr && autopushFailed ){
2641
--- src/xfer.c
+++ src/xfer.c
@@ -96,10 +96,22 @@
96 db_bind_int(&q, ":r", rid);
97 db_step(&q);
98 db_reset(&q);
99 }
100 }
101
102 /*
103 ** Remember that the other side of the connection lacks a copy of
104 ** the artifact with the given hash.
105 */
106 static void remote_unk(Blob *pHash){
107 static Stmt q;
108 db_static_prepare(&q, "INSERT OR IGNORE INTO unk VALUES(:h)");
109 db_bind_text(&q, ":h", blob_str(pHash));
110 db_step(&q);
111 db_reset(&q);
112 }
113
114 /*
115 ** The aToken[0..nToken-1] blob array is a parse of a "file" line
116 ** message. This routine finishes parsing that message and does
117 ** a record insert of the file.
@@ -749,11 +761,12 @@
761 */
762 static void request_phantoms(Xfer *pXfer, int maxReq){
763 Stmt q;
764 db_prepare(&q,
765 "SELECT uuid FROM phantom CROSS JOIN blob USING(rid) /*scan*/"
766 " WHERE NOT EXISTS(SELECT 1 FROM unk WHERE unk.uuid=blob.uuid)"
767 " AND NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
768 (pXfer->syncPrivate ? "" :
769 " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
770 );
771 while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
772 const char *zUuid = db_column_text(&q, 0);
@@ -1203,10 +1216,11 @@
1216 g.xferPanic = 1;
1217
1218 db_begin_transaction();
1219 db_multi_exec(
1220 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
1221 "CREATE TEMP TABLE unk(uuid TEXT PRIMARY KEY) WITHOUT ROWID;"
1222 );
1223 manifest_crosslink_begin();
1224 rc = xfer_run_common_script();
1225 if( rc==TH_ERROR ){
1226 cgi_reset_content();
@@ -1286,10 +1300,11 @@
1300 if( blob_eq(&xfer.aToken[0], "gimme")
1301 && xfer.nToken==2
1302 && blob_is_hname(&xfer.aToken[1])
1303 ){
1304 nGimme++;
1305 remote_unk(&xfer.aToken[1]);
1306 if( isPull ){
1307 int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
1308 if( rid ){
1309 send_file(&xfer, rid, &xfer.aToken[1], deltaFlag);
1310 }
@@ -1724,11 +1739,11 @@
1739 }else if( isPull ){
1740 create_cluster();
1741 send_unclustered(&xfer);
1742 if( xfer.syncPrivate ) send_private(&xfer);
1743 }
1744 db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
1745 manifest_crosslink_end(MC_PERMIT_HOOKS);
1746
1747 /* Send the server timestamp last, in case prior processing happened
1748 ** to use up a significant fraction of our time window.
1749 */
@@ -1964,10 +1979,11 @@
1979 char *zRandomness;
1980 db_begin_transaction();
1981 db_record_repository_filename(0);
1982 db_multi_exec(
1983 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
1984 "CREATE TEMP TABLE unk(uuid TEXT PRIMARY KEY) WITHOUT ROWID;"
1985 );
1986 manifest_crosslink_begin();
1987
1988
1989 /* Client sends the most recently received cookie back to the server.
@@ -2227,10 +2243,11 @@
2243 */
2244 if( blob_eq(&xfer.aToken[0], "gimme")
2245 && xfer.nToken==2
2246 && blob_is_hname(&xfer.aToken[1])
2247 ){
2248 remote_unk(&xfer.aToken[1]);
2249 if( syncFlags & SYNC_PUSH ){
2250 int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
2251 if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
2252 }
2253 }else
@@ -2603,11 +2620,11 @@
2620
2621 /* Continue looping as long as new uvfile cards are being received
2622 ** and uvgimme cards are being sent. */
2623 if( nUvGimmeSent>0 && (nUvFileRcvd>0 || nCycle<3) ) go = 1;
2624
2625 db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
2626 if( go ){
2627 manifest_crosslink_end(MC_PERMIT_HOOKS);
2628 }else{
2629 manifest_crosslink_end(MC_PERMIT_HOOKS);
2630 content_enable_dephantomize(1);
@@ -2630,11 +2647,11 @@
2647 "%s done, sent: %lld received: %lld ip: %s\n",
2648 zOpType, nSent, nRcvd, g.zIpAddr);
2649 transport_close(&g.url);
2650 transport_global_shutdown(&g.url);
2651 if( nErr && go==2 ){
2652 db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
2653 manifest_crosslink_end(MC_PERMIT_HOOKS);
2654 content_enable_dephantomize(1);
2655 db_end_transaction(0);
2656 }
2657 if( nErr && autopushFailed ){
2658

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button