Check-in [405457c161]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 405457c1613710562744ca77eb9e5ee84a05c4bd5a48e07404bb96365372fa1b
User & Date: drh 2020-07-03 20:54:08.483
Context
2020-07-05
13:14
Fix output formatting in the "fossil tls-config show" command. check-in: 8c50f807b7 user: drh tags: trunk
2020-07-03
20:54
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. check-in: 405457c161 user: drh tags: trunk
14:06
isspace() -> fossil_isspace() check-in: 1d9e0897e3 user: jan.nijtmans tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/xfer.c.
94
95
96
97
98
99
100












101
102
103
104
105
106
107
    static Stmt q;
    db_static_prepare(&q, "INSERT OR IGNORE INTO onremote VALUES(:r)");
    db_bind_int(&q, ":r", rid);
    db_step(&q);
    db_reset(&q);
  }
}













/*
** The aToken[0..nToken-1] blob array is a parse of a "file" line
** message.  This routine finishes parsing that message and does
** a record insert of the file.
**
** The file line is in one of the following two forms:







>
>
>
>
>
>
>
>
>
>
>
>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    static Stmt q;
    db_static_prepare(&q, "INSERT OR IGNORE INTO onremote VALUES(:r)");
    db_bind_int(&q, ":r", rid);
    db_step(&q);
    db_reset(&q);
  }
}

/*
** Remember that the other side of the connection lacks a copy of
** the artifact with the given hash.
*/
static void remote_unk(Blob *pHash){
  static Stmt q;
  db_static_prepare(&q, "INSERT OR IGNORE INTO unk VALUES(:h)");
  db_bind_text(&q, ":h", blob_str(pHash));
  db_step(&q);
  db_reset(&q);
}

/*
** The aToken[0..nToken-1] blob array is a parse of a "file" line
** message.  This routine finishes parsing that message and does
** a record insert of the file.
**
** The file line is in one of the following two forms:
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
** Except: do not request shunned artifacts.  And do not request
** private artifacts if we are not doing a private transfer.
*/
static void request_phantoms(Xfer *pXfer, int maxReq){
  Stmt q;
  db_prepare(&q,
    "SELECT uuid FROM phantom CROSS JOIN blob USING(rid) /*scan*/"

    " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
    (pXfer->syncPrivate ? "" :
         "   AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
  );
  while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
    const char *zUuid = db_column_text(&q, 0);
    blob_appendf(pXfer->pOut, "gimme %s\n", zUuid);
    pXfer->nGimmeSent++;







>
|







759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
** Except: do not request shunned artifacts.  And do not request
** private artifacts if we are not doing a private transfer.
*/
static void request_phantoms(Xfer *pXfer, int maxReq){
  Stmt q;
  db_prepare(&q,
    "SELECT uuid FROM phantom CROSS JOIN blob USING(rid) /*scan*/"
    " WHERE NOT EXISTS(SELECT 1 FROM unk WHERE unk.uuid=blob.uuid)"
    "   AND NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
    (pXfer->syncPrivate ? "" :
         "   AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
  );
  while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
    const char *zUuid = db_column_text(&q, 0);
    blob_appendf(pXfer->pOut, "gimme %s\n", zUuid);
    pXfer->nGimmeSent++;
1201
1202
1203
1204
1205
1206
1207

1208
1209
1210
1211
1212
1213
1214
  if( xfer.maxTime<1 ) xfer.maxTime = 1;
  xfer.maxTime += time(NULL);
  g.xferPanic = 1;

  db_begin_transaction();
  db_multi_exec(
     "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"

  );
  manifest_crosslink_begin();
  rc = xfer_run_common_script();
  if( rc==TH_ERROR ){
    cgi_reset_content();
    @ error common\sscript\sfailed:\s%F(g.zErrMsg)
    nErr++;







>







1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
  if( xfer.maxTime<1 ) xfer.maxTime = 1;
  xfer.maxTime += time(NULL);
  g.xferPanic = 1;

  db_begin_transaction();
  db_multi_exec(
     "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
     "CREATE TEMP TABLE unk(uuid TEXT PRIMARY KEY) WITHOUT ROWID;"
  );
  manifest_crosslink_begin();
  rc = xfer_run_common_script();
  if( rc==TH_ERROR ){
    cgi_reset_content();
    @ error common\sscript\sfailed:\s%F(g.zErrMsg)
    nErr++;
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
    ** Client is requesting a file from the server.  Send it.
    */
    if( blob_eq(&xfer.aToken[0], "gimme")
     && xfer.nToken==2
     && blob_is_hname(&xfer.aToken[1])
    ){
      nGimme++;

      if( isPull ){
        int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
        if( rid ){
          send_file(&xfer, rid, &xfer.aToken[1], deltaFlag);
        }
      }
    }else







>







1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
    ** Client is requesting a file from the server.  Send it.
    */
    if( blob_eq(&xfer.aToken[0], "gimme")
     && xfer.nToken==2
     && blob_is_hname(&xfer.aToken[1])
    ){
      nGimme++;
      remote_unk(&xfer.aToken[1]);
      if( isPull ){
        int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
        if( rid ){
          send_file(&xfer, rid, &xfer.aToken[1], deltaFlag);
        }
      }
    }else
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
    send_all(&xfer);
    if( xfer.syncPrivate ) send_private(&xfer);
  }else if( isPull ){
    create_cluster();
    send_unclustered(&xfer);
    if( xfer.syncPrivate ) send_private(&xfer);
  }
  db_multi_exec("DROP TABLE onremote");
  manifest_crosslink_end(MC_PERMIT_HOOKS);

  /* Send the server timestamp last, in case prior processing happened
  ** to use up a significant fraction of our time window.
  */
  zNow = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S', 'now')");
  @ # timestamp %s(zNow)







|







1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
    send_all(&xfer);
    if( xfer.syncPrivate ) send_private(&xfer);
  }else if( isPull ){
    create_cluster();
    send_unclustered(&xfer);
    if( xfer.syncPrivate ) send_private(&xfer);
  }
  db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
  manifest_crosslink_end(MC_PERMIT_HOOKS);

  /* Send the server timestamp last, in case prior processing happened
  ** to use up a significant fraction of our time window.
  */
  zNow = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S', 'now')");
  @ # timestamp %s(zNow)
1962
1963
1964
1965
1966
1967
1968

1969
1970
1971
1972
1973
1974
1975
  while( go ){
    int newPhantom = 0;
    char *zRandomness;
    db_begin_transaction();
    db_record_repository_filename(0);
    db_multi_exec(
      "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"

    );
    manifest_crosslink_begin();


    /* Client sends the most recently received cookie back to the server.
    ** Let the server figure out if this is a cookie that it cares about.
    */







>







1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
  while( go ){
    int newPhantom = 0;
    char *zRandomness;
    db_begin_transaction();
    db_record_repository_filename(0);
    db_multi_exec(
      "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
      "CREATE TEMP TABLE unk(uuid TEXT PRIMARY KEY) WITHOUT ROWID;"
    );
    manifest_crosslink_begin();


    /* Client sends the most recently received cookie back to the server.
    ** Let the server figure out if this is a cookie that it cares about.
    */
2225
2226
2227
2228
2229
2230
2231

2232
2233
2234
2235
2236
2237
2238
      ** to know all of the content artifacts associated with the manifest
      ** and send those too.
      */
      if( blob_eq(&xfer.aToken[0], "gimme")
       && xfer.nToken==2
       && blob_is_hname(&xfer.aToken[1])
      ){

        if( syncFlags & SYNC_PUSH ){
          int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
          if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
        }
      }else

      /*   igot HASH  ?PRIVATEFLAG?







>







2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
      ** to know all of the content artifacts associated with the manifest
      ** and send those too.
      */
      if( blob_eq(&xfer.aToken[0], "gimme")
       && xfer.nToken==2
       && blob_is_hname(&xfer.aToken[1])
      ){
        remote_unk(&xfer.aToken[1]);
        if( syncFlags & SYNC_PUSH ){
          int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
          if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
        }
      }else

      /*   igot HASH  ?PRIVATEFLAG?
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
    */
    if( cloneSeqno<=0 && nCycle>1 ) go = 0;

    /* Continue looping as long as new uvfile cards are being received
    ** and uvgimme cards are being sent. */
    if( nUvGimmeSent>0 && (nUvFileRcvd>0 || nCycle<3) ) go = 1;

    db_multi_exec("DROP TABLE onremote");
    if( go ){
      manifest_crosslink_end(MC_PERMIT_HOOKS);
    }else{
      manifest_crosslink_end(MC_PERMIT_HOOKS);
      content_enable_dephantomize(1);
    }
    db_end_transaction(0);







|







2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
    */
    if( cloneSeqno<=0 && nCycle>1 ) go = 0;

    /* Continue looping as long as new uvfile cards are being received
    ** and uvgimme cards are being sent. */
    if( nUvGimmeSent>0 && (nUvFileRcvd>0 || nCycle<3) ) go = 1;

    db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
    if( go ){
      manifest_crosslink_end(MC_PERMIT_HOOKS);
    }else{
      manifest_crosslink_end(MC_PERMIT_HOOKS);
      content_enable_dephantomize(1);
    }
    db_end_transaction(0);
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
  fossil_force_newline();
  fossil_print(
     "%s done, sent: %lld  received: %lld  ip: %s\n",
     zOpType, nSent, nRcvd, g.zIpAddr);
  transport_close(&g.url);
  transport_global_shutdown(&g.url);
  if( nErr && go==2 ){
    db_multi_exec("DROP TABLE onremote");
    manifest_crosslink_end(MC_PERMIT_HOOKS);
    content_enable_dephantomize(1);
    db_end_transaction(0);
  }
  if( nErr && autopushFailed ){
    fossil_warning(
      "Warning: The check-in was successful and is saved locally but you\n"







|







2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
  fossil_force_newline();
  fossil_print(
     "%s done, sent: %lld  received: %lld  ip: %s\n",
     zOpType, nSent, nRcvd, g.zIpAddr);
  transport_close(&g.url);
  transport_global_shutdown(&g.url);
  if( nErr && go==2 ){
    db_multi_exec("DROP TABLE onremote; DROP TABLE unk;");
    manifest_crosslink_end(MC_PERMIT_HOOKS);
    content_enable_dephantomize(1);
    db_end_transaction(0);
  }
  if( nErr && autopushFailed ){
    fossil_warning(
      "Warning: The check-in was successful and is saved locally but you\n"