Hex Artifact Content
Not logged in

Artifact 4b0a0159248a3c8025c0624c8fd638c487ec154f:


0000: 2f 2a 20 43 6f 70 79 72 69 67 68 74 20 28 63 29  /* Copyright (c)
0010: 20 32 30 31 31 20 6d 61 69 64 73 61 66 65 2e 6e   2011 maidsafe.n
0020: 65 74 20 6c 69 6d 69 74 65 64 0a 41 6c 6c 20 72  et limited.All r
0030: 69 67 68 74 73 20 72 65 73 65 72 76 65 64 2e 0a  ights reserved..
0040: 0a 52 65 64 69 73 74 72 69 62 75 74 69 6f 6e 20  .Redistribution 
0050: 61 6e 64 20 75 73 65 20 69 6e 20 73 6f 75 72 63  and use in sourc
0060: 65 20 61 6e 64 20 62 69 6e 61 72 79 20 66 6f 72  e and binary for
0070: 6d 73 2c 20 77 69 74 68 20 6f 72 20 77 69 74 68  ms, with or with
0080: 6f 75 74 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e  out modification
0090: 2c 0a 61 72 65 20 70 65 72 6d 69 74 74 65 64 20  ,.are permitted 
00a0: 70 72 6f 76 69 64 65 64 20 74 68 61 74 20 74 68  provided that th
00b0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 6e 64  e following cond
00c0: 69 74 69 6f 6e 73 20 61 72 65 20 6d 65 74 3a 0a  itions are met:.
00d0: 0a 20 20 20 20 2a 20 52 65 64 69 73 74 72 69 62  .    * Redistrib
00e0: 75 74 69 6f 6e 73 20 6f 66 20 73 6f 75 72 63 65  utions of source
00f0: 20 63 6f 64 65 20 6d 75 73 74 20 72 65 74 61 69   code must retai
0100: 6e 20 74 68 65 20 61 62 6f 76 65 20 63 6f 70 79  n the above copy
0110: 72 69 67 68 74 20 6e 6f 74 69 63 65 2c 0a 20 20  right notice,.  
0120: 20 20 74 68 69 73 20 6c 69 73 74 20 6f 66 20 63    this list of c
0130: 6f 6e 64 69 74 69 6f 6e 73 20 61 6e 64 20 74 68  onditions and th
0140: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 64 69 73 63  e following disc
0150: 6c 61 69 6d 65 72 2e 0a 20 20 20 20 2a 20 52 65  laimer..    * Re
0160: 64 69 73 74 72 69 62 75 74 69 6f 6e 73 20 69 6e  distributions in
0170: 20 62 69 6e 61 72 79 20 66 6f 72 6d 20 6d 75 73   binary form mus
0180: 74 20 72 65 70 72 6f 64 75 63 65 20 74 68 65 20  t reproduce the 
0190: 61 62 6f 76 65 20 63 6f 70 79 72 69 67 68 74 20  above copyright 
01a0: 6e 6f 74 69 63 65 2c 0a 20 20 20 20 74 68 69 73  notice,.    this
01b0: 20 6c 69 73 74 20 6f 66 20 63 6f 6e 64 69 74 69   list of conditi
01c0: 6f 6e 73 20 61 6e 64 20 74 68 65 20 66 6f 6c 6c  ons and the foll
01d0: 6f 77 69 6e 67 20 64 69 73 63 6c 61 69 6d 65 72  owing disclaimer
01e0: 20 69 6e 20 74 68 65 20 64 6f 63 75 6d 65 6e 74   in the document
01f0: 61 74 69 6f 6e 0a 20 20 20 20 61 6e 64 2f 6f 72  ation.    and/or
0200: 20 6f 74 68 65 72 20 6d 61 74 65 72 69 61 6c 73   other materials
0210: 20 70 72 6f 76 69 64 65 64 20 77 69 74 68 20 74   provided with t
0220: 68 65 20 64 69 73 74 72 69 62 75 74 69 6f 6e 2e  he distribution.
0230: 0a 20 20 20 20 2a 20 4e 65 69 74 68 65 72 20 74  .    * Neither t
0240: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 6d  he name of the m
0250: 61 69 64 73 61 66 65 2e 6e 65 74 20 6c 69 6d 69  aidsafe.net limi
0260: 74 65 64 20 6e 6f 72 20 74 68 65 20 6e 61 6d 65  ted nor the name
0270: 73 20 6f 66 20 69 74 73 0a 20 20 20 20 63 6f 6e  s of its.    con
0280: 74 72 69 62 75 74 6f 72 73 20 6d 61 79 20 62 65  tributors may be
0290: 20 75 73 65 64 20 74 6f 20 65 6e 64 6f 72 73 65   used to endorse
02a0: 20 6f 72 20 70 72 6f 6d 6f 74 65 20 70 72 6f 64   or promote prod
02b0: 75 63 74 73 20 64 65 72 69 76 65 64 20 66 72 6f  ucts derived fro
02c0: 6d 20 74 68 69 73 0a 20 20 20 20 73 6f 66 74 77  m this.    softw
02d0: 61 72 65 20 77 69 74 68 6f 75 74 20 73 70 65 63  are without spec
02e0: 69 66 69 63 20 70 72 69 6f 72 20 77 72 69 74 74  ific prior writt
02f0: 65 6e 20 70 65 72 6d 69 73 73 69 6f 6e 2e 0a 0a  en permission...
0300: 54 48 49 53 20 53 4f 46 54 57 41 52 45 20 49 53  THIS SOFTWARE IS
0310: 20 50 52 4f 56 49 44 45 44 20 42 59 20 54 48 45   PROVIDED BY THE
0320: 20 43 4f 50 59 52 49 47 48 54 20 48 4f 4c 44 45   COPYRIGHT HOLDE
0330: 52 53 20 41 4e 44 20 43 4f 4e 54 52 49 42 55 54  RS AND CONTRIBUT
0340: 4f 52 53 20 22 41 53 20 49 53 22 20 41 4e 44 0a  ORS "AS IS" AND.
0350: 41 4e 59 20 45 58 50 52 45 53 53 20 4f 52 20 49  ANY EXPRESS OR I
0360: 4d 50 4c 49 45 44 20 57 41 52 52 41 4e 54 49 45  MPLIED WARRANTIE
0370: 53 2c 20 49 4e 43 4c 55 44 49 4e 47 2c 20 42 55  S, INCLUDING, BU
0380: 54 20 4e 4f 54 20 4c 49 4d 49 54 45 44 20 54 4f  T NOT LIMITED TO
0390: 2c 20 54 48 45 20 49 4d 50 4c 49 45 44 0a 57 41  , THE IMPLIED.WA
03a0: 52 52 41 4e 54 49 45 53 20 4f 46 20 4d 45 52 43  RRANTIES OF MERC
03b0: 48 41 4e 54 41 42 49 4c 49 54 59 20 41 4e 44 20  HANTABILITY AND 
03c0: 46 49 54 4e 45 53 53 20 46 4f 52 20 41 20 50 41  FITNESS FOR A PA
03d0: 52 54 49 43 55 4c 41 52 20 50 55 52 50 4f 53 45  RTICULAR PURPOSE
03e0: 20 41 52 45 0a 44 49 53 43 4c 41 49 4d 45 44 2e   ARE.DISCLAIMED.
03f0: 20 20 49 4e 20 4e 4f 20 45 56 45 4e 54 20 53 48    IN NO EVENT SH
0400: 41 4c 4c 20 54 48 45 20 43 4f 50 59 52 49 47 48  ALL THE COPYRIGH
0410: 54 20 48 4f 4c 44 45 52 20 4f 52 20 43 4f 4e 54  T HOLDER OR CONT
0420: 52 49 42 55 54 4f 52 53 20 42 45 20 4c 49 41 42  RIBUTORS BE LIAB
0430: 4c 45 0a 46 4f 52 20 41 4e 59 20 44 49 52 45 43  LE.FOR ANY DIREC
0440: 54 2c 20 49 4e 44 49 52 45 43 54 2c 20 49 4e 43  T, INDIRECT, INC
0450: 49 44 45 4e 54 41 4c 2c 20 53 50 45 43 49 41 4c  IDENTAL, SPECIAL
0460: 2c 20 45 58 45 4d 50 4c 41 52 59 2c 20 4f 52 20  , EXEMPLARY, OR 
0470: 43 4f 4e 53 45 51 55 45 4e 54 49 41 4c 0a 44 41  CONSEQUENTIAL.DA
0480: 4d 41 47 45 53 20 28 49 4e 43 4c 55 44 49 4e 47  MAGES (INCLUDING
0490: 2c 20 42 55 54 20 4e 4f 54 20 4c 49 4d 49 54 45  , BUT NOT LIMITE
04a0: 44 20 54 4f 2c 20 50 52 4f 43 55 52 45 4d 45 4e  D TO, PROCUREMEN
04b0: 54 20 4f 46 20 53 55 42 53 54 49 54 55 54 45 20  T OF SUBSTITUTE 
04c0: 47 4f 4f 44 53 20 4f 52 0a 53 45 52 56 49 43 45  GOODS OR.SERVICE
04d0: 53 3b 20 4c 4f 53 53 20 4f 46 20 55 53 45 2c 20  S; LOSS OF USE, 
04e0: 44 41 54 41 2c 20 4f 52 20 50 52 4f 46 49 54 53  DATA, OR PROFITS
04f0: 3b 20 4f 52 20 42 55 53 49 4e 45 53 53 20 49 4e  ; OR BUSINESS IN
0500: 54 45 52 52 55 50 54 49 4f 4e 29 20 48 4f 57 45  TERRUPTION) HOWE
0510: 56 45 52 0a 43 41 55 53 45 44 20 41 4e 44 20 4f  VER.CAUSED AND O
0520: 4e 20 41 4e 59 20 54 48 45 4f 52 59 20 4f 46 20  N ANY THEORY OF 
0530: 4c 49 41 42 49 4c 49 54 59 2c 20 57 48 45 54 48  LIABILITY, WHETH
0540: 45 52 20 49 4e 20 43 4f 4e 54 52 41 43 54 2c 20  ER IN CONTRACT, 
0550: 53 54 52 49 43 54 20 4c 49 41 42 49 4c 49 54 59  STRICT LIABILITY
0560: 2c 20 4f 52 0a 54 4f 52 54 20 28 49 4e 43 4c 55  , OR.TORT (INCLU
0570: 44 49 4e 47 20 4e 45 47 4c 49 47 45 4e 43 45 20  DING NEGLIGENCE 
0580: 4f 52 20 4f 54 48 45 52 57 49 53 45 29 20 41 52  OR OTHERWISE) AR
0590: 49 53 49 4e 47 20 49 4e 20 41 4e 59 20 57 41 59  ISING IN ANY WAY
05a0: 20 4f 55 54 20 4f 46 20 54 48 45 20 55 53 45 20   OUT OF THE USE 
05b0: 4f 46 0a 54 48 49 53 20 53 4f 46 54 57 41 52 45  OF.THIS SOFTWARE
05c0: 2c 20 45 56 45 4e 20 49 46 20 41 44 56 49 53 45  , EVEN IF ADVISE
05d0: 44 20 4f 46 20 54 48 45 20 50 4f 53 53 49 42 49  D OF THE POSSIBI
05e0: 4c 49 54 59 20 4f 46 20 53 55 43 48 20 44 41 4d  LITY OF SUCH DAM
05f0: 41 47 45 2e 0a 2a 2f 0a 0a 0a 23 69 66 6e 64 65  AGE..*/...#ifnde
0600: 66 20 4d 41 49 44 53 41 46 45 5f 44 48 54 5f 4e  f MAIDSAFE_DHT_N
0610: 4f 44 45 5f 43 4f 4e 54 41 49 4e 45 52 5f 48 5f  ODE_CONTAINER_H_
0620: 0a 23 64 65 66 69 6e 65 20 4d 41 49 44 53 41 46  .#define MAIDSAF
0630: 45 5f 44 48 54 5f 4e 4f 44 45 5f 43 4f 4e 54 41  E_DHT_NODE_CONTA
0640: 49 4e 45 52 5f 48 5f 0a 0a 23 69 6e 63 6c 75 64  INER_H_..#includ
0650: 65 20 3c 6d 65 6d 6f 72 79 3e 0a 23 69 6e 63 6c  e <memory>.#incl
0660: 75 64 65 20 3c 73 74 72 69 6e 67 3e 0a 23 69 6e  ude <string>.#in
0670: 63 6c 75 64 65 20 3c 75 74 69 6c 69 74 79 3e 0a  clude <utility>.
0680: 23 69 6e 63 6c 75 64 65 20 3c 76 65 63 74 6f 72  #include <vector
0690: 3e 0a 0a 23 69 6e 63 6c 75 64 65 20 22 62 6f 6f  >..#include "boo
06a0: 73 74 2f 61 73 69 6f 2f 69 6f 5f 73 65 72 76 69  st/asio/io_servi
06b0: 63 65 2e 68 70 70 22 0a 23 69 6e 63 6c 75 64 65  ce.hpp".#include
06c0: 20 22 62 6f 6f 73 74 2f 64 61 74 65 5f 74 69 6d   "boost/date_tim
06d0: 65 2f 70 6f 73 69 78 5f 74 69 6d 65 2f 70 6f 73  e/posix_time/pos
06e0: 69 78 5f 74 69 6d 65 5f 64 75 72 61 74 69 6f 6e  ix_time_duration
06f0: 2e 68 70 70 22 0a 23 69 6e 63 6c 75 64 65 20 22  .hpp".#include "
0700: 62 6f 6f 73 74 2f 74 68 72 65 61 64 2e 68 70 70  boost/thread.hpp
0710: 22 0a 0a 23 69 6e 63 6c 75 64 65 20 22 6d 61 69  "..#include "mai
0720: 64 73 61 66 65 2f 63 6f 6d 6d 6f 6e 2f 61 73 69  dsafe/common/asi
0730: 6f 5f 73 65 72 76 69 63 65 2e 68 22 0a 23 69 6e  o_service.h".#in
0740: 63 6c 75 64 65 20 22 6d 61 69 64 73 61 66 65 2f  clude "maidsafe/
0750: 63 6f 6d 6d 6f 6e 2f 63 72 79 70 74 6f 2e 68 22  common/crypto.h"
0760: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 6d 61 69 64  ..#include "maid
0770: 73 61 66 65 2f 74 72 61 6e 73 70 6f 72 74 2f 72  safe/transport/r
0780: 75 64 70 5f 74 72 61 6e 73 70 6f 72 74 2e 68 22  udp_transport.h"
0790: 0a 23 69 6e 63 6c 75 64 65 20 22 6d 61 69 64 73  .#include "maids
07a0: 61 66 65 2f 74 72 61 6e 73 70 6f 72 74 2f 74 63  afe/transport/tc
07b0: 70 5f 74 72 61 6e 73 70 6f 72 74 2e 68 22 0a 23  p_transport.h".#
07c0: 69 6e 63 6c 75 64 65 20 22 6d 61 69 64 73 61 66  include "maidsaf
07d0: 65 2f 74 72 61 6e 73 70 6f 72 74 2f 75 64 70 5f  e/transport/udp_
07e0: 74 72 61 6e 73 70 6f 72 74 2e 68 22 0a 2f 2f 20  transport.h".// 
07f0: 54 4f 44 4f 28 46 72 61 73 65 72 23 35 23 29 3a  TODO(Fraser#5#):
0800: 20 32 30 31 31 2d 30 38 2d 33 30 20 2d 20 72 65   2011-08-30 - re
0810: 6d 6f 76 65 20 23 69 6e 63 6c 75 64 65 20 75 74  move #include ut
0820: 69 6c 73 2e 68 20 6f 6e 63 65 20 4e 41 54 20 64  ils.h once NAT d
0830: 65 74 65 63 74 69 6f 6e 20 69 73 0a 2f 2f 20 20  etection is.//  
0840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0850: 69 6d 70 6c 65 6d 65 6e 74 65 64 2e 0a 23 69 6e  implemented..#in
0860: 63 6c 75 64 65 20 22 6d 61 69 64 73 61 66 65 2f  clude "maidsafe/
0870: 74 72 61 6e 73 70 6f 72 74 2f 75 74 69 6c 73 2e  transport/utils.
0880: 68 22 0a 0a 23 69 6e 63 6c 75 64 65 20 22 6d 61  h"..#include "ma
0890: 69 64 73 61 66 65 2f 64 68 74 2f 63 6f 6e 66 69  idsafe/dht/confi
08a0: 67 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 6d  g.h".#include "m
08b0: 61 69 64 73 61 66 65 2f 64 68 74 2f 6d 65 73 73  aidsafe/dht/mess
08c0: 61 67 65 5f 68 61 6e 64 6c 65 72 2e 68 22 0a 23  age_handler.h".#
08d0: 69 6e 63 6c 75 64 65 20 22 6d 61 69 64 73 61 66  include "maidsaf
08e0: 65 2f 64 68 74 2f 76 65 72 73 69 6f 6e 2e 68 22  e/dht/version.h"
08f0: 0a 23 69 6e 63 6c 75 64 65 20 22 6d 61 69 64 73  .#include "maids
0900: 61 66 65 2f 64 68 74 2f 6e 6f 64 65 2d 61 70 69  afe/dht/node-api
0910: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 6d 61  .h".#include "ma
0920: 69 64 73 61 66 65 2f 64 68 74 2f 72 65 74 75 72  idsafe/dht/retur
0930: 6e 5f 63 6f 64 65 73 2e 68 22 0a 0a 23 69 66 20  n_codes.h"..#if 
0940: 4d 41 49 44 53 41 46 45 5f 44 48 54 5f 56 45 52  MAIDSAFE_DHT_VER
0950: 53 49 4f 4e 20 21 3d 20 33 32 30 30 0a 23 20 20  SION != 3200.#  
0960: 65 72 72 6f 72 20 54 68 69 73 20 41 50 49 20 69  error This API i
0970: 73 20 6e 6f 74 20 63 6f 6d 70 61 74 69 62 6c 65  s not compatible
0980: 20 77 69 74 68 20 74 68 65 20 69 6e 73 74 61 6c   with the instal
0990: 6c 65 64 20 6c 69 62 72 61 72 79 2e 5c 0a 20 20  led library.\.  
09a0: 20 20 50 6c 65 61 73 65 20 75 70 64 61 74 65 20    Please update 
09b0: 74 68 65 20 6d 61 69 64 73 61 66 65 2d 64 68 74  the maidsafe-dht
09c0: 20 6c 69 62 72 61 72 79 2e 0a 23 65 6e 64 69 66   library..#endif
09d0: 0a 0a 6e 61 6d 65 73 70 61 63 65 20 61 72 67 73  ..namespace args
09e0: 20 3d 20 73 74 64 3a 3a 70 6c 61 63 65 68 6f 6c   = std::placehol
09f0: 64 65 72 73 3b 0a 6e 61 6d 65 73 70 61 63 65 20  ders;.namespace 
0a00: 62 70 74 69 6d 65 20 3d 20 62 6f 6f 73 74 3a 3a  bptime = boost::
0a10: 70 6f 73 69 78 5f 74 69 6d 65 3b 0a 0a 6e 61 6d  posix_time;..nam
0a20: 65 73 70 61 63 65 20 6d 61 69 64 73 61 66 65 20  espace maidsafe 
0a30: 7b 0a 0a 6e 61 6d 65 73 70 61 63 65 20 64 68 74  {..namespace dht
0a40: 20 7b 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79   {..template <ty
0a50: 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e  pename NodeType>
0a60: 0a 63 6c 61 73 73 20 4e 6f 64 65 43 6f 6e 74 61  .class NodeConta
0a70: 69 6e 65 72 20 7b 0a 20 70 75 62 6c 69 63 3a 0a  iner {. public:.
0a80: 20 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 28    NodeContainer(
0a90: 29 3b 0a 20 20 76 69 72 74 75 61 6c 20 7e 4e 6f  );.  virtual ~No
0aa0: 64 65 43 6f 6e 74 61 69 6e 65 72 28 29 3b 0a 0a  deContainer();..
0ab0: 20 20 76 69 72 74 75 61 6c 20 76 6f 69 64 20 49    virtual void I
0ac0: 6e 69 74 28 0a 20 20 20 20 20 20 75 69 6e 74 38  nit(.      uint8
0ad0: 5f 74 20 74 68 72 65 61 64 5f 63 6f 75 6e 74 2c  _t thread_count,
0ae0: 0a 20 20 20 20 20 20 4b 65 79 50 61 69 72 50 74  .      KeyPairPt
0af0: 72 20 6b 65 79 5f 70 61 69 72 2c 0a 20 20 20 20  r key_pair,.    
0b00: 20 20 4d 65 73 73 61 67 65 48 61 6e 64 6c 65 72    MessageHandler
0b10: 50 74 72 20 6d 65 73 73 61 67 65 5f 68 61 6e 64  Ptr message_hand
0b20: 6c 65 72 2c 0a 20 20 20 20 20 20 62 6f 6f 6c 20  ler,.      bool 
0b30: 63 6c 69 65 6e 74 5f 6f 6e 6c 79 5f 6e 6f 64 65  client_only_node
0b40: 2c 0a 20 20 20 20 20 20 75 69 6e 74 31 36 5f 74  ,.      uint16_t
0b50: 20 6b 20 3d 20 38 2c 0a 20 20 20 20 20 20 75 69   k = 8,.      ui
0b60: 6e 74 31 36 5f 74 20 61 6c 70 68 61 20 3d 20 33  nt16_t alpha = 3
0b70: 2c 0a 20 20 20 20 20 20 75 69 6e 74 31 36 5f 74  ,.      uint16_t
0b80: 20 62 65 74 61 20 3d 20 32 2c 0a 20 20 20 20 20   beta = 2,.     
0b90: 20 62 70 74 69 6d 65 3a 3a 74 69 6d 65 5f 64 75   bptime::time_du
0ba0: 72 61 74 69 6f 6e 20 6d 65 61 6e 5f 72 65 66 72  ration mean_refr
0bb0: 65 73 68 5f 69 6e 74 65 72 76 61 6c 20 3d 20 62  esh_interval = b
0bc0: 70 74 69 6d 65 3a 3a 68 6f 75 72 73 28 31 29 29  ptime::hours(1))
0bd0: 3b 0a 0a 20 20 2f 2f 20 46 6f 72 20 61 20 6e 6f  ;..  // For a no
0be0: 6e 2d 63 6c 69 65 6e 74 2c 20 73 74 61 72 74 73  n-client, starts
0bf0: 20 6c 69 73 74 65 6e 69 6e 67 20 6f 6e 20 61 20   listening on a 
0c00: 72 61 6e 64 6f 6d 20 70 6f 72 74 20 77 69 74 68  random port with
0c10: 69 6e 20 74 68 65 20 72 61 6e 67 65 2e 20 20 54  in the range.  T
0c20: 68 65 6e 0a 20 20 2f 2f 20 66 6f 72 20 61 6c 6c  hen.  // for all
0c30: 20 74 79 70 65 73 2c 20 6a 6f 69 6e 73 20 6e 65   types, joins ne
0c40: 74 77 6f 72 6b 2e 0a 20 20 69 6e 74 20 53 74 61  twork..  int Sta
0c50: 72 74 28 63 6f 6e 73 74 20 73 74 64 3a 3a 76 65  rt(const std::ve
0c60: 63 74 6f 72 3c 43 6f 6e 74 61 63 74 3e 20 26 62  ctor<Contact> &b
0c70: 6f 6f 74 73 74 72 61 70 5f 63 6f 6e 74 61 63 74  ootstrap_contact
0c80: 73 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  s,.            s
0c90: 74 64 3a 3a 70 61 69 72 3c 75 69 6e 74 31 36 5f  td::pair<uint16_
0ca0: 74 2c 20 75 69 6e 74 31 36 5f 74 3e 20 70 6f 72  t, uint16_t> por
0cb0: 74 5f 72 61 6e 67 65 29 3b 0a 20 20 2f 2f 20 4a  t_range);.  // J
0cc0: 6f 69 6e 73 20 74 68 65 20 6e 65 74 77 6f 72 6b  oins the network
0cd0: 2e 20 4f 6e 6c 79 20 66 6f 72 20 61 20 63 6c 69  . Only for a cli
0ce0: 65 6e 74 20 6f 6e 6c 79 20 6e 6f 64 65 73 2e 0a  ent only nodes..
0cf0: 20 20 69 6e 74 20 53 74 61 72 74 43 6c 69 65 6e    int StartClien
0d00: 74 28 63 6f 6e 73 74 20 73 74 64 3a 3a 76 65 63  t(const std::vec
0d10: 74 6f 72 3c 43 6f 6e 74 61 63 74 3e 20 26 62 6f  tor<Contact> &bo
0d20: 6f 74 73 74 72 61 70 5f 63 6f 6e 74 61 63 74 73  otstrap_contacts
0d30: 29 3b 0a 0a 20 20 2f 2f 20 53 74 6f 70 73 20 6c  );..  // Stops l
0d40: 69 73 74 65 6e 69 6e 67 20 28 69 66 20 6e 6f 6e  istening (if non
0d50: 2d 63 6c 69 65 6e 74 29 20 61 6e 64 20 6c 65 61  -client) and lea
0d60: 76 65 73 20 6e 65 74 77 6f 72 6b 2e 20 20 4a 6f  ves network.  Jo
0d70: 69 6e 73 20 61 6c 6c 20 74 68 72 65 61 64 73 2e  ins all threads.
0d80: 0a 20 20 69 6e 74 20 53 74 6f 70 28 73 74 64 3a  .  int Stop(std:
0d90: 3a 76 65 63 74 6f 72 3c 43 6f 6e 74 61 63 74 3e  :vector<Contact>
0da0: 20 2a 62 6f 6f 74 73 74 72 61 70 5f 63 6f 6e 74   *bootstrap_cont
0db0: 61 63 74 73 29 3b 0a 0a 20 20 2f 2f 20 54 68 65  acts);..  // The
0dc0: 73 65 20 38 20 66 75 6e 63 74 69 6f 6e 73 20 63  se 8 functions c
0dd0: 61 6c 6c 20 74 68 65 20 63 6f 72 72 65 73 70 6f  all the correspo
0de0: 6e 64 69 6e 67 20 66 75 6e 63 74 69 6f 6e 20 6f  nding function o
0df0: 6e 20 6e 6f 64 65 5f 20 75 73 69 6e 67 20 74 68  n node_ using th
0e00: 65 0a 20 20 2f 2f 20 63 6f 72 72 65 73 70 6f 6e  e.  // correspon
0e10: 64 69 6e 67 20 6d 65 6d 62 65 72 20 63 61 6c 6c  ding member call
0e20: 62 61 63 6b 20 66 75 6e 63 74 6f 72 73 20 6f 66  back functors of
0e30: 20 74 68 69 73 20 63 6c 61 73 73 2e 0a 20 20 76   this class..  v
0e40: 6f 69 64 20 4a 6f 69 6e 28 63 6f 6e 73 74 20 4e  oid Join(const N
0e50: 6f 64 65 49 64 20 26 6e 6f 64 65 5f 69 64 2c 0a  odeId &node_id,.
0e60: 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73              cons
0e70: 74 20 73 74 64 3a 3a 76 65 63 74 6f 72 3c 43 6f  t std::vector<Co
0e80: 6e 74 61 63 74 3e 20 26 62 6f 6f 74 73 74 72 61  ntact> &bootstra
0e90: 70 5f 63 6f 6e 74 61 63 74 73 29 3b 0a 20 20 76  p_contacts);.  v
0ea0: 6f 69 64 20 53 74 6f 72 65 28 63 6f 6e 73 74 20  oid Store(const 
0eb0: 4b 65 79 20 26 6b 65 79 2c 0a 20 20 20 20 20 20  Key &key,.      
0ec0: 20 20 20 20 20 20 20 63 6f 6e 73 74 20 73 74 64         const std
0ed0: 3a 3a 73 74 72 69 6e 67 20 26 76 61 6c 75 65 2c  ::string &value,
0ee0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f  .             co
0ef0: 6e 73 74 20 73 74 64 3a 3a 73 74 72 69 6e 67 20  nst std::string 
0f00: 26 73 69 67 6e 61 74 75 72 65 2c 0a 20 20 20 20  &signature,.    
0f10: 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 62           const b
0f20: 6f 6f 73 74 3a 3a 70 6f 73 69 78 5f 74 69 6d 65  oost::posix_time
0f30: 3a 3a 74 69 6d 65 5f 64 75 72 61 74 69 6f 6e 20  ::time_duration 
0f40: 26 74 74 6c 2c 0a 20 20 20 20 20 20 20 20 20 20  &ttl,.          
0f50: 20 20 20 50 72 69 76 61 74 65 4b 65 79 50 74 72     PrivateKeyPtr
0f60: 20 70 72 69 76 61 74 65 5f 6b 65 79 29 3b 0a 20   private_key);. 
0f70: 20 76 6f 69 64 20 44 65 6c 65 74 65 28 63 6f 6e   void Delete(con
0f80: 73 74 20 4b 65 79 20 26 6b 65 79 2c 0a 20 20 20  st Key &key,.   
0f90: 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74             const
0fa0: 20 73 74 64 3a 3a 73 74 72 69 6e 67 20 26 76 61   std::string &va
0fb0: 6c 75 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20  lue,.           
0fc0: 20 20 20 63 6f 6e 73 74 20 73 74 64 3a 3a 73 74     const std::st
0fd0: 72 69 6e 67 20 26 73 69 67 6e 61 74 75 72 65 2c  ring &signature,
0fe0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 50  .              P
0ff0: 72 69 76 61 74 65 4b 65 79 50 74 72 20 70 72 69  rivateKeyPtr pri
1000: 76 61 74 65 5f 6b 65 79 29 3b 0a 20 20 76 6f 69  vate_key);.  voi
1010: 64 20 55 70 64 61 74 65 28 63 6f 6e 73 74 20 4b  d Update(const K
1020: 65 79 20 26 6b 65 79 2c 0a 20 20 20 20 20 20 20  ey &key,.       
1030: 20 20 20 20 20 20 20 63 6f 6e 73 74 20 73 74 64         const std
1040: 3a 3a 73 74 72 69 6e 67 20 26 6e 65 77 5f 76 61  ::string &new_va
1050: 6c 75 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20  lue,.           
1060: 20 20 20 63 6f 6e 73 74 20 73 74 64 3a 3a 73 74     const std::st
1070: 72 69 6e 67 20 26 6e 65 77 5f 73 69 67 6e 61 74  ring &new_signat
1080: 75 72 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ure,.           
1090: 20 20 20 63 6f 6e 73 74 20 73 74 64 3a 3a 73 74     const std::st
10a0: 72 69 6e 67 20 26 6f 6c 64 5f 76 61 6c 75 65 2c  ring &old_value,
10b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63  .              c
10c0: 6f 6e 73 74 20 73 74 64 3a 3a 73 74 72 69 6e 67  onst std::string
10d0: 20 26 6f 6c 64 5f 73 69 67 6e 61 74 75 72 65 2c   &old_signature,
10e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63  .              c
10f0: 6f 6e 73 74 20 62 6f 6f 73 74 3a 3a 70 6f 73 69  onst boost::posi
1100: 78 5f 74 69 6d 65 3a 3a 74 69 6d 65 5f 64 75 72  x_time::time_dur
1110: 61 74 69 6f 6e 20 26 74 74 6c 2c 0a 20 20 20 20  ation &ttl,.    
1120: 20 20 20 20 20 20 20 20 20 20 50 72 69 76 61 74            Privat
1130: 65 4b 65 79 50 74 72 20 70 72 69 76 61 74 65 5f  eKeyPtr private_
1140: 6b 65 79 29 3b 0a 20 20 76 6f 69 64 20 46 69 6e  key);.  void Fin
1150: 64 56 61 6c 75 65 28 63 6f 6e 73 74 20 4b 65 79  dValue(const Key
1160: 20 26 6b 65 79 2c 0a 20 20 20 20 20 20 20 20 20   &key,.         
1170: 20 20 20 20 20 20 20 20 50 72 69 76 61 74 65 4b          PrivateK
1180: 65 79 50 74 72 20 70 72 69 76 61 74 65 5f 6b 65  eyPtr private_ke
1190: 79 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  y,.             
11a0: 20 20 20 20 63 6f 6e 73 74 20 75 69 6e 74 31 36      const uint16
11b0: 5f 74 20 26 65 78 74 72 61 5f 63 6f 6e 74 61 63  _t &extra_contac
11c0: 74 73 20 3d 20 30 29 3b 0a 20 20 76 6f 69 64 20  ts = 0);.  void 
11d0: 46 69 6e 64 4e 6f 64 65 73 28 63 6f 6e 73 74 20  FindNodes(const 
11e0: 4b 65 79 20 26 6b 65 79 2c 0a 20 20 20 20 20 20  Key &key,.      
11f0: 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74             const
1200: 20 75 69 6e 74 31 36 5f 74 20 26 65 78 74 72 61   uint16_t &extra
1210: 5f 63 6f 6e 74 61 63 74 73 20 3d 20 30 29 3b 0a  _contacts = 0);.
1220: 20 20 76 6f 69 64 20 47 65 74 43 6f 6e 74 61 63    void GetContac
1230: 74 28 63 6f 6e 73 74 20 4e 6f 64 65 49 64 20 26  t(const NodeId &
1240: 6e 6f 64 65 5f 69 64 29 3b 0a 20 20 76 6f 69 64  node_id);.  void
1250: 20 50 69 6e 67 28 63 6f 6e 73 74 20 43 6f 6e 74   Ping(const Cont
1260: 61 63 74 20 26 63 6f 6e 74 61 63 74 29 3b 0a 0a  act &contact);..
1270: 20 20 2f 2f 20 54 68 65 73 65 20 4d 61 6b 65 3c    // These Make<
1280: 58 58 58 3e 46 75 6e 63 74 6f 72 20 66 75 6e 63  XXX>Functor func
1290: 74 69 6f 6e 73 20 73 65 74 20 74 68 65 20 61 70  tions set the ap
12a0: 70 72 6f 70 72 69 61 74 65 20 3c 58 58 58 3e 5f  propriate <XXX>_
12b0: 66 75 6e 63 74 6f 72 5f 20 62 79 0a 20 20 2f 2f  functor_ by.  //
12c0: 20 62 69 6e 64 69 6e 67 20 74 68 65 20 63 6f 72   binding the cor
12d0: 72 65 73 70 6f 6e 64 69 6e 67 20 70 72 69 76 61  responding priva
12e0: 74 65 20 3c 58 58 58 3e 43 61 6c 6c 62 61 63 6b  te <XXX>Callback
12f0: 20 6d 65 74 68 6f 64 2e 0a 20 20 76 6f 69 64 20   method..  void 
1300: 4d 61 6b 65 4a 6f 69 6e 46 75 6e 63 74 6f 72 28  MakeJoinFunctor(
1310: 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20 2a 6d 75  boost::mutex *mu
1320: 74 65 78 2c 0a 20 20 20 20 20 20 20 20 20 20 20  tex,.           
1330: 20 20 20 20 20 20 20 20 20 20 20 20 62 6f 6f 73              boos
1340: 74 3a 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61 72  t::condition_var
1350: 69 61 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72 29  iable *cond_var)
1360: 3b 0a 20 20 76 6f 69 64 20 4d 61 6b 65 53 74 6f  ;.  void MakeSto
1370: 72 65 46 75 6e 63 74 6f 72 28 62 6f 6f 73 74 3a  reFunctor(boost:
1380: 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20  :mutex *mutex,. 
1390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13a0: 20 20 20 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f         boost::co
13b0: 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65  ndition_variable
13c0: 20 2a 63 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 76   *cond_var);.  v
13d0: 6f 69 64 20 4d 61 6b 65 44 65 6c 65 74 65 46 75  oid MakeDeleteFu
13e0: 6e 63 74 6f 72 28 62 6f 6f 73 74 3a 3a 6d 75 74  nctor(boost::mut
13f0: 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20 20 20 20  ex *mutex,.     
1400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1410: 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69      boost::condi
1420: 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63  tion_variable *c
1430: 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 76 6f 69 64  ond_var);.  void
1440: 20 4d 61 6b 65 55 70 64 61 74 65 46 75 6e 63 74   MakeUpdateFunct
1450: 6f 72 28 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20  or(boost::mutex 
1460: 2a 6d 75 74 65 78 2c 0a 20 20 20 20 20 20 20 20  *mutex,.        
1470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1480: 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69 6f   boost::conditio
1490: 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e 64  n_variable *cond
14a0: 5f 76 61 72 29 3b 0a 20 20 76 6f 69 64 20 4d 61  _var);.  void Ma
14b0: 6b 65 46 69 6e 64 56 61 6c 75 65 46 75 6e 63 74  keFindValueFunct
14c0: 6f 72 28 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20  or(boost::mutex 
14d0: 2a 6d 75 74 65 78 2c 0a 20 20 20 20 20 20 20 20  *mutex,.        
14e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14f0: 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69      boost::condi
1500: 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63  tion_variable *c
1510: 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 76 6f 69 64  ond_var);.  void
1520: 20 4d 61 6b 65 46 69 6e 64 4e 6f 64 65 73 46 75   MakeFindNodesFu
1530: 6e 63 74 6f 72 28 62 6f 6f 73 74 3a 3a 6d 75 74  nctor(boost::mut
1540: 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20 20 20 20  ex *mutex,.     
1550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1560: 20 20 20 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f         boost::co
1570: 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65  ndition_variable
1580: 20 2a 63 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 76   *cond_var);.  v
1590: 6f 69 64 20 4d 61 6b 65 47 65 74 43 6f 6e 74 61  oid MakeGetConta
15a0: 63 74 46 75 6e 63 74 6f 72 28 62 6f 6f 73 74 3a  ctFunctor(boost:
15b0: 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20  :mutex *mutex,. 
15c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15d0: 20 20 20 20 20 20 20 20 20 20 20 20 62 6f 6f 73              boos
15e0: 74 3a 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61 72  t::condition_var
15f0: 69 61 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72 29  iable *cond_var)
1600: 3b 0a 20 20 76 6f 69 64 20 4d 61 6b 65 50 69 6e  ;.  void MakePin
1610: 67 46 75 6e 63 74 6f 72 28 62 6f 6f 73 74 3a 3a  gFunctor(boost::
1620: 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20  mutex *mutex,.  
1630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1640: 20 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64       boost::cond
1650: 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a  ition_variable *
1660: 63 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 2f 2f 20  cond_var);.  // 
1670: 43 6f 6e 76 65 6e 69 65 6e 63 65 20 6d 65 74 68  Convenience meth
1680: 6f 64 20 66 6f 72 20 77 68 65 72 65 20 61 6c 6c  od for where all
1690: 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 6f   callback functo
16a0: 72 73 20 75 73 65 20 74 68 65 20 73 61 6d 65 20  rs use the same 
16b0: 6d 75 74 65 78 20 61 6e 64 0a 20 20 2f 2f 20 63  mutex and.  // c
16c0: 6f 6e 64 5f 76 61 72 0a 20 20 76 6f 69 64 20 4d  ond_var.  void M
16d0: 61 6b 65 41 6c 6c 43 61 6c 6c 62 61 63 6b 46 75  akeAllCallbackFu
16e0: 6e 63 74 6f 72 73 28 62 6f 6f 73 74 3a 3a 6d 75  nctors(boost::mu
16f0: 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20 20 20  tex *mutex,.    
1700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1710: 20 20 20 20 20 20 20 20 20 20 20 62 6f 6f 73 74             boost
1720: 3a 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61 72 69  ::condition_vari
1730: 61 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72 29 3b  able *cond_var);
1740: 0a 0a 20 20 2f 2f 20 54 68 65 73 65 20 37 20 73  ..  // These 7 s
1750: 65 74 74 65 72 73 20 61 6c 6c 6f 77 20 75 73 69  etters allow usi
1760: 6e 67 20 61 20 64 69 66 66 65 72 65 6e 74 20 63  ng a different c
1770: 61 6c 6c 62 61 63 6b 20 6d 65 74 68 6f 64 20 74  allback method t
1780: 6f 20 74 68 65 20 6f 6e 65 20 70 72 6f 76 69 64  o the one provid
1790: 65 64 0a 20 20 2f 2f 20 69 6e 20 74 68 69 73 20  ed.  // in this 
17a0: 63 6c 61 73 73 2e 0a 20 20 76 6f 69 64 20 73 65  class..  void se
17b0: 74 5f 6a 6f 69 6e 5f 66 75 6e 63 74 6f 72 28 63  t_join_functor(c
17c0: 6f 6e 73 74 20 4a 6f 69 6e 46 75 6e 63 74 6f 72  onst JoinFunctor
17d0: 20 26 66 75 6e 63 74 6f 72 29 20 7b 0a 20 20 20   &functor) {.   
17e0: 20 6a 6f 69 6e 5f 66 75 6e 63 74 6f 72 5f 20 3d   join_functor_ =
17f0: 20 66 75 6e 63 74 6f 72 3b 0a 20 20 7d 0a 20 20   functor;.  }.  
1800: 76 6f 69 64 20 73 65 74 5f 73 74 6f 72 65 5f 66  void set_store_f
1810: 75 6e 63 74 6f 72 28 63 6f 6e 73 74 20 53 74 6f  unctor(const Sto
1820: 72 65 46 75 6e 63 74 6f 72 20 26 66 75 6e 63 74  reFunctor &funct
1830: 6f 72 29 20 7b 0a 20 20 20 20 73 74 6f 72 65 5f  or) {.    store_
1840: 66 75 6e 63 74 6f 72 5f 20 3d 20 66 75 6e 63 74  functor_ = funct
1850: 6f 72 3b 0a 20 20 7d 0a 20 20 76 6f 69 64 20 73  or;.  }.  void s
1860: 65 74 5f 64 65 6c 65 74 65 5f 66 75 6e 63 74 6f  et_delete_functo
1870: 72 28 63 6f 6e 73 74 20 44 65 6c 65 74 65 46 75  r(const DeleteFu
1880: 6e 63 74 6f 72 20 26 66 75 6e 63 74 6f 72 29 20  nctor &functor) 
1890: 7b 0a 20 20 20 20 64 65 6c 65 74 65 5f 66 75 6e  {.    delete_fun
18a0: 63 74 6f 72 5f 20 3d 20 66 75 6e 63 74 6f 72 3b  ctor_ = functor;
18b0: 0a 20 20 7d 0a 20 20 76 6f 69 64 20 73 65 74 5f  .  }.  void set_
18c0: 75 70 64 61 74 65 5f 66 75 6e 63 74 6f 72 28 63  update_functor(c
18d0: 6f 6e 73 74 20 55 70 64 61 74 65 46 75 6e 63 74  onst UpdateFunct
18e0: 6f 72 20 26 66 75 6e 63 74 6f 72 29 20 7b 0a 20  or &functor) {. 
18f0: 20 20 20 75 70 64 61 74 65 5f 66 75 6e 63 74 6f     update_functo
1900: 72 5f 20 3d 20 66 75 6e 63 74 6f 72 3b 0a 20 20  r_ = functor;.  
1910: 7d 0a 20 20 76 6f 69 64 20 73 65 74 5f 66 69 6e  }.  void set_fin
1920: 64 5f 76 61 6c 75 65 5f 66 75 6e 63 74 6f 72 28  d_value_functor(
1930: 63 6f 6e 73 74 20 46 69 6e 64 56 61 6c 75 65 46  const FindValueF
1940: 75 6e 63 74 6f 72 20 26 66 75 6e 63 74 6f 72 29  unctor &functor)
1950: 20 7b 0a 20 20 20 20 66 69 6e 64 5f 76 61 6c 75   {.    find_valu
1960: 65 5f 66 75 6e 63 74 6f 72 5f 20 3d 20 66 75 6e  e_functor_ = fun
1970: 63 74 6f 72 3b 0a 20 20 7d 0a 20 20 76 6f 69 64  ctor;.  }.  void
1980: 20 73 65 74 5f 66 69 6e 64 5f 6e 6f 64 65 73 5f   set_find_nodes_
1990: 66 75 6e 63 74 6f 72 28 63 6f 6e 73 74 20 46 69  functor(const Fi
19a0: 6e 64 4e 6f 64 65 73 46 75 6e 63 74 6f 72 20 26  ndNodesFunctor &
19b0: 66 75 6e 63 74 6f 72 29 20 7b 0a 20 20 20 20 66  functor) {.    f
19c0: 69 6e 64 5f 6e 6f 64 65 73 5f 66 75 6e 63 74 6f  ind_nodes_functo
19d0: 72 5f 20 3d 20 66 75 6e 63 74 6f 72 3b 0a 20 20  r_ = functor;.  
19e0: 7d 0a 20 20 76 6f 69 64 20 73 65 74 5f 67 65 74  }.  void set_get
19f0: 5f 63 6f 6e 74 61 63 74 5f 66 75 6e 63 74 6f 72  _contact_functor
1a00: 28 63 6f 6e 73 74 20 47 65 74 43 6f 6e 74 61 63  (const GetContac
1a10: 74 46 75 6e 63 74 6f 72 20 26 66 75 6e 63 74 6f  tFunctor &functo
1a20: 72 29 20 7b 0a 20 20 20 20 67 65 74 5f 63 6f 6e  r) {.    get_con
1a30: 74 61 63 74 5f 66 75 6e 63 74 6f 72 5f 20 3d 20  tact_functor_ = 
1a40: 66 75 6e 63 74 6f 72 3b 0a 20 20 7d 0a 20 20 76  functor;.  }.  v
1a50: 6f 69 64 20 73 65 74 5f 70 69 6e 67 5f 66 75 6e  oid set_ping_fun
1a60: 63 74 6f 72 28 63 6f 6e 73 74 20 50 69 6e 67 46  ctor(const PingF
1a70: 75 6e 63 74 6f 72 20 26 66 75 6e 63 74 6f 72 29  unctor &functor)
1a80: 20 7b 0a 20 20 20 20 70 69 6e 67 5f 66 75 6e 63   {.    ping_func
1a90: 74 6f 72 5f 20 3d 20 66 75 6e 63 74 6f 72 3b 0a  tor_ = functor;.
1aa0: 20 20 7d 0a 0a 20 20 2f 2f 20 54 68 65 73 65 20    }..  // These 
1ab0: 37 20 67 65 74 74 65 72 73 20 61 6c 73 6f 20 73  7 getters also s
1ac0: 65 74 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67  et corresponding
1ad0: 20 63 6c 61 73 73 20 6d 65 6d 62 65 72 20 72 65   class member re
1ae0: 73 75 6c 74 73 20 74 6f 0a 20 20 2f 2f 20 6b 50  sults to.  // kP
1af0: 65 6e 64 69 6e 67 52 65 73 75 6c 74 20 61 6e 64  endingResult and
1b00: 20 63 6c 65 61 72 20 61 6e 79 20 63 6f 72 72 65   clear any corre
1b10: 73 70 6f 6e 64 69 6e 67 20 72 65 73 75 6c 74 20  sponding result 
1b20: 73 74 72 75 63 74 73 2f 63 6f 6e 74 61 69 6e 65  structs/containe
1b30: 72 73 20 72 65 61 64 79 0a 20 20 2f 2f 20 66 6f  rs ready.  // fo
1b40: 72 20 73 75 62 73 65 71 75 65 6e 74 20 63 61 6c  r subsequent cal
1b50: 6c 73 2e 0a 20 20 76 6f 69 64 20 47 65 74 41 6e  ls..  void GetAn
1b60: 64 52 65 73 65 74 4a 6f 69 6e 52 65 73 75 6c 74  dResetJoinResult
1b70: 28 69 6e 74 20 2a 72 65 73 75 6c 74 29 3b 0a 20  (int *result);. 
1b80: 20 76 6f 69 64 20 47 65 74 41 6e 64 52 65 73 65   void GetAndRese
1b90: 74 53 74 6f 72 65 52 65 73 75 6c 74 28 69 6e 74  tStoreResult(int
1ba0: 20 2a 72 65 73 75 6c 74 29 3b 0a 20 20 76 6f 69   *result);.  voi
1bb0: 64 20 47 65 74 41 6e 64 52 65 73 65 74 44 65 6c  d GetAndResetDel
1bc0: 65 74 65 52 65 73 75 6c 74 28 69 6e 74 20 2a 72  eteResult(int *r
1bd0: 65 73 75 6c 74 29 3b 0a 20 20 76 6f 69 64 20 47  esult);.  void G
1be0: 65 74 41 6e 64 52 65 73 65 74 55 70 64 61 74 65  etAndResetUpdate
1bf0: 52 65 73 75 6c 74 28 69 6e 74 20 2a 72 65 73 75  Result(int *resu
1c00: 6c 74 29 3b 0a 20 20 76 6f 69 64 20 47 65 74 41  lt);.  void GetA
1c10: 6e 64 52 65 73 65 74 46 69 6e 64 4e 6f 64 65 73  ndResetFindNodes
1c20: 52 65 73 75 6c 74 28 69 6e 74 20 2a 72 65 73 75  Result(int *resu
1c30: 6c 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  lt,.            
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c50: 20 20 20 20 20 20 73 74 64 3a 3a 76 65 63 74 6f        std::vecto
1c60: 72 3c 43 6f 6e 74 61 63 74 3e 20 2a 63 6c 6f 73  r<Contact> *clos
1c70: 65 73 74 5f 6e 6f 64 65 73 29 3b 0a 20 20 76 6f  est_nodes);.  vo
1c80: 69 64 20 47 65 74 41 6e 64 52 65 73 65 74 46 69  id GetAndResetFi
1c90: 6e 64 56 61 6c 75 65 52 65 73 75 6c 74 28 46 69  ndValueResult(Fi
1ca0: 6e 64 56 61 6c 75 65 52 65 74 75 72 6e 73 20 2a  ndValueReturns *
1cb0: 66 69 6e 64 5f 76 61 6c 75 65 5f 72 65 74 75 72  find_value_retur
1cc0: 6e 73 29 3b 0a 20 20 76 6f 69 64 20 47 65 74 41  ns);.  void GetA
1cd0: 6e 64 52 65 73 65 74 47 65 74 43 6f 6e 74 61 63  ndResetGetContac
1ce0: 74 52 65 73 75 6c 74 28 69 6e 74 20 2a 72 65 73  tResult(int *res
1cf0: 75 6c 74 2c 20 43 6f 6e 74 61 63 74 20 2a 63 6f  ult, Contact *co
1d00: 6e 74 61 63 74 29 3b 0a 20 20 76 6f 69 64 20 47  ntact);.  void G
1d10: 65 74 41 6e 64 52 65 73 65 74 50 69 6e 67 52 65  etAndResetPingRe
1d20: 73 75 6c 74 28 69 6e 74 20 2a 72 65 73 75 6c 74  sult(int *result
1d30: 29 3b 0a 0a 20 20 2f 2f 20 54 68 69 73 20 72 65  );..  // This re
1d40: 74 75 72 6e 73 20 74 68 65 20 69 6f 5f 73 65 72  turns the io_ser
1d50: 76 69 63 65 20 62 79 20 72 65 66 65 72 65 6e 63  vice by referenc
1d60: 65 21 20 20 54 68 69 73 20 69 73 20 6e 65 65 64  e!  This is need
1d70: 65 64 20 62 79 20 61 6c 6d 6f 73 74 20 61 6e 79  ed by almost any
1d80: 0a 20 20 2f 2f 20 61 73 69 6f 20 6f 62 6a 65 63  .  // asio objec
1d90: 74 20 77 68 69 63 68 20 74 61 6b 65 73 20 61 6e  t which takes an
1da0: 20 69 6f 5f 73 65 72 76 69 63 65 20 69 6e 20 69   io_service in i
1db0: 74 73 20 63 6f 6e 73 74 72 75 63 74 6f 72 2e 20  ts constructor. 
1dc0: 20 45 6e 73 75 72 65 20 74 68 61 74 20 69 66 0a   Ensure that if.
1dd0: 20 20 2f 2f 20 74 68 69 73 20 67 65 74 74 65 72    // this getter
1de0: 20 69 73 20 75 73 65 64 2c 20 74 68 69 73 20 63   is used, this c
1df0: 6c 61 73 73 20 69 6e 73 74 61 6e 63 65 20 6f 75  lass instance ou
1e00: 74 6c 69 76 65 73 20 74 68 65 20 63 61 6c 6c 65  tlives the calle
1e10: 72 2e 0a 20 20 62 6f 6f 73 74 3a 3a 61 73 69 6f  r..  boost::asio
1e20: 3a 3a 69 6f 5f 73 65 72 76 69 63 65 20 26 61 73  ::io_service &as
1e30: 69 6f 5f 73 65 72 76 69 63 65 28 29 20 7b 20 72  io_service() { r
1e40: 65 74 75 72 6e 20 61 73 69 6f 5f 73 65 72 76 69  eturn asio_servi
1e50: 63 65 5f 2e 73 65 72 76 69 63 65 28 29 3b 20 7d  ce_.service(); }
1e60: 0a 0a 20 20 2f 2f 20 53 74 61 6e 64 61 72 64 20  ..  // Standard 
1e70: 67 65 74 74 65 72 73 0a 20 20 73 74 64 3a 3a 73  getters.  std::s
1e80: 68 61 72 65 64 5f 70 74 72 3c 4e 6f 64 65 54 79  hared_ptr<NodeTy
1e90: 70 65 3e 20 6e 6f 64 65 28 29 20 63 6f 6e 73 74  pe> node() const
1ea0: 20 7b 20 72 65 74 75 72 6e 20 6e 6f 64 65 5f 3b   { return node_;
1eb0: 20 7d 0a 20 20 4b 65 79 50 61 69 72 50 74 72 20   }.  KeyPairPtr 
1ec0: 6b 65 79 5f 70 61 69 72 28 29 20 63 6f 6e 73 74  key_pair() const
1ed0: 20 7b 20 72 65 74 75 72 6e 20 6b 65 79 5f 70 61   { return key_pa
1ee0: 69 72 5f 3b 20 7d 0a 20 20 73 74 64 3a 3a 76 65  ir_; }.  std::ve
1ef0: 63 74 6f 72 3c 43 6f 6e 74 61 63 74 3e 20 62 6f  ctor<Contact> bo
1f00: 6f 74 73 74 72 61 70 5f 63 6f 6e 74 61 63 74 73  otstrap_contacts
1f10: 28 29 20 63 6f 6e 73 74 20 7b 0a 20 20 20 20 72  () const {.    r
1f20: 65 74 75 72 6e 20 62 6f 6f 74 73 74 72 61 70 5f  eturn bootstrap_
1f30: 63 6f 6e 74 61 63 74 73 5f 3b 0a 20 20 7d 0a 20  contacts_;.  }. 
1f40: 20 4a 6f 69 6e 46 75 6e 63 74 6f 72 20 6a 6f 69   JoinFunctor joi
1f50: 6e 5f 66 75 6e 63 74 6f 72 28 29 20 63 6f 6e 73  n_functor() cons
1f60: 74 20 7b 20 72 65 74 75 72 6e 20 6a 6f 69 6e 5f  t { return join_
1f70: 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a 20 20 53 74  functor_; }.  St
1f80: 6f 72 65 46 75 6e 63 74 6f 72 20 73 74 6f 72 65  oreFunctor store
1f90: 5f 66 75 6e 63 74 6f 72 28 29 20 63 6f 6e 73 74  _functor() const
1fa0: 20 7b 20 72 65 74 75 72 6e 20 73 74 6f 72 65 5f   { return store_
1fb0: 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a 20 20 44 65  functor_; }.  De
1fc0: 6c 65 74 65 46 75 6e 63 74 6f 72 20 64 65 6c 65  leteFunctor dele
1fd0: 74 65 5f 66 75 6e 63 74 6f 72 28 29 20 63 6f 6e  te_functor() con
1fe0: 73 74 20 7b 20 72 65 74 75 72 6e 20 64 65 6c 65  st { return dele
1ff0: 74 65 5f 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a 20  te_functor_; }. 
2000: 20 55 70 64 61 74 65 46 75 6e 63 74 6f 72 20 75   UpdateFunctor u
2010: 70 64 61 74 65 5f 66 75 6e 63 74 6f 72 28 29 20  pdate_functor() 
2020: 63 6f 6e 73 74 20 7b 20 72 65 74 75 72 6e 20 75  const { return u
2030: 70 64 61 74 65 5f 66 75 6e 63 74 6f 72 5f 3b 20  pdate_functor_; 
2040: 7d 0a 20 20 46 69 6e 64 56 61 6c 75 65 46 75 6e  }.  FindValueFun
2050: 63 74 6f 72 20 66 69 6e 64 5f 76 61 6c 75 65 5f  ctor find_value_
2060: 66 75 6e 63 74 6f 72 28 29 20 63 6f 6e 73 74 20  functor() const 
2070: 7b 20 72 65 74 75 72 6e 20 66 69 6e 64 5f 76 61  { return find_va
2080: 6c 75 65 5f 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a  lue_functor_; }.
2090: 20 20 46 69 6e 64 4e 6f 64 65 73 46 75 6e 63 74    FindNodesFunct
20a0: 6f 72 20 66 69 6e 64 5f 6e 6f 64 65 73 5f 66 75  or find_nodes_fu
20b0: 6e 63 74 6f 72 28 29 20 63 6f 6e 73 74 20 7b 20  nctor() const { 
20c0: 72 65 74 75 72 6e 20 66 69 6e 64 5f 6e 6f 64 65  return find_node
20d0: 73 5f 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a 20 20  s_functor_; }.  
20e0: 47 65 74 43 6f 6e 74 61 63 74 46 75 6e 63 74 6f  GetContactFuncto
20f0: 72 20 67 65 74 5f 63 6f 6e 74 61 63 74 5f 66 75  r get_contact_fu
2100: 6e 63 74 6f 72 28 29 20 63 6f 6e 73 74 20 7b 20  nctor() const { 
2110: 72 65 74 75 72 6e 20 67 65 74 5f 63 6f 6e 74 61  return get_conta
2120: 63 74 5f 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a 20  ct_functor_; }. 
2130: 20 50 69 6e 67 46 75 6e 63 74 6f 72 20 70 69 6e   PingFunctor pin
2140: 67 5f 66 75 6e 63 74 6f 72 28 29 20 63 6f 6e 73  g_functor() cons
2150: 74 20 7b 20 72 65 74 75 72 6e 20 70 69 6e 67 5f  t { return ping_
2160: 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a 0a 20 20 2f  functor_; }..  /
2170: 2f 20 54 68 65 73 65 20 57 61 69 74 46 75 6e 63  / These WaitFunc
2180: 74 6f 72 73 20 63 61 6e 20 62 65 20 75 73 65 64  tors can be used
2190: 20 69 6e 73 69 64 65 20 62 6f 6f 73 74 20 77 61   inside boost wa
21a0: 69 74 20 6f 72 20 74 69 6d 65 64 5f 77 61 69 74  it or timed_wait
21b0: 20 66 75 6e 63 74 69 6f 6e 73 0a 20 20 2f 2f 20   functions.  // 
21c0: 61 73 20 70 72 65 64 69 63 61 74 65 73 2e 0a 20  as predicates.. 
21d0: 20 57 61 69 74 46 75 6e 63 74 6f 72 20 77 61 69   WaitFunctor wai
21e0: 74 5f 66 6f 72 5f 6a 6f 69 6e 5f 66 75 6e 63 74  t_for_join_funct
21f0: 6f 72 28 29 20 63 6f 6e 73 74 20 7b 20 72 65 74  or() const { ret
2200: 75 72 6e 20 77 61 69 74 5f 66 6f 72 5f 6a 6f 69  urn wait_for_joi
2210: 6e 5f 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a 20 20  n_functor_; }.  
2220: 57 61 69 74 46 75 6e 63 74 6f 72 20 77 61 69 74  WaitFunctor wait
2230: 5f 66 6f 72 5f 73 74 6f 72 65 5f 66 75 6e 63 74  _for_store_funct
2240: 6f 72 28 29 20 63 6f 6e 73 74 20 7b 20 72 65 74  or() const { ret
2250: 75 72 6e 20 77 61 69 74 5f 66 6f 72 5f 73 74 6f  urn wait_for_sto
2260: 72 65 5f 66 75 6e 63 74 6f 72 5f 3b 20 7d 0a 20  re_functor_; }. 
2270: 20 57 61 69 74 46 75 6e 63 74 6f 72 20 77 61 69   WaitFunctor wai
2280: 74 5f 66 6f 72 5f 64 65 6c 65 74 65 5f 66 75 6e  t_for_delete_fun
2290: 63 74 6f 72 28 29 20 63 6f 6e 73 74 20 7b 0a 20  ctor() const {. 
22a0: 20 20 20 72 65 74 75 72 6e 20 77 61 69 74 5f 66     return wait_f
22b0: 6f 72 5f 64 65 6c 65 74 65 5f 66 75 6e 63 74 6f  or_delete_functo
22c0: 72 5f 3b 0a 20 20 7d 0a 20 20 57 61 69 74 46 75  r_;.  }.  WaitFu
22d0: 6e 63 74 6f 72 20 77 61 69 74 5f 66 6f 72 5f 75  nctor wait_for_u
22e0: 70 64 61 74 65 5f 66 75 6e 63 74 6f 72 28 29 20  pdate_functor() 
22f0: 63 6f 6e 73 74 20 7b 0a 20 20 20 20 72 65 74 75  const {.    retu
2300: 72 6e 20 77 61 69 74 5f 66 6f 72 5f 75 70 64 61  rn wait_for_upda
2310: 74 65 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 7d  te_functor_;.  }
2320: 0a 20 20 57 61 69 74 46 75 6e 63 74 6f 72 20 77  .  WaitFunctor w
2330: 61 69 74 5f 66 6f 72 5f 66 69 6e 64 5f 76 61 6c  ait_for_find_val
2340: 75 65 5f 66 75 6e 63 74 6f 72 28 29 20 63 6f 6e  ue_functor() con
2350: 73 74 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  st {.    return 
2360: 77 61 69 74 5f 66 6f 72 5f 66 69 6e 64 5f 76 61  wait_for_find_va
2370: 6c 75 65 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20  lue_functor_;.  
2380: 7d 0a 20 20 57 61 69 74 46 75 6e 63 74 6f 72 20  }.  WaitFunctor 
2390: 77 61 69 74 5f 66 6f 72 5f 66 69 6e 64 5f 6e 6f  wait_for_find_no
23a0: 64 65 73 5f 66 75 6e 63 74 6f 72 28 29 20 63 6f  des_functor() co
23b0: 6e 73 74 20 7b 0a 20 20 20 20 72 65 74 75 72 6e  nst {.    return
23c0: 20 77 61 69 74 5f 66 6f 72 5f 66 69 6e 64 5f 6e   wait_for_find_n
23d0: 6f 64 65 73 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20  odes_functor_;. 
23e0: 20 7d 0a 20 20 57 61 69 74 46 75 6e 63 74 6f 72   }.  WaitFunctor
23f0: 20 77 61 69 74 5f 66 6f 72 5f 67 65 74 5f 63 6f   wait_for_get_co
2400: 6e 74 61 63 74 5f 66 75 6e 63 74 6f 72 28 29 20  ntact_functor() 
2410: 63 6f 6e 73 74 20 7b 0a 20 20 20 20 72 65 74 75  const {.    retu
2420: 72 6e 20 77 61 69 74 5f 66 6f 72 5f 67 65 74 5f  rn wait_for_get_
2430: 63 6f 6e 74 61 63 74 5f 66 75 6e 63 74 6f 72 5f  contact_functor_
2440: 3b 0a 20 20 7d 0a 20 20 57 61 69 74 46 75 6e 63  ;.  }.  WaitFunc
2450: 74 6f 72 20 77 61 69 74 5f 66 6f 72 5f 70 69 6e  tor wait_for_pin
2460: 67 5f 66 75 6e 63 74 6f 72 28 29 20 63 6f 6e 73  g_functor() cons
2470: 74 20 7b 20 72 65 74 75 72 6e 20 77 61 69 74 5f  t { return wait_
2480: 66 6f 72 5f 70 69 6e 67 5f 66 75 6e 63 74 6f 72  for_ping_functor
2490: 5f 3b 20 7d 0a 0a 0a 20 70 72 6f 74 65 63 74 65  _; }... protecte
24a0: 64 3a 0a 20 20 41 73 69 6f 53 65 72 76 69 63 65  d:.  AsioService
24b0: 20 61 73 69 6f 5f 73 65 72 76 69 63 65 5f 3b 0a   asio_service_;.
24c0: 20 20 54 72 61 6e 73 70 6f 72 74 50 74 72 20 6c    TransportPtr l
24d0: 69 73 74 65 6e 69 6e 67 5f 74 72 61 6e 73 70 6f  istening_transpo
24e0: 72 74 5f 3b 0a 20 20 4d 65 73 73 61 67 65 48 61  rt_;.  MessageHa
24f0: 6e 64 6c 65 72 50 74 72 20 6d 65 73 73 61 67 65  ndlerPtr message
2500: 5f 68 61 6e 64 6c 65 72 5f 3b 0a 20 20 4b 65 79  _handler_;.  Key
2510: 50 61 69 72 50 74 72 20 6b 65 79 5f 70 61 69 72  PairPtr key_pair
2520: 5f 3b 0a 20 20 73 74 64 3a 3a 73 68 61 72 65 64  _;.  std::shared
2530: 5f 70 74 72 3c 4e 6f 64 65 54 79 70 65 3e 20 6e  _ptr<NodeType> n
2540: 6f 64 65 5f 3b 0a 20 20 73 74 64 3a 3a 76 65 63  ode_;.  std::vec
2550: 74 6f 72 3c 43 6f 6e 74 61 63 74 3e 20 62 6f 6f  tor<Contact> boo
2560: 74 73 74 72 61 70 5f 63 6f 6e 74 61 63 74 73 5f  tstrap_contacts_
2570: 3b 0a 20 20 69 6e 74 20 6a 6f 69 6e 5f 72 65 73  ;.  int join_res
2580: 75 6c 74 5f 2c 20 73 74 6f 72 65 5f 72 65 73 75  ult_, store_resu
2590: 6c 74 5f 2c 20 64 65 6c 65 74 65 5f 72 65 73 75  lt_, delete_resu
25a0: 6c 74 5f 2c 20 75 70 64 61 74 65 5f 72 65 73 75  lt_, update_resu
25b0: 6c 74 5f 2c 0a 20 20 20 20 20 20 66 69 6e 64 5f  lt_,.      find_
25c0: 6e 6f 64 65 73 5f 72 65 73 75 6c 74 5f 2c 20 67  nodes_result_, g
25d0: 65 74 5f 63 6f 6e 74 61 63 74 5f 72 65 73 75 6c  et_contact_resul
25e0: 74 5f 2c 20 70 69 6e 67 5f 72 65 73 75 6c 74 5f  t_, ping_result_
25f0: 3b 0a 20 20 46 69 6e 64 56 61 6c 75 65 52 65 74  ;.  FindValueRet
2600: 75 72 6e 73 20 66 69 6e 64 5f 76 61 6c 75 65 5f  urns find_value_
2610: 72 65 74 75 72 6e 73 5f 3b 0a 20 20 73 74 64 3a  returns_;.  std:
2620: 3a 76 65 63 74 6f 72 3c 43 6f 6e 74 61 63 74 3e  :vector<Contact>
2630: 20 66 69 6e 64 5f 6e 6f 64 65 73 5f 63 6c 6f 73   find_nodes_clos
2640: 65 73 74 5f 6e 6f 64 65 73 5f 3b 0a 20 20 43 6f  est_nodes_;.  Co
2650: 6e 74 61 63 74 20 67 6f 74 74 65 6e 5f 63 6f 6e  ntact gotten_con
2660: 74 61 63 74 5f 3b 0a 20 20 57 61 69 74 46 75 6e  tact_;.  WaitFun
2670: 63 74 6f 72 20 77 61 69 74 5f 66 6f 72 5f 6a 6f  ctor wait_for_jo
2680: 69 6e 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 57  in_functor_;.  W
2690: 61 69 74 46 75 6e 63 74 6f 72 20 77 61 69 74 5f  aitFunctor wait_
26a0: 66 6f 72 5f 73 74 6f 72 65 5f 66 75 6e 63 74 6f  for_store_functo
26b0: 72 5f 3b 0a 20 20 57 61 69 74 46 75 6e 63 74 6f  r_;.  WaitFuncto
26c0: 72 20 77 61 69 74 5f 66 6f 72 5f 64 65 6c 65 74  r wait_for_delet
26d0: 65 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 57 61  e_functor_;.  Wa
26e0: 69 74 46 75 6e 63 74 6f 72 20 77 61 69 74 5f 66  itFunctor wait_f
26f0: 6f 72 5f 75 70 64 61 74 65 5f 66 75 6e 63 74 6f  or_update_functo
2700: 72 5f 3b 0a 20 20 57 61 69 74 46 75 6e 63 74 6f  r_;.  WaitFuncto
2710: 72 20 77 61 69 74 5f 66 6f 72 5f 66 69 6e 64 5f  r wait_for_find_
2720: 76 61 6c 75 65 5f 66 75 6e 63 74 6f 72 5f 3b 0a  value_functor_;.
2730: 20 20 57 61 69 74 46 75 6e 63 74 6f 72 20 77 61    WaitFunctor wa
2740: 69 74 5f 66 6f 72 5f 66 69 6e 64 5f 6e 6f 64 65  it_for_find_node
2750: 73 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 57 61  s_functor_;.  Wa
2760: 69 74 46 75 6e 63 74 6f 72 20 77 61 69 74 5f 66  itFunctor wait_f
2770: 6f 72 5f 67 65 74 5f 63 6f 6e 74 61 63 74 5f 66  or_get_contact_f
2780: 75 6e 63 74 6f 72 5f 3b 0a 20 20 57 61 69 74 46  unctor_;.  WaitF
2790: 75 6e 63 74 6f 72 20 77 61 69 74 5f 66 6f 72 5f  unctor wait_for_
27a0: 70 69 6e 67 5f 66 75 6e 63 74 6f 72 5f 3b 0a 0a  ping_functor_;..
27b0: 20 70 72 69 76 61 74 65 3a 0a 20 20 4e 6f 64 65   private:.  Node
27c0: 43 6f 6e 74 61 69 6e 65 72 28 63 6f 6e 73 74 20  Container(const 
27d0: 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 26 29 3b  NodeContainer&);
27e0: 0a 20 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72  .  NodeContainer
27f0: 20 26 6f 70 65 72 61 74 6f 72 3d 28 63 6f 6e 73   &operator=(cons
2800: 74 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 26  t NodeContainer&
2810: 29 3b 0a 20 20 76 6f 69 64 20 4a 6f 69 6e 43 61  );.  void JoinCa
2820: 6c 6c 62 61 63 6b 28 69 6e 74 20 72 65 73 75 6c  llback(int resul
2830: 74 5f 69 6e 2c 0a 20 20 20 20 20 20 20 20 20 20  t_in,.          
2840: 20 20 20 20 20 20 20 20 20 20 62 6f 6f 73 74 3a            boost:
2850: 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20  :mutex *mutex,. 
2860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2870: 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74     boost::condit
2880: 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f  ion_variable *co
2890: 6e 64 5f 76 61 72 29 3b 0a 20 20 76 6f 69 64 20  nd_var);.  void 
28a0: 53 74 6f 72 65 43 61 6c 6c 62 61 63 6b 28 69 6e  StoreCallback(in
28b0: 74 20 72 65 73 75 6c 74 5f 69 6e 2c 0a 20 20 20  t result_in,.   
28c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28d0: 20 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20 2a    boost::mutex *
28e0: 6d 75 74 65 78 2c 0a 20 20 20 20 20 20 20 20 20  mutex,.         
28f0: 20 20 20 20 20 20 20 20 20 20 20 20 62 6f 6f 73              boos
2900: 74 3a 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61 72  t::condition_var
2910: 69 61 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72 29  iable *cond_var)
2920: 3b 0a 20 20 76 6f 69 64 20 44 65 6c 65 74 65 43  ;.  void DeleteC
2930: 61 6c 6c 62 61 63 6b 28 69 6e 74 20 72 65 73 75  allback(int resu
2940: 6c 74 5f 69 6e 2c 0a 20 20 20 20 20 20 20 20 20  lt_in,.         
2950: 20 20 20 20 20 20 20 20 20 20 20 20 20 62 6f 6f               boo
2960: 73 74 3a 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78  st::mutex *mutex
2970: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
2980: 20 20 20 20 20 20 20 20 62 6f 6f 73 74 3a 3a 63          boost::c
2990: 6f 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c  ondition_variabl
29a0: 65 20 2a 63 6f 6e 64 5f 76 61 72 29 3b 0a 20 20  e *cond_var);.  
29b0: 76 6f 69 64 20 55 70 64 61 74 65 43 61 6c 6c 62  void UpdateCallb
29c0: 61 63 6b 28 69 6e 74 20 72 65 73 75 6c 74 5f 69  ack(int result_i
29d0: 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  n,.             
29e0: 20 20 20 20 20 20 20 20 20 62 6f 6f 73 74 3a 3a           boost::
29f0: 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20  mutex *mutex,.  
2a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a10: 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69      boost::condi
2a20: 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63  tion_variable *c
2a30: 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 76 6f 69 64  ond_var);.  void
2a40: 20 46 69 6e 64 56 61 6c 75 65 43 61 6c 6c 62 61   FindValueCallba
2a50: 63 6b 28 46 69 6e 64 56 61 6c 75 65 52 65 74 75  ck(FindValueRetu
2a60: 72 6e 73 20 66 69 6e 64 5f 76 61 6c 75 65 5f 72  rns find_value_r
2a70: 65 74 75 72 6e 73 5f 69 6e 2c 0a 20 20 20 20 20  eturns_in,.     
2a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a90: 20 20 20 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78      boost::mutex
2aa0: 20 2a 6d 75 74 65 78 2c 0a 20 20 20 20 20 20 20   *mutex,.       
2ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ac0: 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69    boost::conditi
2ad0: 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e  on_variable *con
2ae0: 64 5f 76 61 72 29 3b 0a 20 20 76 6f 69 64 20 46  d_var);.  void F
2af0: 69 6e 64 4e 6f 64 65 73 43 61 6c 6c 62 61 63 6b  indNodesCallback
2b00: 28 69 6e 74 20 72 65 73 75 6c 74 5f 69 6e 2c 0a  (int result_in,.
2b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2b20: 20 20 20 20 20 20 20 20 20 73 74 64 3a 3a 76 65           std::ve
2b30: 63 74 6f 72 3c 43 6f 6e 74 61 63 74 3e 20 63 6c  ctor<Contact> cl
2b40: 6f 73 65 73 74 5f 6e 6f 64 65 73 5f 69 6e 2c 0a  osest_nodes_in,.
2b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2b60: 20 20 20 20 20 20 20 20 20 62 6f 6f 73 74 3a 3a           boost::
2b70: 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20  mutex *mutex,.  
2b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2b90: 20 20 20 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f         boost::co
2ba0: 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65  ndition_variable
2bb0: 20 2a 63 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 76   *cond_var);.  v
2bc0: 6f 69 64 20 47 65 74 43 6f 6e 74 61 63 74 43 61  oid GetContactCa
2bd0: 6c 6c 62 61 63 6b 28 69 6e 74 20 72 65 73 75 6c  llback(int resul
2be0: 74 5f 69 6e 2c 0a 20 20 20 20 20 20 20 20 20 20  t_in,.          
2bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c00: 43 6f 6e 74 61 63 74 20 63 6f 6e 74 61 63 74 5f  Contact contact_
2c10: 69 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  in,.            
2c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62 6f                bo
2c30: 6f 73 74 3a 3a 6d 75 74 65 78 20 2a 6d 75 74 65  ost::mutex *mute
2c40: 78 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  x,.             
2c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 62 6f 6f               boo
2c60: 73 74 3a 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61  st::condition_va
2c70: 72 69 61 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72  riable *cond_var
2c80: 29 3b 0a 20 20 76 6f 69 64 20 50 69 6e 67 43 61  );.  void PingCa
2c90: 6c 6c 62 61 63 6b 28 69 6e 74 20 72 65 73 75 6c  llback(int resul
2ca0: 74 5f 69 6e 2c 0a 20 20 20 20 20 20 20 20 20 20  t_in,.          
2cb0: 20 20 20 20 20 20 20 20 20 20 62 6f 6f 73 74 3a            boost:
2cc0: 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20  :mutex *mutex,. 
2cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ce0: 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74     boost::condit
2cf0: 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f  ion_variable *co
2d00: 6e 64 5f 76 61 72 29 3b 0a 20 20 62 6f 6f 6c 20  nd_var);.  bool 
2d10: 52 65 73 75 6c 74 52 65 61 64 79 28 69 6e 74 20  ResultReady(int 
2d20: 2a 72 65 73 75 6c 74 29 20 7b 20 72 65 74 75 72  *result) { retur
2d30: 6e 20 2a 72 65 73 75 6c 74 20 21 3d 20 6b 50 65  n *result != kPe
2d40: 6e 64 69 6e 67 52 65 73 75 6c 74 3b 20 7d 0a 20  ndingResult; }. 
2d50: 20 4a 6f 69 6e 46 75 6e 63 74 6f 72 20 6a 6f 69   JoinFunctor joi
2d60: 6e 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 53 74  n_functor_;.  St
2d70: 6f 72 65 46 75 6e 63 74 6f 72 20 73 74 6f 72 65  oreFunctor store
2d80: 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 44 65 6c  _functor_;.  Del
2d90: 65 74 65 46 75 6e 63 74 6f 72 20 64 65 6c 65 74  eteFunctor delet
2da0: 65 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 55 70  e_functor_;.  Up
2db0: 64 61 74 65 46 75 6e 63 74 6f 72 20 75 70 64 61  dateFunctor upda
2dc0: 74 65 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 46  te_functor_;.  F
2dd0: 69 6e 64 56 61 6c 75 65 46 75 6e 63 74 6f 72 20  indValueFunctor 
2de0: 66 69 6e 64 5f 76 61 6c 75 65 5f 66 75 6e 63 74  find_value_funct
2df0: 6f 72 5f 3b 0a 20 20 46 69 6e 64 4e 6f 64 65 73  or_;.  FindNodes
2e00: 46 75 6e 63 74 6f 72 20 66 69 6e 64 5f 6e 6f 64  Functor find_nod
2e10: 65 73 5f 66 75 6e 63 74 6f 72 5f 3b 0a 20 20 47  es_functor_;.  G
2e20: 65 74 43 6f 6e 74 61 63 74 46 75 6e 63 74 6f 72  etContactFunctor
2e30: 20 67 65 74 5f 63 6f 6e 74 61 63 74 5f 66 75 6e   get_contact_fun
2e40: 63 74 6f 72 5f 3b 0a 20 20 50 69 6e 67 46 75 6e  ctor_;.  PingFun
2e50: 63 74 6f 72 20 70 69 6e 67 5f 66 75 6e 63 74 6f  ctor ping_functo
2e60: 72 5f 3b 0a 7d 3b 0a 0a 74 65 6d 70 6c 61 74 65  r_;.};..template
2e70: 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54   <typename NodeT
2e80: 79 70 65 3e 0a 73 74 64 3a 3a 73 74 72 69 6e 67  ype>.std::string
2e90: 20 44 65 62 75 67 49 64 28 63 6f 6e 73 74 20 4e   DebugId(const N
2ea0: 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64  odeContainer<Nod
2eb0: 65 54 79 70 65 3e 20 26 63 6f 6e 74 61 69 6e 65  eType> &containe
2ec0: 72 29 20 7b 0a 20 20 72 65 74 75 72 6e 20 6d 61  r) {.  return ma
2ed0: 69 64 73 61 66 65 3a 3a 64 68 74 3a 3a 44 65 62  idsafe::dht::Deb
2ee0: 75 67 49 64 28 63 6f 6e 74 61 69 6e 65 72 2e 6e  ugId(container.n
2ef0: 6f 64 65 28 29 2d 3e 63 6f 6e 74 61 63 74 28 29  ode()->contact()
2f00: 29 3b 0a 7d 0a 0a 0a 74 65 6d 70 6c 61 74 65 3c  );.}...template<
2f10: 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70  typename NodeTyp
2f20: 65 3e 0a 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72  e>.NodeContainer
2f30: 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 4e 6f 64 65  <NodeType>::Node
2f40: 43 6f 6e 74 61 69 6e 65 72 28 29 0a 20 20 20 20  Container().    
2f50: 3a 20 61 73 69 6f 5f 73 65 72 76 69 63 65 5f 28  : asio_service_(
2f60: 29 2c 0a 20 20 20 20 20 20 6c 69 73 74 65 6e 69  ),.      listeni
2f70: 6e 67 5f 74 72 61 6e 73 70 6f 72 74 5f 28 29 2c  ng_transport_(),
2f80: 0a 20 20 20 20 20 20 6d 65 73 73 61 67 65 5f 68  .      message_h
2f90: 61 6e 64 6c 65 72 5f 28 29 2c 0a 20 20 20 20 20  andler_(),.     
2fa0: 20 6b 65 79 5f 70 61 69 72 5f 28 29 2c 0a 20 20   key_pair_(),.  
2fb0: 20 20 20 20 6e 6f 64 65 5f 28 29 2c 0a 20 20 20      node_(),.   
2fc0: 20 20 20 62 6f 6f 74 73 74 72 61 70 5f 63 6f 6e     bootstrap_con
2fd0: 74 61 63 74 73 5f 28 29 2c 0a 20 20 20 20 20 20  tacts_(),.      
2fe0: 6a 6f 69 6e 5f 72 65 73 75 6c 74 5f 28 6b 50 65  join_result_(kPe
2ff0: 6e 64 69 6e 67 52 65 73 75 6c 74 29 2c 0a 20 20  ndingResult),.  
3000: 20 20 20 20 73 74 6f 72 65 5f 72 65 73 75 6c 74      store_result
3010: 5f 28 6b 50 65 6e 64 69 6e 67 52 65 73 75 6c 74  _(kPendingResult
3020: 29 2c 0a 20 20 20 20 20 20 64 65 6c 65 74 65 5f  ),.      delete_
3030: 72 65 73 75 6c 74 5f 28 6b 50 65 6e 64 69 6e 67  result_(kPending
3040: 52 65 73 75 6c 74 29 2c 0a 20 20 20 20 20 20 75  Result),.      u
3050: 70 64 61 74 65 5f 72 65 73 75 6c 74 5f 28 6b 50  pdate_result_(kP
3060: 65 6e 64 69 6e 67 52 65 73 75 6c 74 29 2c 0a 20  endingResult),. 
3070: 20 20 20 20 20 66 69 6e 64 5f 6e 6f 64 65 73 5f       find_nodes_
3080: 72 65 73 75 6c 74 5f 28 6b 50 65 6e 64 69 6e 67  result_(kPending
3090: 52 65 73 75 6c 74 29 2c 0a 20 20 20 20 20 20 67  Result),.      g
30a0: 65 74 5f 63 6f 6e 74 61 63 74 5f 72 65 73 75 6c  et_contact_resul
30b0: 74 5f 28 6b 50 65 6e 64 69 6e 67 52 65 73 75 6c  t_(kPendingResul
30c0: 74 29 2c 0a 20 20 20 20 20 20 70 69 6e 67 5f 72  t),.      ping_r
30d0: 65 73 75 6c 74 5f 28 6b 50 65 6e 64 69 6e 67 52  esult_(kPendingR
30e0: 65 73 75 6c 74 29 2c 0a 20 20 20 20 20 20 66 69  esult),.      fi
30f0: 6e 64 5f 76 61 6c 75 65 5f 72 65 74 75 72 6e 73  nd_value_returns
3100: 5f 28 29 2c 0a 20 20 20 20 20 20 66 69 6e 64 5f  _(),.      find_
3110: 6e 6f 64 65 73 5f 63 6c 6f 73 65 73 74 5f 6e 6f  nodes_closest_no
3120: 64 65 73 5f 28 29 2c 0a 20 20 20 20 20 20 67 6f  des_(),.      go
3130: 74 74 65 6e 5f 63 6f 6e 74 61 63 74 5f 28 29 2c  tten_contact_(),
3140: 0a 20 20 20 20 20 20 77 61 69 74 5f 66 6f 72 5f  .      wait_for_
3150: 6a 6f 69 6e 5f 66 75 6e 63 74 6f 72 5f 28 29 2c  join_functor_(),
3160: 0a 20 20 20 20 20 20 77 61 69 74 5f 66 6f 72 5f  .      wait_for_
3170: 73 74 6f 72 65 5f 66 75 6e 63 74 6f 72 5f 28 29  store_functor_()
3180: 2c 0a 20 20 20 20 20 20 77 61 69 74 5f 66 6f 72  ,.      wait_for
3190: 5f 64 65 6c 65 74 65 5f 66 75 6e 63 74 6f 72 5f  _delete_functor_
31a0: 28 29 2c 0a 20 20 20 20 20 20 77 61 69 74 5f 66  (),.      wait_f
31b0: 6f 72 5f 75 70 64 61 74 65 5f 66 75 6e 63 74 6f  or_update_functo
31c0: 72 5f 28 29 2c 0a 20 20 20 20 20 20 77 61 69 74  r_(),.      wait
31d0: 5f 66 6f 72 5f 66 69 6e 64 5f 76 61 6c 75 65 5f  _for_find_value_
31e0: 66 75 6e 63 74 6f 72 5f 28 29 2c 0a 20 20 20 20  functor_(),.    
31f0: 20 20 77 61 69 74 5f 66 6f 72 5f 66 69 6e 64 5f    wait_for_find_
3200: 6e 6f 64 65 73 5f 66 75 6e 63 74 6f 72 5f 28 29  nodes_functor_()
3210: 2c 0a 20 20 20 20 20 20 77 61 69 74 5f 66 6f 72  ,.      wait_for
3220: 5f 67 65 74 5f 63 6f 6e 74 61 63 74 5f 66 75 6e  _get_contact_fun
3230: 63 74 6f 72 5f 28 29 2c 0a 20 20 20 20 20 20 77  ctor_(),.      w
3240: 61 69 74 5f 66 6f 72 5f 70 69 6e 67 5f 66 75 6e  ait_for_ping_fun
3250: 63 74 6f 72 5f 28 29 2c 0a 20 20 20 20 20 20 6a  ctor_(),.      j
3260: 6f 69 6e 5f 66 75 6e 63 74 6f 72 5f 28 29 2c 0a  oin_functor_(),.
3270: 20 20 20 20 20 20 73 74 6f 72 65 5f 66 75 6e 63        store_func
3280: 74 6f 72 5f 28 29 2c 0a 20 20 20 20 20 20 64 65  tor_(),.      de
3290: 6c 65 74 65 5f 66 75 6e 63 74 6f 72 5f 28 29 2c  lete_functor_(),
32a0: 0a 20 20 20 20 20 20 75 70 64 61 74 65 5f 66 75  .      update_fu
32b0: 6e 63 74 6f 72 5f 28 29 2c 0a 20 20 20 20 20 20  nctor_(),.      
32c0: 66 69 6e 64 5f 76 61 6c 75 65 5f 66 75 6e 63 74  find_value_funct
32d0: 6f 72 5f 28 29 2c 0a 20 20 20 20 20 20 66 69 6e  or_(),.      fin
32e0: 64 5f 6e 6f 64 65 73 5f 66 75 6e 63 74 6f 72 5f  d_nodes_functor_
32f0: 28 29 2c 0a 20 20 20 20 20 20 67 65 74 5f 63 6f  (),.      get_co
3300: 6e 74 61 63 74 5f 66 75 6e 63 74 6f 72 5f 28 29  ntact_functor_()
3310: 2c 0a 20 20 20 20 20 20 70 69 6e 67 5f 66 75 6e  ,.      ping_fun
3320: 63 74 6f 72 5f 28 29 20 7b 0a 20 20 77 61 69 74  ctor_() {.  wait
3330: 5f 66 6f 72 5f 6a 6f 69 6e 5f 66 75 6e 63 74 6f  _for_join_functo
3340: 72 5f 20 3d 0a 20 20 20 20 20 20 73 74 64 3a 3a  r_ =.      std::
3350: 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e 74 61 69  bind(&NodeContai
3360: 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 52  ner<NodeType>::R
3370: 65 73 75 6c 74 52 65 61 64 79 2c 20 74 68 69 73  esultReady, this
3380: 2c 20 26 6a 6f 69 6e 5f 72 65 73 75 6c 74 5f 29  , &join_result_)
3390: 3b 0a 20 20 77 61 69 74 5f 66 6f 72 5f 73 74 6f  ;.  wait_for_sto
33a0: 72 65 5f 66 75 6e 63 74 6f 72 5f 20 3d 0a 20 20  re_functor_ =.  
33b0: 20 20 20 20 73 74 64 3a 3a 62 69 6e 64 28 26 4e      std::bind(&N
33c0: 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64  odeContainer<Nod
33d0: 65 54 79 70 65 3e 3a 3a 52 65 73 75 6c 74 52 65  eType>::ResultRe
33e0: 61 64 79 2c 20 74 68 69 73 2c 20 26 73 74 6f 72  ady, this, &stor
33f0: 65 5f 72 65 73 75 6c 74 5f 29 3b 0a 20 20 77 61  e_result_);.  wa
3400: 69 74 5f 66 6f 72 5f 64 65 6c 65 74 65 5f 66 75  it_for_delete_fu
3410: 6e 63 74 6f 72 5f 20 3d 0a 20 20 20 20 20 20 73  nctor_ =.      s
3420: 74 64 3a 3a 62 69 6e 64 28 26 4e 6f 64 65 43 6f  td::bind(&NodeCo
3430: 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65  ntainer<NodeType
3440: 3e 3a 3a 52 65 73 75 6c 74 52 65 61 64 79 2c 20  >::ResultReady, 
3450: 74 68 69 73 2c 20 26 64 65 6c 65 74 65 5f 72 65  this, &delete_re
3460: 73 75 6c 74 5f 29 3b 0a 20 20 77 61 69 74 5f 66  sult_);.  wait_f
3470: 6f 72 5f 75 70 64 61 74 65 5f 66 75 6e 63 74 6f  or_update_functo
3480: 72 5f 20 3d 0a 20 20 20 20 20 20 73 74 64 3a 3a  r_ =.      std::
3490: 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e 74 61 69  bind(&NodeContai
34a0: 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 52  ner<NodeType>::R
34b0: 65 73 75 6c 74 52 65 61 64 79 2c 20 74 68 69 73  esultReady, this
34c0: 2c 20 26 75 70 64 61 74 65 5f 72 65 73 75 6c 74  , &update_result
34d0: 5f 29 3b 0a 20 20 77 61 69 74 5f 66 6f 72 5f 66  _);.  wait_for_f
34e0: 69 6e 64 5f 76 61 6c 75 65 5f 66 75 6e 63 74 6f  ind_value_functo
34f0: 72 5f 20 3d 0a 20 20 20 20 20 20 73 74 64 3a 3a  r_ =.      std::
3500: 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e 74 61 69  bind(&NodeContai
3510: 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 52  ner<NodeType>::R
3520: 65 73 75 6c 74 52 65 61 64 79 2c 20 74 68 69 73  esultReady, this
3530: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
3540: 20 20 26 66 69 6e 64 5f 76 61 6c 75 65 5f 72 65    &find_value_re
3550: 74 75 72 6e 73 5f 2e 72 65 74 75 72 6e 5f 63 6f  turns_.return_co
3560: 64 65 29 3b 0a 20 20 77 61 69 74 5f 66 6f 72 5f  de);.  wait_for_
3570: 66 69 6e 64 5f 6e 6f 64 65 73 5f 66 75 6e 63 74  find_nodes_funct
3580: 6f 72 5f 20 3d 0a 20 20 20 20 20 20 73 74 64 3a  or_ =.      std:
3590: 3a 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e 74 61  :bind(&NodeConta
35a0: 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a  iner<NodeType>::
35b0: 52 65 73 75 6c 74 52 65 61 64 79 2c 20 74 68 69  ResultReady, thi
35c0: 73 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  s,.             
35d0: 20 20 20 26 66 69 6e 64 5f 6e 6f 64 65 73 5f 72     &find_nodes_r
35e0: 65 73 75 6c 74 5f 29 3b 0a 20 20 77 61 69 74 5f  esult_);.  wait_
35f0: 66 6f 72 5f 67 65 74 5f 63 6f 6e 74 61 63 74 5f  for_get_contact_
3600: 66 75 6e 63 74 6f 72 5f 20 3d 0a 20 20 20 20 20  functor_ =.     
3610: 20 73 74 64 3a 3a 62 69 6e 64 28 26 4e 6f 64 65   std::bind(&Node
3620: 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79  Container<NodeTy
3630: 70 65 3e 3a 3a 52 65 73 75 6c 74 52 65 61 64 79  pe>::ResultReady
3640: 2c 20 74 68 69 73 2c 0a 20 20 20 20 20 20 20 20  , this,.        
3650: 20 20 20 20 20 20 20 20 26 67 65 74 5f 63 6f 6e          &get_con
3660: 74 61 63 74 5f 72 65 73 75 6c 74 5f 29 3b 0a 20  tact_result_);. 
3670: 20 77 61 69 74 5f 66 6f 72 5f 70 69 6e 67 5f 66   wait_for_ping_f
3680: 75 6e 63 74 6f 72 5f 20 3d 0a 20 20 20 20 20 20  unctor_ =.      
3690: 73 74 64 3a 3a 62 69 6e 64 28 26 4e 6f 64 65 43  std::bind(&NodeC
36a0: 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70  ontainer<NodeTyp
36b0: 65 3e 3a 3a 52 65 73 75 6c 74 52 65 61 64 79 2c  e>::ResultReady,
36c0: 20 74 68 69 73 2c 20 26 70 69 6e 67 5f 72 65 73   this, &ping_res
36d0: 75 6c 74 5f 29 3b 0a 7d 0a 0a 74 65 6d 70 6c 61  ult_);.}..templa
36e0: 74 65 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65  te<typename Node
36f0: 54 79 70 65 3e 0a 4e 6f 64 65 43 6f 6e 74 61 69  Type>.NodeContai
3700: 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 7e  ner<NodeType>::~
3710: 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 28 29 20  NodeContainer() 
3720: 7b 0a 20 20 53 74 6f 70 28 6e 75 6c 6c 70 74 72  {.  Stop(nullptr
3730: 29 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c  );.}..template <
3740: 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70  typename NodeTyp
3750: 65 3e 0a 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74  e>.void NodeCont
3760: 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a  ainer<NodeType>:
3770: 3a 49 6e 69 74 28 0a 20 20 20 20 75 69 6e 74 38  :Init(.    uint8
3780: 5f 74 20 74 68 72 65 61 64 5f 63 6f 75 6e 74 2c  _t thread_count,
3790: 0a 20 20 20 20 4b 65 79 50 61 69 72 50 74 72 20  .    KeyPairPtr 
37a0: 6b 65 79 5f 70 61 69 72 2c 0a 20 20 20 20 4d 65  key_pair,.    Me
37b0: 73 73 61 67 65 48 61 6e 64 6c 65 72 50 74 72 20  ssageHandlerPtr 
37c0: 6d 65 73 73 61 67 65 5f 68 61 6e 64 6c 65 72 2c  message_handler,
37d0: 0a 20 20 20 20 62 6f 6f 6c 20 63 6c 69 65 6e 74  .    bool client
37e0: 5f 6f 6e 6c 79 5f 6e 6f 64 65 2c 0a 20 20 20 20  _only_node,.    
37f0: 75 69 6e 74 31 36 5f 74 20 6b 2c 0a 20 20 20 20  uint16_t k,.    
3800: 75 69 6e 74 31 36 5f 74 20 61 6c 70 68 61 2c 0a  uint16_t alpha,.
3810: 20 20 20 20 75 69 6e 74 31 36 5f 74 20 62 65 74      uint16_t bet
3820: 61 2c 0a 20 20 20 20 62 70 74 69 6d 65 3a 3a 74  a,.    bptime::t
3830: 69 6d 65 5f 64 75 72 61 74 69 6f 6e 20 6d 65 61  ime_duration mea
3840: 6e 5f 72 65 66 72 65 73 68 5f 69 6e 74 65 72 76  n_refresh_interv
3850: 61 6c 29 20 7b 0a 20 20 2f 2f 20 43 72 65 61 74  al) {.  // Creat
3860: 65 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73  e worker threads
3870: 20 66 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75   for asynchronou
3880: 73 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 20 20  s operations..  
3890: 61 73 69 6f 5f 73 65 72 76 69 63 65 5f 2e 53 74  asio_service_.St
38a0: 61 72 74 28 74 68 72 65 61 64 5f 63 6f 75 6e 74  art(thread_count
38b0: 29 3b 0a 0a 20 20 2f 2f 20 53 65 74 20 75 70 20  );..  // Set up 
38c0: 70 72 69 76 61 74 65 5f 6b 65 79 20 69 66 20 69  private_key if i
38d0: 74 20 77 61 73 6e 27 74 20 70 61 73 73 65 64 20  t wasn't passed 
38e0: 69 6e 20 2d 20 6d 61 6b 65 20 73 69 67 6e 69 6e  in - make signin
38f0: 67 5f 6b 65 79 5f 69 64 20 63 6f 6d 70 61 74 69  g_key_id compati
3900: 62 6c 65 0a 20 20 2f 2f 20 77 69 74 68 20 74 79  ble.  // with ty
3910: 70 65 20 4e 6f 64 65 49 64 20 73 6f 20 74 68 61  pe NodeId so tha
3920: 74 20 74 68 65 20 6e 6f 64 65 27 73 20 49 44 20  t the node's ID 
3930: 63 61 6e 20 62 65 20 73 65 74 20 61 73 20 74 68  can be set as th
3940: 65 20 70 75 62 6c 69 63 20 6b 65 79 27 73 20 49  e public key's I
3950: 44 0a 20 20 69 66 20 28 6b 65 79 5f 70 61 69 72  D.  if (key_pair
3960: 29 20 7b 0a 20 20 20 20 6b 65 79 5f 70 61 69 72  ) {.    key_pair
3970: 5f 20 3d 20 6b 65 79 5f 70 61 69 72 3b 0a 20 20  _ = key_pair;.  
3980: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 6b 65 79  } else {.    key
3990: 5f 70 61 69 72 5f 20 3d 20 4b 65 79 50 61 69 72  _pair_ = KeyPair
39a0: 50 74 72 28 6e 65 77 20 61 73 79 6d 6d 3a 3a 4b  Ptr(new asymm::K
39b0: 65 79 73 29 3b 0a 20 20 20 20 61 73 79 6d 6d 3a  eys);.    asymm:
39c0: 3a 47 65 6e 65 72 61 74 65 4b 65 79 50 61 69 72  :GenerateKeyPair
39d0: 28 6b 65 79 5f 70 61 69 72 5f 2e 67 65 74 28 29  (key_pair_.get()
39e0: 29 3b 0a 20 20 20 20 6b 65 79 5f 70 61 69 72 5f  );.    key_pair_
39f0: 2d 3e 69 64 65 6e 74 69 74 79 20 3d 20 52 61 6e  ->identity = Ran
3a00: 64 6f 6d 53 74 72 69 6e 67 28 63 72 79 70 74 6f  domString(crypto
3a10: 3a 3a 53 48 41 35 31 32 3a 3a 44 49 47 45 53 54  ::SHA512::DIGEST
3a20: 53 49 5a 45 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  SIZE);.  }..  if
3a30: 20 28 6d 65 73 73 61 67 65 5f 68 61 6e 64 6c 65   (message_handle
3a40: 72 29 20 7b 0a 20 20 20 20 6d 65 73 73 61 67 65  r) {.    message
3a50: 5f 68 61 6e 64 6c 65 72 5f 20 3d 20 6d 65 73 73  _handler_ = mess
3a60: 61 67 65 5f 68 61 6e 64 6c 65 72 3b 0a 20 20 7d  age_handler;.  }
3a70: 20 65 6c 73 65 20 7b 0a 20 20 20 20 50 72 69 76   else {.    Priv
3a80: 61 74 65 4b 65 79 50 74 72 20 70 72 69 76 5f 6b  ateKeyPtr priv_k
3a90: 65 79 20 3d 20 50 72 69 76 61 74 65 4b 65 79 50  ey = PrivateKeyP
3aa0: 74 72 28 0a 20 20 20 20 20 20 20 20 6e 65 77 20  tr(.        new 
3ab0: 61 73 79 6d 6d 3a 3a 50 72 69 76 61 74 65 4b 65  asymm::PrivateKe
3ac0: 79 28 6b 65 79 5f 70 61 69 72 5f 2d 3e 70 72 69  y(key_pair_->pri
3ad0: 76 61 74 65 5f 6b 65 79 29 29 3b 0a 20 20 20 20  vate_key));.    
3ae0: 6d 65 73 73 61 67 65 5f 68 61 6e 64 6c 65 72 5f  message_handler_
3af0: 2e 72 65 73 65 74 28 6e 65 77 20 4d 65 73 73 61  .reset(new Messa
3b00: 67 65 48 61 6e 64 6c 65 72 28 70 72 69 76 5f 6b  geHandler(priv_k
3b10: 65 79 29 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2f 20  ey));.  }..  // 
3b20: 49 66 20 74 68 69 73 20 69 73 20 6e 6f 74 20 61  If this is not a
3b30: 20 63 6c 69 65 6e 74 20 6e 6f 64 65 2c 20 63 6f   client node, co
3b40: 6e 6e 65 63 74 20 6d 65 73 73 61 67 65 20 68 61  nnect message ha
3b50: 6e 64 6c 65 72 20 74 6f 20 74 72 61 6e 73 70 6f  ndler to transpo
3b60: 72 74 20 66 6f 72 0a 20 20 2f 2f 20 69 6e 63 6f  rt for.  // inco
3b70: 6d 69 6e 67 20 72 61 77 20 6d 65 73 73 61 67 65  ming raw message
3b80: 73 2e 20 20 44 6f 6e 27 74 20 6e 65 65 64 20 74  s.  Don't need t
3b90: 6f 20 63 6f 6e 6e 65 63 74 20 74 6f 20 6f 6e 5f  o connect to on_
3ba0: 65 72 72 6f 72 28 29 20 61 73 20 73 65 72 76 69  error() as servi
3bb0: 63 65 0a 20 20 2f 2f 20 64 6f 65 73 6e 27 74 20  ce.  // doesn't 
3bc0: 63 61 72 65 20 69 66 20 72 65 70 6c 79 20 73 75  care if reply su
3bd0: 63 63 65 65 64 73 20 6f 72 20 6e 6f 74 2e 0a 20  cceeds or not.. 
3be0: 20 69 66 20 28 21 63 6c 69 65 6e 74 5f 6f 6e 6c   if (!client_onl
3bf0: 79 5f 6e 6f 64 65 29 20 7b 0a 2f 2f 20 20 20 20  y_node) {.//    
3c00: 6c 69 73 74 65 6e 69 6e 67 5f 74 72 61 6e 73 70  listening_transp
3c10: 6f 72 74 5f 2e 72 65 73 65 74 28 0a 2f 2f 20 20  ort_.reset(.//  
3c20: 20 20 20 20 20 20 6e 65 77 20 74 72 61 6e 73 70        new transp
3c30: 6f 72 74 3a 3a 54 63 70 54 72 61 6e 73 70 6f 72  ort::TcpTranspor
3c40: 74 28 61 73 69 6f 5f 73 65 72 76 69 63 65 5f 2e  t(asio_service_.
3c50: 73 65 72 76 69 63 65 28 29 29 29 3b 0a 20 20 20  service()));.   
3c60: 20 6c 69 73 74 65 6e 69 6e 67 5f 74 72 61 6e 73   listening_trans
3c70: 70 6f 72 74 5f 2e 72 65 73 65 74 28 0a 20 20 20  port_.reset(.   
3c80: 20 20 20 20 20 6e 65 77 20 74 72 61 6e 73 70 6f       new transpo
3c90: 72 74 3a 3a 54 63 70 54 72 61 6e 73 70 6f 72 74  rt::TcpTransport
3ca0: 28 61 73 69 6f 5f 73 65 72 76 69 63 65 5f 2e 73  (asio_service_.s
3cb0: 65 72 76 69 63 65 28 29 29 29 3b 0a 20 20 20 20  ervice()));.    
3cc0: 6c 69 73 74 65 6e 69 6e 67 5f 74 72 61 6e 73 70  listening_transp
3cd0: 6f 72 74 5f 2d 3e 6f 6e 5f 6d 65 73 73 61 67 65  ort_->on_message
3ce0: 5f 72 65 63 65 69 76 65 64 28 29 2d 3e 63 6f 6e  _received()->con
3cf0: 6e 65 63 74 28 0a 20 20 20 20 20 20 20 20 74 72  nect(.        tr
3d00: 61 6e 73 70 6f 72 74 3a 3a 4f 6e 4d 65 73 73 61  ansport::OnMessa
3d10: 67 65 52 65 63 65 69 76 65 64 3a 3a 65 6c 65 6d  geReceived::elem
3d20: 65 6e 74 5f 74 79 70 65 3a 3a 73 6c 6f 74 5f 74  ent_type::slot_t
3d30: 79 70 65 28 0a 20 20 20 20 20 20 20 20 20 20 20  ype(.           
3d40: 20 26 4d 65 73 73 61 67 65 48 61 6e 64 6c 65 72   &MessageHandler
3d50: 3a 3a 4f 6e 4d 65 73 73 61 67 65 52 65 63 65 69  ::OnMessageRecei
3d60: 76 65 64 2c 20 6d 65 73 73 61 67 65 5f 68 61 6e  ved, message_han
3d70: 64 6c 65 72 5f 2e 67 65 74 28 29 2c 0a 20 20 20  dler_.get(),.   
3d80: 20 20 20 20 20 20 20 20 20 5f 31 2c 20 5f 32 2c           _1, _2,
3d90: 20 5f 33 2c 20 5f 34 29 2e 74 72 61 63 6b 5f 66   _3, _4).track_f
3da0: 6f 72 65 69 67 6e 28 6d 65 73 73 61 67 65 5f 68  oreign(message_h
3db0: 61 6e 64 6c 65 72 5f 29 29 3b 0a 20 20 20 20 6c  andler_));.    l
3dc0: 69 73 74 65 6e 69 6e 67 5f 74 72 61 6e 73 70 6f  istening_transpo
3dd0: 72 74 5f 2d 3e 6f 6e 5f 65 72 72 6f 72 28 29 2d  rt_->on_error()-
3de0: 3e 63 6f 6e 6e 65 63 74 28 0a 20 20 20 20 20 20  >connect(.      
3df0: 20 20 74 72 61 6e 73 70 6f 72 74 3a 3a 4f 6e 45    transport::OnE
3e00: 72 72 6f 72 3a 3a 65 6c 65 6d 65 6e 74 5f 74 79  rror::element_ty
3e10: 70 65 3a 3a 73 6c 6f 74 5f 74 79 70 65 28 0a 20  pe::slot_type(. 
3e20: 20 20 20 20 20 20 20 20 20 20 20 26 4d 65 73 73             &Mess
3e30: 61 67 65 48 61 6e 64 6c 65 72 3a 3a 4f 6e 45 72  ageHandler::OnEr
3e40: 72 6f 72 2c 20 6d 65 73 73 61 67 65 5f 68 61 6e  ror, message_han
3e50: 64 6c 65 72 5f 2e 67 65 74 28 29 2c 0a 20 20 20  dler_.get(),.   
3e60: 20 20 20 20 20 20 20 20 20 5f 31 2c 20 5f 32 29           _1, _2)
3e70: 2e 74 72 61 63 6b 5f 66 6f 72 65 69 67 6e 28 6d  .track_foreign(m
3e80: 65 73 73 61 67 65 5f 68 61 6e 64 6c 65 72 29 29  essage_handler))
3e90: 3b 0a 20 20 7d 0a 0a 20 20 2f 2f 20 43 72 65 61  ;.  }..  // Crea
3ea0: 74 65 20 6e 6f 64 65 0a 20 20 6e 6f 64 65 5f 2e  te node.  node_.
3eb0: 72 65 73 65 74 28 6e 65 77 20 4e 6f 64 65 54 79  reset(new NodeTy
3ec0: 70 65 28 61 73 69 6f 5f 73 65 72 76 69 63 65 5f  pe(asio_service_
3ed0: 2e 73 65 72 76 69 63 65 28 29 2c 20 6c 69 73 74  .service(), list
3ee0: 65 6e 69 6e 67 5f 74 72 61 6e 73 70 6f 72 74 5f  ening_transport_
3ef0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
3f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 6d 65 73               mes
3f10: 73 61 67 65 5f 68 61 6e 64 6c 65 72 5f 2c 20 6b  sage_handler_, k
3f20: 65 79 5f 70 61 69 72 5f 2c 20 63 6c 69 65 6e 74  ey_pair_, client
3f30: 5f 6f 6e 6c 79 5f 6e 6f 64 65 2c 20 6b 2c 0a 20  _only_node, k,. 
3f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f50: 20 20 20 20 20 20 20 20 20 20 61 6c 70 68 61 2c            alpha,
3f60: 20 62 65 74 61 2c 20 6d 65 61 6e 5f 72 65 66 72   beta, mean_refr
3f70: 65 73 68 5f 69 6e 74 65 72 76 61 6c 29 29 3b 0a  esh_interval));.
3f80: 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70  }..template <typ
3f90: 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a  ename NodeType>.
3fa0: 69 6e 74 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65  int NodeContaine
3fb0: 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 53 74 61  r<NodeType>::Sta
3fc0: 72 74 28 0a 20 20 20 20 63 6f 6e 73 74 20 73 74  rt(.    const st
3fd0: 64 3a 3a 76 65 63 74 6f 72 3c 64 68 74 3a 3a 43  d::vector<dht::C
3fe0: 6f 6e 74 61 63 74 3e 20 26 62 6f 6f 74 73 74 72  ontact> &bootstr
3ff0: 61 70 5f 63 6f 6e 74 61 63 74 73 2c 0a 20 20 20  ap_contacts,.   
4000: 20 73 74 64 3a 3a 70 61 69 72 3c 75 69 6e 74 31   std::pair<uint1
4010: 36 5f 74 2c 20 75 69 6e 74 31 36 5f 74 3e 20 70  6_t, uint16_t> p
4020: 6f 72 74 5f 72 61 6e 67 65 29 20 7b 0a 20 20 62  ort_range) {.  b
4030: 6f 6f 74 73 74 72 61 70 5f 63 6f 6e 74 61 63 74  ootstrap_contact
4040: 73 5f 20 3d 20 62 6f 6f 74 73 74 72 61 70 5f 63  s_ = bootstrap_c
4050: 6f 6e 74 61 63 74 73 3b 0a 20 20 69 6e 74 20 72  ontacts;.  int r
4060: 65 73 75 6c 74 28 6b 50 65 6e 64 69 6e 67 52 65  esult(kPendingRe
4070: 73 75 6c 74 29 3b 0a 20 20 69 66 20 28 21 6e 6f  sult);.  if (!no
4080: 64 65 5f 2d 3e 63 6c 69 65 6e 74 5f 6f 6e 6c 79  de_->client_only
4090: 5f 6e 6f 64 65 28 29 29 20 7b 0a 20 20 20 20 20  _node()) {.     
40a0: 2f 2f 20 57 6f 72 6b 61 72 6f 75 6e 64 20 75 6e  // Workaround un
40b0: 74 69 6c 20 4e 41 54 20 64 65 74 65 63 74 69 6f  til NAT detectio
40c0: 6e 20 69 73 20 75 70 2e 0a 20 20 20 20 73 74 64  n is up..    std
40d0: 3a 3a 76 65 63 74 6f 72 3c 74 72 61 6e 73 70 6f  ::vector<transpo
40e0: 72 74 3a 3a 49 50 3e 20 69 70 73 20 3d 20 74 72  rt::IP> ips = tr
40f0: 61 6e 73 70 6f 72 74 3a 3a 47 65 74 4c 6f 63 61  ansport::GetLoca
4100: 6c 41 64 64 72 65 73 73 65 73 28 29 3b 0a 20 20  lAddresses();.  
4110: 20 20 74 72 61 6e 73 70 6f 72 74 3a 3a 45 6e 64    transport::End
4120: 70 6f 69 6e 74 20 65 6e 64 70 6f 69 6e 74 28 0a  point endpoint(.
4130: 20 20 20 20 20 20 20 20 69 70 73 2e 65 6d 70 74          ips.empt
4140: 79 28 29 20 3f 20 49 50 3a 3a 66 72 6f 6d 5f 73  y() ? IP::from_s
4150: 74 72 69 6e 67 28 22 31 32 37 2e 30 2e 30 2e 31  tring("127.0.0.1
4160: 22 29 20 3a 20 69 70 73 2e 66 72 6f 6e 74 28 29  ") : ips.front()
4170: 2c 20 30 29 3b 0a 20 20 20 20 69 6e 74 20 72 65  , 0);.    int re
4180: 73 75 6c 74 28 74 72 61 6e 73 70 6f 72 74 3a 3a  sult(transport::
4190: 6b 45 72 72 6f 72 29 3b 0a 20 20 20 20 73 74 64  kError);.    std
41a0: 3a 3a 76 65 63 74 6f 72 3c 50 6f 72 74 3e 20 74  ::vector<Port> t
41b0: 72 79 5f 70 6f 72 74 73 3b 0a 20 20 20 20 69 66  ry_ports;.    if
41c0: 20 28 70 6f 72 74 5f 72 61 6e 67 65 2e 66 69 72   (port_range.fir
41d0: 73 74 20 3d 3d 20 70 6f 72 74 5f 72 61 6e 67 65  st == port_range
41e0: 2e 73 65 63 6f 6e 64 29 20 7b 0a 20 20 20 20 20  .second) {.     
41f0: 20 74 72 79 5f 70 6f 72 74 73 2e 72 65 73 65 72   try_ports.reser
4200: 76 65 28 31 29 3b 0a 20 20 20 20 20 20 74 72 79  ve(1);.      try
4210: 5f 70 6f 72 74 73 2e 70 75 73 68 5f 62 61 63 6b  _ports.push_back
4220: 28 70 6f 72 74 5f 72 61 6e 67 65 2e 66 69 72 73  (port_range.firs
4230: 74 29 3b 0a 20 20 20 20 7d 20 65 6c 73 65 20 20  t);.    } else  
4240: 7b 0a 20 20 20 20 20 20 69 66 20 28 70 6f 72 74  {.      if (port
4250: 5f 72 61 6e 67 65 2e 66 69 72 73 74 20 3e 20 70  _range.first > p
4260: 6f 72 74 5f 72 61 6e 67 65 2e 73 65 63 6f 6e 64  ort_range.second
4270: 29 0a 20 20 20 20 20 20 20 20 70 6f 72 74 5f 72  ).        port_r
4280: 61 6e 67 65 20 3d 20 73 74 64 3a 3a 6d 61 6b 65  ange = std::make
4290: 5f 70 61 69 72 28 70 6f 72 74 5f 72 61 6e 67 65  _pair(port_range
42a0: 2e 73 65 63 6f 6e 64 2c 20 70 6f 72 74 5f 72 61  .second, port_ra
42b0: 6e 67 65 2e 66 69 72 73 74 29 3b 0a 20 20 20 20  nge.first);.    
42c0: 20 20 74 72 79 5f 70 6f 72 74 73 2e 72 65 73 65    try_ports.rese
42d0: 72 76 65 28 70 6f 72 74 5f 72 61 6e 67 65 2e 73  rve(port_range.s
42e0: 65 63 6f 6e 64 20 2d 20 70 6f 72 74 5f 72 61 6e  econd - port_ran
42f0: 67 65 2e 66 69 72 73 74 29 3b 0a 20 20 20 20 20  ge.first);.     
4300: 20 66 6f 72 20 28 50 6f 72 74 20 70 6f 72 74 28   for (Port port(
4310: 70 6f 72 74 5f 72 61 6e 67 65 2e 66 69 72 73 74  port_range.first
4320: 29 3b 20 70 6f 72 74 20 21 3d 20 70 6f 72 74 5f  ); port != port_
4330: 72 61 6e 67 65 2e 73 65 63 6f 6e 64 3b 20 2b 2b  range.second; ++
4340: 70 6f 72 74 29 0a 20 20 20 20 20 20 20 20 74 72  port).        tr
4350: 79 5f 70 6f 72 74 73 2e 70 75 73 68 5f 62 61 63  y_ports.push_bac
4360: 6b 28 70 6f 72 74 29 3b 0a 20 20 20 20 20 20 73  k(port);.      s
4370: 74 64 3a 3a 72 61 6e 64 6f 6d 5f 73 68 75 66 66  td::random_shuff
4380: 6c 65 28 74 72 79 5f 70 6f 72 74 73 2e 62 65 67  le(try_ports.beg
4390: 69 6e 28 29 2c 20 74 72 79 5f 70 6f 72 74 73 2e  in(), try_ports.
43a0: 65 6e 64 28 29 29 3b 0a 20 20 20 20 7d 0a 20 20  end());.    }.  
43b0: 20 20 66 6f 72 20 28 61 75 74 6f 20 69 74 72 28    for (auto itr(
43c0: 74 72 79 5f 70 6f 72 74 73 2e 62 65 67 69 6e 28  try_ports.begin(
43d0: 29 29 3b 20 69 74 72 20 21 3d 20 74 72 79 5f 70  )); itr != try_p
43e0: 6f 72 74 73 2e 65 6e 64 28 29 3b 20 2b 2b 69 74  orts.end(); ++it
43f0: 72 29 20 7b 0a 20 20 20 20 20 20 65 6e 64 70 6f  r) {.      endpo
4400: 69 6e 74 2e 70 6f 72 74 20 3d 20 2a 69 74 72 3b  int.port = *itr;
4410: 0a 20 20 20 20 20 20 72 65 73 75 6c 74 20 3d 20  .      result = 
4420: 6c 69 73 74 65 6e 69 6e 67 5f 74 72 61 6e 73 70  listening_transp
4430: 6f 72 74 5f 2d 3e 53 74 61 72 74 4c 69 73 74 65  ort_->StartListe
4440: 6e 69 6e 67 28 65 6e 64 70 6f 69 6e 74 29 3b 0a  ning(endpoint);.
4450: 20 20 20 20 20 20 69 66 20 28 74 72 61 6e 73 70        if (transp
4460: 6f 72 74 3a 3a 6b 53 75 63 63 65 73 73 20 3d 3d  ort::kSuccess ==
4470: 20 72 65 73 75 6c 74 29 20 7b 0a 20 20 20 20 20   result) {.     
4480: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
4490: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
44a0: 20 6c 69 73 74 65 6e 69 6e 67 5f 74 72 61 6e 73   listening_trans
44b0: 70 6f 72 74 5f 2d 3e 53 74 6f 70 4c 69 73 74 65  port_->StopListe
44c0: 6e 69 6e 67 28 29 3b 0a 20 20 20 20 20 20 7d 0a  ning();.      }.
44d0: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 28 74 72      }.    if (tr
44e0: 61 6e 73 70 6f 72 74 3a 3a 6b 53 75 63 63 65 73  ansport::kSucces
44f0: 73 20 21 3d 20 72 65 73 75 6c 74 29 20 7b 0a 20  s != result) {. 
4500: 20 20 20 20 20 72 65 74 75 72 6e 20 72 65 73 75       return resu
4510: 6c 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  lt;.    }.  }.. 
4520: 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20 6d 75   boost::mutex mu
4530: 74 65 78 3b 0a 20 20 62 6f 6f 73 74 3a 3a 63 6f  tex;.  boost::co
4540: 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65  ndition_variable
4550: 20 63 6f 6e 64 5f 76 61 72 3b 0a 20 20 4e 6f 64   cond_var;.  Nod
4560: 65 49 64 20 6e 6f 64 65 5f 69 64 28 6b 65 79 5f  eId node_id(key_
4570: 70 61 69 72 5f 2d 3e 69 64 65 6e 74 69 74 79 29  pair_->identity)
4580: 3b 0a 20 20 4a 6f 69 6e 46 75 6e 63 74 6f 72 20  ;.  JoinFunctor 
4590: 6a 6f 69 6e 5f 66 75 6e 63 74 6f 72 28 73 74 64  join_functor(std
45a0: 3a 3a 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e 74  ::bind(&NodeCont
45b0: 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a  ainer<NodeType>:
45c0: 3a 4a 6f 69 6e 43 61 6c 6c 62 61 63 6b 2c 0a 20  :JoinCallback,. 
45d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
45e0: 20 20 20 20 20 20 20 20 20 20 74 68 69 73 2c 20            this, 
45f0: 61 72 67 73 3a 3a 5f 31 2c 20 26 6d 75 74 65 78  args::_1, &mutex
4600: 2c 20 26 63 6f 6e 64 5f 76 61 72 29 29 3b 0a 0a  , &cond_var));..
4610: 20 20 62 6f 6f 73 74 3a 3a 66 75 6e 63 74 69 6f    boost::functio
4620: 6e 3c 62 6f 6f 6c 28 29 3e 20 77 61 69 74 5f 66  n<bool()> wait_f
4630: 75 6e 63 74 6f 72 20 3d 20 62 6f 6f 73 74 3a 3a  unctor = boost::
4640: 62 69 6e 64 28 0a 20 20 20 20 20 20 26 4e 6f 64  bind(.      &Nod
4650: 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54  eContainer<NodeT
4660: 79 70 65 3e 3a 3a 52 65 73 75 6c 74 52 65 61 64  ype>::ResultRead
4670: 79 2c 20 74 68 69 73 2c 20 26 6a 6f 69 6e 5f 72  y, this, &join_r
4680: 65 73 75 6c 74 5f 29 3b 0a 20 20 62 6f 6f 73 74  esult_);.  boost
4690: 3a 3a 6d 75 74 65 78 3a 3a 73 63 6f 70 65 64 5f  ::mutex::scoped_
46a0: 6c 6f 63 6b 20 6c 6f 63 6b 28 6d 75 74 65 78 29  lock lock(mutex)
46b0: 3b 0a 20 20 6e 6f 64 65 5f 2d 3e 4a 6f 69 6e 28  ;.  node_->Join(
46c0: 6e 6f 64 65 5f 69 64 2c 20 62 6f 6f 74 73 74 72  node_id, bootstr
46d0: 61 70 5f 63 6f 6e 74 61 63 74 73 5f 2c 20 6a 6f  ap_contacts_, jo
46e0: 69 6e 5f 66 75 6e 63 74 6f 72 29 3b 0a 20 20 62  in_functor);.  b
46f0: 6f 6f 6c 20 77 61 69 74 5f 73 75 63 63 65 73 73  ool wait_success
4700: 28 63 6f 6e 64 5f 76 61 72 2e 74 69 6d 65 64 5f  (cond_var.timed_
4710: 77 61 69 74 28 6c 6f 63 6b 2c 20 62 70 74 69 6d  wait(lock, bptim
4720: 65 3a 3a 6d 69 6e 75 74 65 73 28 31 29 2c 0a 20  e::minutes(1),. 
4730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4750: 20 20 20 20 20 20 20 77 61 69 74 5f 66 75 6e 63         wait_func
4760: 74 6f 72 29 29 3b 0a 20 20 72 65 73 75 6c 74 20  tor));.  result 
4770: 3d 20 6b 50 65 6e 64 69 6e 67 52 65 73 75 6c 74  = kPendingResult
4780: 3b 0a 20 20 47 65 74 41 6e 64 52 65 73 65 74 4a  ;.  GetAndResetJ
4790: 6f 69 6e 52 65 73 75 6c 74 28 26 72 65 73 75 6c  oinResult(&resul
47a0: 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 77 61  t);.  return (wa
47b0: 69 74 5f 73 75 63 63 65 73 73 20 3f 20 72 65 73  it_success ? res
47c0: 75 6c 74 20 3a 20 6b 54 69 6d 65 64 4f 75 74 29  ult : kTimedOut)
47d0: 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74  ;.}..template <t
47e0: 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65  ypename NodeType
47f0: 3e 0a 69 6e 74 20 4e 6f 64 65 43 6f 6e 74 61 69  >.int NodeContai
4800: 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 53  ner<NodeType>::S
4810: 74 61 72 74 43 6c 69 65 6e 74 28 0a 20 20 20 20  tartClient(.    
4820: 63 6f 6e 73 74 20 73 74 64 3a 3a 76 65 63 74 6f  const std::vecto
4830: 72 3c 64 68 74 3a 3a 43 6f 6e 74 61 63 74 3e 20  r<dht::Contact> 
4840: 26 62 6f 6f 74 73 74 72 61 70 5f 63 6f 6e 74 61  &bootstrap_conta
4850: 63 74 73 29 20 7b 0a 20 20 69 66 20 28 6e 6f 64  cts) {.  if (nod
4860: 65 5f 2d 3e 63 6c 69 65 6e 74 5f 6f 6e 6c 79 5f  e_->client_only_
4870: 6e 6f 64 65 28 29 29 20 7b 0a 20 20 20 20 73 74  node()) {.    st
4880: 64 3a 3a 70 61 69 72 3c 50 6f 72 74 2c 20 50 6f  d::pair<Port, Po
4890: 72 74 3e 20 70 6f 72 74 5f 72 61 6e 67 65 28 30  rt> port_range(0
48a0: 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  , 0);.    return
48b0: 20 53 74 61 72 74 28 62 6f 6f 74 73 74 72 61 70   Start(bootstrap
48c0: 5f 63 6f 6e 74 61 63 74 73 2c 20 70 6f 72 74 5f  _contacts, port_
48d0: 72 61 6e 67 65 29 3b 0a 20 20 7d 0a 20 20 72 65  range);.  }.  re
48e0: 74 75 72 6e 20 6b 47 65 6e 65 72 61 6c 45 72 72  turn kGeneralErr
48f0: 6f 72 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74 65 20  or;.}..template 
4900: 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79  <typename NodeTy
4910: 70 65 3e 0a 69 6e 74 20 4e 6f 64 65 43 6f 6e 74  pe>.int NodeCont
4920: 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a  ainer<NodeType>:
4930: 3a 53 74 6f 70 28 73 74 64 3a 3a 76 65 63 74 6f  :Stop(std::vecto
4940: 72 3c 43 6f 6e 74 61 63 74 3e 20 2a 62 6f 6f 74  r<Contact> *boot
4950: 73 74 72 61 70 5f 63 6f 6e 74 61 63 74 73 29 20  strap_contacts) 
4960: 7b 0a 20 20 74 72 79 20 7b 0a 20 20 20 20 69 66  {.  try {.    if
4970: 20 28 6e 6f 64 65 5f 2d 3e 6a 6f 69 6e 65 64 28   (node_->joined(
4980: 29 29 20 7b 0a 20 20 20 20 20 20 6e 6f 64 65 5f  )) {.      node_
4990: 2d 3e 4c 65 61 76 65 28 26 62 6f 6f 74 73 74 72  ->Leave(&bootstr
49a0: 61 70 5f 63 6f 6e 74 61 63 74 73 5f 29 3b 0a 20  ap_contacts_);. 
49b0: 20 20 20 20 20 69 66 20 28 62 6f 6f 74 73 74 72       if (bootstr
49c0: 61 70 5f 63 6f 6e 74 61 63 74 73 29 0a 20 20 20  ap_contacts).   
49d0: 20 20 20 20 20 2a 62 6f 6f 74 73 74 72 61 70 5f       *bootstrap_
49e0: 63 6f 6e 74 61 63 74 73 20 3d 20 62 6f 6f 74 73  contacts = boots
49f0: 74 72 61 70 5f 63 6f 6e 74 61 63 74 73 5f 3b 0a  trap_contacts_;.
4a00: 20 20 20 20 7d 0a 20 20 7d 20 63 61 74 63 68 28      }.  } catch(
4a10: 63 6f 6e 73 74 20 73 74 64 3a 3a 65 78 63 65 70  const std::excep
4a20: 74 69 6f 6e 26 29 20 7b 0a 20 20 20 20 72 65 74  tion&) {.    ret
4a30: 75 72 6e 20 6b 47 65 6e 65 72 61 6c 45 72 72 6f  urn kGeneralErro
4a40: 72 3b 0a 20 20 7d 0a 20 20 69 66 20 28 6c 69 73  r;.  }.  if (lis
4a50: 74 65 6e 69 6e 67 5f 74 72 61 6e 73 70 6f 72 74  tening_transport
4a60: 5f 29 0a 20 20 20 20 6c 69 73 74 65 6e 69 6e 67  _).    listening
4a70: 5f 74 72 61 6e 73 70 6f 72 74 5f 2d 3e 53 74 6f  _transport_->Sto
4a80: 70 4c 69 73 74 65 6e 69 6e 67 28 29 3b 0a 20 20  pListening();.  
4a90: 61 73 69 6f 5f 73 65 72 76 69 63 65 5f 2e 53 74  asio_service_.St
4aa0: 6f 70 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 6b  op();.  return k
4ab0: 53 75 63 63 65 73 73 3b 0a 7d 0a 0a 74 65 6d 70  Success;.}..temp
4ac0: 6c 61 74 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e  late <typename N
4ad0: 6f 64 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f  odeType>.void No
4ae0: 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65  deContainer<Node
4af0: 54 79 70 65 3e 3a 3a 4a 6f 69 6e 28 0a 20 20 20  Type>::Join(.   
4b00: 20 63 6f 6e 73 74 20 4e 6f 64 65 49 64 20 26 6e   const NodeId &n
4b10: 6f 64 65 5f 69 64 2c 0a 20 20 20 20 63 6f 6e 73  ode_id,.    cons
4b20: 74 20 73 74 64 3a 3a 76 65 63 74 6f 72 3c 43 6f  t std::vector<Co
4b30: 6e 74 61 63 74 3e 20 26 62 6f 6f 74 73 74 72 61  ntact> &bootstra
4b40: 70 5f 63 6f 6e 74 61 63 74 73 29 20 7b 0a 20 20  p_contacts) {.  
4b50: 6e 6f 64 65 5f 2d 3e 4a 6f 69 6e 28 6e 6f 64 65  node_->Join(node
4b60: 5f 69 64 2c 20 62 6f 6f 74 73 74 72 61 70 5f 63  _id, bootstrap_c
4b70: 6f 6e 74 61 63 74 73 2c 20 6a 6f 69 6e 5f 66 75  ontacts, join_fu
4b80: 6e 63 74 6f 72 5f 29 3b 0a 7d 0a 0a 74 65 6d 70  nctor_);.}..temp
4b90: 6c 61 74 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e  late <typename N
4ba0: 6f 64 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f  odeType>.void No
4bb0: 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65  deContainer<Node
4bc0: 54 79 70 65 3e 3a 3a 53 74 6f 72 65 28 63 6f 6e  Type>::Store(con
4bd0: 73 74 20 4b 65 79 20 26 6b 65 79 2c 0a 20 20 20  st Key &key,.   
4be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c00: 20 63 6f 6e 73 74 20 73 74 64 3a 3a 73 74 72 69   const std::stri
4c10: 6e 67 20 26 76 61 6c 75 65 2c 0a 20 20 20 20 20  ng &value,.     
4c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63                 c
4c40: 6f 6e 73 74 20 73 74 64 3a 3a 73 74 72 69 6e 67  onst std::string
4c50: 20 26 73 69 67 6e 61 74 75 72 65 2c 0a 20 20 20   &signature,.   
4c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c80: 20 63 6f 6e 73 74 20 62 6f 6f 73 74 3a 3a 70 6f   const boost::po
4c90: 73 69 78 5f 74 69 6d 65 3a 3a 74 69 6d 65 5f 64  six_time::time_d
4ca0: 75 72 61 74 69 6f 6e 20 26 74 74 6c 2c 0a 20 20  uration &ttl,.  
4cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4cd0: 20 20 50 72 69 76 61 74 65 4b 65 79 50 74 72 20    PrivateKeyPtr 
4ce0: 70 72 69 76 61 74 65 5f 6b 65 79 29 20 7b 0a 20  private_key) {. 
4cf0: 20 6e 6f 64 65 5f 2d 3e 53 74 6f 72 65 28 6b 65   node_->Store(ke
4d00: 79 2c 20 76 61 6c 75 65 2c 20 73 69 67 6e 61 74  y, value, signat
4d10: 75 72 65 2c 20 74 74 6c 2c 20 70 72 69 76 61 74  ure, ttl, privat
4d20: 65 5f 6b 65 79 2c 20 73 74 6f 72 65 5f 66 75 6e  e_key, store_fun
4d30: 63 74 6f 72 5f 29 3b 0a 7d 0a 0a 74 65 6d 70 6c  ctor_);.}..templ
4d40: 61 74 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f  ate <typename No
4d50: 64 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f 64  deType>.void Nod
4d60: 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54  eContainer<NodeT
4d70: 79 70 65 3e 3a 3a 44 65 6c 65 74 65 28 63 6f 6e  ype>::Delete(con
4d80: 73 74 20 4b 65 79 20 26 6b 65 79 2c 0a 20 20 20  st Key &key,.   
4d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4db0: 20 20 63 6f 6e 73 74 20 73 74 64 3a 3a 73 74 72    const std::str
4dc0: 69 6e 67 20 26 76 61 6c 75 65 2c 0a 20 20 20 20  ing &value,.    
4dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4df0: 20 63 6f 6e 73 74 20 73 74 64 3a 3a 73 74 72 69   const std::stri
4e00: 6e 67 20 26 73 69 67 6e 61 74 75 72 65 2c 0a 20  ng &signature,. 
4e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e30: 20 20 20 20 50 72 69 76 61 74 65 4b 65 79 50 74      PrivateKeyPt
4e40: 72 20 70 72 69 76 61 74 65 5f 6b 65 79 29 20 7b  r private_key) {
4e50: 0a 20 20 6e 6f 64 65 5f 2d 3e 44 65 6c 65 74 65  .  node_->Delete
4e60: 28 6b 65 79 2c 20 76 61 6c 75 65 2c 20 73 69 67  (key, value, sig
4e70: 6e 61 74 75 72 65 2c 20 70 72 69 76 61 74 65 5f  nature, private_
4e80: 6b 65 79 2c 20 64 65 6c 65 74 65 5f 66 75 6e 63  key, delete_func
4e90: 74 6f 72 5f 29 3b 0a 7d 0a 0a 74 65 6d 70 6c 61  tor_);.}..templa
4ea0: 74 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64  te <typename Nod
4eb0: 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f 64 65  eType>.void Node
4ec0: 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79  Container<NodeTy
4ed0: 70 65 3e 3a 3a 55 70 64 61 74 65 28 0a 20 20 20  pe>::Update(.   
4ee0: 20 63 6f 6e 73 74 20 4b 65 79 20 26 6b 65 79 2c   const Key &key,
4ef0: 0a 20 20 20 20 63 6f 6e 73 74 20 73 74 64 3a 3a  .    const std::
4f00: 73 74 72 69 6e 67 20 26 6e 65 77 5f 76 61 6c 75  string &new_valu
4f10: 65 2c 0a 20 20 20 20 63 6f 6e 73 74 20 73 74 64  e,.    const std
4f20: 3a 3a 73 74 72 69 6e 67 20 26 6e 65 77 5f 73 69  ::string &new_si
4f30: 67 6e 61 74 75 72 65 2c 0a 20 20 20 20 63 6f 6e  gnature,.    con
4f40: 73 74 20 73 74 64 3a 3a 73 74 72 69 6e 67 20 26  st std::string &
4f50: 6f 6c 64 5f 76 61 6c 75 65 2c 0a 20 20 20 20 63  old_value,.    c
4f60: 6f 6e 73 74 20 73 74 64 3a 3a 73 74 72 69 6e 67  onst std::string
4f70: 20 26 6f 6c 64 5f 73 69 67 6e 61 74 75 72 65 2c   &old_signature,
4f80: 0a 20 20 20 20 63 6f 6e 73 74 20 62 6f 6f 73 74  .    const boost
4f90: 3a 3a 70 6f 73 69 78 5f 74 69 6d 65 3a 3a 74 69  ::posix_time::ti
4fa0: 6d 65 5f 64 75 72 61 74 69 6f 6e 20 26 74 74 6c  me_duration &ttl
4fb0: 2c 0a 20 20 20 20 50 72 69 76 61 74 65 4b 65 79  ,.    PrivateKey
4fc0: 50 74 72 20 70 72 69 76 61 74 65 5f 6b 65 79 29  Ptr private_key)
4fd0: 20 7b 0a 20 20 6e 6f 64 65 5f 2d 3e 55 70 64 61   {.  node_->Upda
4fe0: 74 65 28 6b 65 79 2c 20 6e 65 77 5f 76 61 6c 75  te(key, new_valu
4ff0: 65 2c 20 6e 65 77 5f 73 69 67 6e 61 74 75 72 65  e, new_signature
5000: 2c 20 6f 6c 64 5f 76 61 6c 75 65 2c 20 6f 6c 64  , old_value, old
5010: 5f 73 69 67 6e 61 74 75 72 65 2c 20 74 74 6c 2c  _signature, ttl,
5020: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5030: 20 70 72 69 76 61 74 65 5f 6b 65 79 2c 20 75 70   private_key, up
5040: 64 61 74 65 5f 66 75 6e 63 74 6f 72 5f 29 3b 0a  date_functor_);.
5050: 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70  }..template <typ
5060: 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a  ename NodeType>.
5070: 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e  void NodeContain
5080: 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 46 69  er<NodeType>::Fi
5090: 6e 64 56 61 6c 75 65 28 63 6f 6e 73 74 20 4b 65  ndValue(const Ke
50a0: 79 20 26 6b 65 79 2c 0a 20 20 20 20 20 20 20 20  y &key,.        
50b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50d0: 50 72 69 76 61 74 65 4b 65 79 50 74 72 20 70 72  PrivateKeyPtr pr
50e0: 69 76 61 74 65 5f 6b 65 79 2c 0a 20 20 20 20 20  ivate_key,.     
50f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5110: 20 20 20 63 6f 6e 73 74 20 75 69 6e 74 31 36 5f     const uint16_
5120: 74 20 26 65 78 74 72 61 5f 63 6f 6e 74 61 63 74  t &extra_contact
5130: 73 29 20 7b 0a 20 20 6e 6f 64 65 5f 2d 3e 46 69  s) {.  node_->Fi
5140: 6e 64 56 61 6c 75 65 28 6b 65 79 2c 20 70 72 69  ndValue(key, pri
5150: 76 61 74 65 5f 6b 65 79 2c 20 66 69 6e 64 5f 76  vate_key, find_v
5160: 61 6c 75 65 5f 66 75 6e 63 74 6f 72 5f 2c 20 65  alue_functor_, e
5170: 78 74 72 61 5f 63 6f 6e 74 61 63 74 73 29 3b 0a  xtra_contacts);.
5180: 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70  }..template <typ
5190: 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a  ename NodeType>.
51a0: 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e  void NodeContain
51b0: 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 46 69  er<NodeType>::Fi
51c0: 6e 64 4e 6f 64 65 73 28 63 6f 6e 73 74 20 4b 65  ndNodes(const Ke
51d0: 79 20 26 6b 65 79 2c 0a 20 20 20 20 20 20 20 20  y &key,.        
51e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5200: 63 6f 6e 73 74 20 75 69 6e 74 31 36 5f 74 20 26  const uint16_t &
5210: 65 78 74 72 61 5f 63 6f 6e 74 61 63 74 73 29 20  extra_contacts) 
5220: 7b 0a 20 20 6e 6f 64 65 5f 2d 3e 46 69 6e 64 4e  {.  node_->FindN
5230: 6f 64 65 73 28 6b 65 79 2c 20 66 69 6e 64 5f 6e  odes(key, find_n
5240: 6f 64 65 73 5f 66 75 6e 63 74 6f 72 5f 2c 20 65  odes_functor_, e
5250: 78 74 72 61 5f 63 6f 6e 74 61 63 74 73 29 3b 0a  xtra_contacts);.
5260: 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70  }..template <typ
5270: 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a  ename NodeType>.
5280: 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e  void NodeContain
5290: 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 47 65  er<NodeType>::Ge
52a0: 74 43 6f 6e 74 61 63 74 28 63 6f 6e 73 74 20 4e  tContact(const N
52b0: 6f 64 65 49 64 20 26 6e 6f 64 65 5f 69 64 29 20  odeId &node_id) 
52c0: 7b 0a 20 20 6e 6f 64 65 5f 2d 3e 47 65 74 43 6f  {.  node_->GetCo
52d0: 6e 74 61 63 74 28 6e 6f 64 65 5f 69 64 2c 20 67  ntact(node_id, g
52e0: 65 74 5f 63 6f 6e 74 61 63 74 5f 66 75 6e 63 74  et_contact_funct
52f0: 6f 72 5f 29 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74  or_);.}..templat
5300: 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65  e <typename Node
5310: 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f 64 65 43  Type>.void NodeC
5320: 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70  ontainer<NodeTyp
5330: 65 3e 3a 3a 50 69 6e 67 28 63 6f 6e 73 74 20 43  e>::Ping(const C
5340: 6f 6e 74 61 63 74 20 26 63 6f 6e 74 61 63 74 29  ontact &contact)
5350: 20 7b 0a 20 20 6e 6f 64 65 5f 2d 3e 50 69 6e 67   {.  node_->Ping
5360: 28 63 6f 6e 74 61 63 74 2c 20 70 69 6e 67 5f 66  (contact, ping_f
5370: 75 6e 63 74 6f 72 5f 29 3b 0a 7d 0a 0a 74 65 6d  unctor_);.}..tem
5380: 70 6c 61 74 65 20 3c 74 79 70 65 6e 61 6d 65 20  plate <typename 
5390: 4e 6f 64 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e  NodeType>.void N
53a0: 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64  odeContainer<Nod
53b0: 65 54 79 70 65 3e 3a 3a 4a 6f 69 6e 43 61 6c 6c  eType>::JoinCall
53c0: 62 61 63 6b 28 0a 20 20 20 20 69 6e 74 20 72 65  back(.    int re
53d0: 73 75 6c 74 5f 69 6e 2c 0a 20 20 20 20 62 6f 6f  sult_in,.    boo
53e0: 73 74 3a 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78  st::mutex *mutex
53f0: 2c 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e  ,.    boost::con
5400: 64 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20  dition_variable 
5410: 2a 63 6f 6e 64 5f 76 61 72 29 20 7b 0a 20 20 62  *cond_var) {.  b
5420: 6f 6f 73 74 3a 3a 6d 75 74 65 78 3a 3a 73 63 6f  oost::mutex::sco
5430: 70 65 64 5f 6c 6f 63 6b 20 6c 6f 63 6b 28 2a 6d  ped_lock lock(*m
5440: 75 74 65 78 29 3b 0a 20 20 6a 6f 69 6e 5f 72 65  utex);.  join_re
5450: 73 75 6c 74 5f 20 3d 20 72 65 73 75 6c 74 5f 69  sult_ = result_i
5460: 6e 3b 0a 20 20 63 6f 6e 64 5f 76 61 72 2d 3e 6e  n;.  cond_var->n
5470: 6f 74 69 66 79 5f 6f 6e 65 28 29 3b 0a 7d 0a 0a  otify_one();.}..
5480: 74 65 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e 61  template <typena
5490: 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f 69  me NodeType>.voi
54a0: 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c  d NodeContainer<
54b0: 4e 6f 64 65 54 79 70 65 3e 3a 3a 53 74 6f 72 65  NodeType>::Store
54c0: 43 61 6c 6c 62 61 63 6b 28 0a 20 20 20 20 69 6e  Callback(.    in
54d0: 74 20 72 65 73 75 6c 74 5f 69 6e 2c 0a 20 20 20  t result_in,.   
54e0: 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20 2a 6d   boost::mutex *m
54f0: 75 74 65 78 2c 0a 20 20 20 20 62 6f 6f 73 74 3a  utex,.    boost:
5500: 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61  :condition_varia
5510: 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72 29 20 7b  ble *cond_var) {
5520: 0a 20 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 3a  .  boost::mutex:
5530: 3a 73 63 6f 70 65 64 5f 6c 6f 63 6b 20 6c 6f 63  :scoped_lock loc
5540: 6b 28 2a 6d 75 74 65 78 29 3b 0a 20 20 73 74 6f  k(*mutex);.  sto
5550: 72 65 5f 72 65 73 75 6c 74 5f 20 3d 20 72 65 73  re_result_ = res
5560: 75 6c 74 5f 69 6e 3b 0a 20 20 63 6f 6e 64 5f 76  ult_in;.  cond_v
5570: 61 72 2d 3e 6e 6f 74 69 66 79 5f 6f 6e 65 28 29  ar->notify_one()
5580: 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74  ;.}..template <t
5590: 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65  ypename NodeType
55a0: 3e 0a 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61  >.void NodeConta
55b0: 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a  iner<NodeType>::
55c0: 44 65 6c 65 74 65 43 61 6c 6c 62 61 63 6b 28 0a  DeleteCallback(.
55d0: 20 20 20 20 69 6e 74 20 72 65 73 75 6c 74 5f 69      int result_i
55e0: 6e 2c 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 6d 75  n,.    boost::mu
55f0: 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20 20 20  tex *mutex,.    
5600: 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69 6f 6e  boost::condition
5610: 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e 64 5f  _variable *cond_
5620: 76 61 72 29 20 7b 0a 20 20 62 6f 6f 73 74 3a 3a  var) {.  boost::
5630: 6d 75 74 65 78 3a 3a 73 63 6f 70 65 64 5f 6c 6f  mutex::scoped_lo
5640: 63 6b 20 6c 6f 63 6b 28 2a 6d 75 74 65 78 29 3b  ck lock(*mutex);
5650: 0a 20 20 64 65 6c 65 74 65 5f 72 65 73 75 6c 74  .  delete_result
5660: 5f 20 3d 20 72 65 73 75 6c 74 5f 69 6e 3b 0a 20  _ = result_in;. 
5670: 20 63 6f 6e 64 5f 76 61 72 2d 3e 6e 6f 74 69 66   cond_var->notif
5680: 79 5f 6f 6e 65 28 29 3b 0a 7d 0a 0a 74 65 6d 70  y_one();.}..temp
5690: 6c 61 74 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e  late <typename N
56a0: 6f 64 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f  odeType>.void No
56b0: 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65  deContainer<Node
56c0: 54 79 70 65 3e 3a 3a 55 70 64 61 74 65 43 61 6c  Type>::UpdateCal
56d0: 6c 62 61 63 6b 28 0a 20 20 20 20 69 6e 74 20 72  lback(.    int r
56e0: 65 73 75 6c 74 5f 69 6e 2c 0a 20 20 20 20 62 6f  esult_in,.    bo
56f0: 6f 73 74 3a 3a 6d 75 74 65 78 20 2a 6d 75 74 65  ost::mutex *mute
5700: 78 2c 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f  x,.    boost::co
5710: 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65  ndition_variable
5720: 20 2a 63 6f 6e 64 5f 76 61 72 29 20 7b 0a 20 20   *cond_var) {.  
5730: 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 3a 3a 73 63  boost::mutex::sc
5740: 6f 70 65 64 5f 6c 6f 63 6b 20 6c 6f 63 6b 28 2a  oped_lock lock(*
5750: 6d 75 74 65 78 29 3b 0a 20 20 75 70 64 61 74 65  mutex);.  update
5760: 5f 72 65 73 75 6c 74 5f 20 3d 20 72 65 73 75 6c  _result_ = resul
5770: 74 5f 69 6e 3b 0a 20 20 63 6f 6e 64 5f 76 61 72  t_in;.  cond_var
5780: 2d 3e 6e 6f 74 69 66 79 5f 6f 6e 65 28 29 3b 0a  ->notify_one();.
5790: 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70  }..template <typ
57a0: 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a  ename NodeType>.
57b0: 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e  void NodeContain
57c0: 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 46 69  er<NodeType>::Fi
57d0: 6e 64 56 61 6c 75 65 43 61 6c 6c 62 61 63 6b 28  ndValueCallback(
57e0: 0a 20 20 20 20 46 69 6e 64 56 61 6c 75 65 52 65  .    FindValueRe
57f0: 74 75 72 6e 73 20 66 69 6e 64 5f 76 61 6c 75 65  turns find_value
5800: 5f 72 65 74 75 72 6e 73 5f 69 6e 2c 0a 20 20 20  _returns_in,.   
5810: 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20 2a 6d   boost::mutex *m
5820: 75 74 65 78 2c 0a 20 20 20 20 62 6f 6f 73 74 3a  utex,.    boost:
5830: 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61  :condition_varia
5840: 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72 29 20 7b  ble *cond_var) {
5850: 0a 20 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 3a  .  boost::mutex:
5860: 3a 73 63 6f 70 65 64 5f 6c 6f 63 6b 20 6c 6f 63  :scoped_lock loc
5870: 6b 28 2a 6d 75 74 65 78 29 3b 0a 20 20 66 69 6e  k(*mutex);.  fin
5880: 64 5f 76 61 6c 75 65 5f 72 65 74 75 72 6e 73 5f  d_value_returns_
5890: 20 3d 20 66 69 6e 64 5f 76 61 6c 75 65 5f 72 65   = find_value_re
58a0: 74 75 72 6e 73 5f 69 6e 3b 0a 20 20 63 6f 6e 64  turns_in;.  cond
58b0: 5f 76 61 72 2d 3e 6e 6f 74 69 66 79 5f 6f 6e 65  _var->notify_one
58c0: 28 29 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74 65 20  ();.}..template 
58d0: 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79  <typename NodeTy
58e0: 70 65 3e 0a 76 6f 69 64 20 4e 6f 64 65 43 6f 6e  pe>.void NodeCon
58f0: 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e  tainer<NodeType>
5900: 3a 3a 46 69 6e 64 4e 6f 64 65 73 43 61 6c 6c 62  ::FindNodesCallb
5910: 61 63 6b 28 0a 20 20 20 20 69 6e 74 20 72 65 73  ack(.    int res
5920: 75 6c 74 5f 69 6e 2c 0a 20 20 20 20 73 74 64 3a  ult_in,.    std:
5930: 3a 76 65 63 74 6f 72 3c 43 6f 6e 74 61 63 74 3e  :vector<Contact>
5940: 20 63 6c 6f 73 65 73 74 5f 6e 6f 64 65 73 5f 69   closest_nodes_i
5950: 6e 2c 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 6d 75  n,.    boost::mu
5960: 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20 20 20  tex *mutex,.    
5970: 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69 6f 6e  boost::condition
5980: 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e 64 5f  _variable *cond_
5990: 76 61 72 29 20 7b 0a 20 20 62 6f 6f 73 74 3a 3a  var) {.  boost::
59a0: 6d 75 74 65 78 3a 3a 73 63 6f 70 65 64 5f 6c 6f  mutex::scoped_lo
59b0: 63 6b 20 6c 6f 63 6b 28 2a 6d 75 74 65 78 29 3b  ck lock(*mutex);
59c0: 0a 20 20 66 69 6e 64 5f 6e 6f 64 65 73 5f 72 65  .  find_nodes_re
59d0: 73 75 6c 74 5f 20 3d 20 72 65 73 75 6c 74 5f 69  sult_ = result_i
59e0: 6e 3b 0a 20 20 66 69 6e 64 5f 6e 6f 64 65 73 5f  n;.  find_nodes_
59f0: 63 6c 6f 73 65 73 74 5f 6e 6f 64 65 73 5f 20 3d  closest_nodes_ =
5a00: 20 63 6c 6f 73 65 73 74 5f 6e 6f 64 65 73 5f 69   closest_nodes_i
5a10: 6e 3b 0a 20 20 63 6f 6e 64 5f 76 61 72 2d 3e 6e  n;.  cond_var->n
5a20: 6f 74 69 66 79 5f 6f 6e 65 28 29 3b 0a 7d 0a 0a  otify_one();.}..
5a30: 74 65 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e 61  template <typena
5a40: 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f 69  me NodeType>.voi
5a50: 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c  d NodeContainer<
5a60: 4e 6f 64 65 54 79 70 65 3e 3a 3a 47 65 74 43 6f  NodeType>::GetCo
5a70: 6e 74 61 63 74 43 61 6c 6c 62 61 63 6b 28 0a 20  ntactCallback(. 
5a80: 20 20 20 69 6e 74 20 72 65 73 75 6c 74 5f 69 6e     int result_in
5a90: 2c 0a 20 20 20 20 43 6f 6e 74 61 63 74 20 63 6f  ,.    Contact co
5aa0: 6e 74 61 63 74 5f 69 6e 2c 0a 20 20 20 20 62 6f  ntact_in,.    bo
5ab0: 6f 73 74 3a 3a 6d 75 74 65 78 20 2a 6d 75 74 65  ost::mutex *mute
5ac0: 78 2c 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f  x,.    boost::co
5ad0: 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65  ndition_variable
5ae0: 20 2a 63 6f 6e 64 5f 76 61 72 29 20 7b 0a 20 20   *cond_var) {.  
5af0: 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 3a 3a 73 63  boost::mutex::sc
5b00: 6f 70 65 64 5f 6c 6f 63 6b 20 6c 6f 63 6b 28 2a  oped_lock lock(*
5b10: 6d 75 74 65 78 29 3b 0a 20 20 67 65 74 5f 63 6f  mutex);.  get_co
5b20: 6e 74 61 63 74 5f 72 65 73 75 6c 74 5f 20 3d 20  ntact_result_ = 
5b30: 72 65 73 75 6c 74 5f 69 6e 3b 0a 20 20 67 6f 74  result_in;.  got
5b40: 74 65 6e 5f 63 6f 6e 74 61 63 74 5f 20 3d 20 63  ten_contact_ = c
5b50: 6f 6e 74 61 63 74 5f 69 6e 3b 0a 20 20 63 6f 6e  ontact_in;.  con
5b60: 64 5f 76 61 72 2d 3e 6e 6f 74 69 66 79 5f 6f 6e  d_var->notify_on
5b70: 65 28 29 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74 65  e();.}..template
5b80: 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54   <typename NodeT
5b90: 79 70 65 3e 0a 76 6f 69 64 20 4e 6f 64 65 43 6f  ype>.void NodeCo
5ba0: 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65  ntainer<NodeType
5bb0: 3e 3a 3a 50 69 6e 67 43 61 6c 6c 62 61 63 6b 28  >::PingCallback(
5bc0: 0a 20 20 20 20 69 6e 74 20 72 65 73 75 6c 74 5f  .    int result_
5bd0: 69 6e 2c 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 6d  in,.    boost::m
5be0: 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20 20  utex *mutex,.   
5bf0: 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69 6f   boost::conditio
5c00: 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e 64  n_variable *cond
5c10: 5f 76 61 72 29 20 7b 0a 20 20 62 6f 6f 73 74 3a  _var) {.  boost:
5c20: 3a 6d 75 74 65 78 3a 3a 73 63 6f 70 65 64 5f 6c  :mutex::scoped_l
5c30: 6f 63 6b 20 6c 6f 63 6b 28 2a 6d 75 74 65 78 29  ock lock(*mutex)
5c40: 3b 0a 20 20 70 69 6e 67 5f 72 65 73 75 6c 74 5f  ;.  ping_result_
5c50: 20 3d 20 72 65 73 75 6c 74 5f 69 6e 3b 0a 20 20   = result_in;.  
5c60: 63 6f 6e 64 5f 76 61 72 2d 3e 6e 6f 74 69 66 79  cond_var->notify
5c70: 5f 6f 6e 65 28 29 3b 0a 7d 0a 0a 74 65 6d 70 6c  _one();.}..templ
5c80: 61 74 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f  ate <typename No
5c90: 64 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f 64  deType>.void Nod
5ca0: 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54  eContainer<NodeT
5cb0: 79 70 65 3e 3a 3a 4d 61 6b 65 4a 6f 69 6e 46 75  ype>::MakeJoinFu
5cc0: 6e 63 74 6f 72 28 0a 20 20 20 20 62 6f 6f 73 74  nctor(.    boost
5cd0: 3a 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a  ::mutex *mutex,.
5ce0: 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69      boost::condi
5cf0: 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63  tion_variable *c
5d00: 6f 6e 64 5f 76 61 72 29 20 7b 0a 20 20 6a 6f 69  ond_var) {.  joi
5d10: 6e 5f 66 75 6e 63 74 6f 72 5f 20 3d 20 73 74 64  n_functor_ = std
5d20: 3a 3a 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e 74  ::bind(&NodeCont
5d30: 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a  ainer<NodeType>:
5d40: 3a 4a 6f 69 6e 43 61 6c 6c 62 61 63 6b 2c 20 74  :JoinCallback, t
5d50: 68 69 73 2c 0a 20 20 20 20 20 20 20 20 20 20 20  his,.           
5d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d70: 20 61 72 67 73 3a 3a 5f 31 2c 20 6d 75 74 65 78   args::_1, mutex
5d80: 2c 20 63 6f 6e 64 5f 76 61 72 29 3b 0a 7d 0a 0a  , cond_var);.}..
5d90: 74 65 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e 61  template <typena
5da0: 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f 69  me NodeType>.voi
5db0: 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c  d NodeContainer<
5dc0: 4e 6f 64 65 54 79 70 65 3e 3a 3a 4d 61 6b 65 53  NodeType>::MakeS
5dd0: 74 6f 72 65 46 75 6e 63 74 6f 72 28 0a 20 20 20  toreFunctor(.   
5de0: 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20 2a 6d   boost::mutex *m
5df0: 75 74 65 78 2c 0a 20 20 20 20 62 6f 6f 73 74 3a  utex,.    boost:
5e00: 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61 72 69 61  :condition_varia
5e10: 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72 29 20 7b  ble *cond_var) {
5e20: 0a 20 20 73 74 6f 72 65 5f 66 75 6e 63 74 6f 72  .  store_functor
5e30: 5f 20 3d 20 73 74 64 3a 3a 62 69 6e 64 28 26 4e  _ = std::bind(&N
5e40: 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64  odeContainer<Nod
5e50: 65 54 79 70 65 3e 3a 3a 53 74 6f 72 65 43 61 6c  eType>::StoreCal
5e60: 6c 62 61 63 6b 2c 20 74 68 69 73 2c 0a 20 20 20  lback, this,.   
5e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e80: 20 20 20 20 20 20 20 20 20 20 61 72 67 73 3a 3a            args::
5e90: 5f 31 2c 20 6d 75 74 65 78 2c 20 63 6f 6e 64 5f  _1, mutex, cond_
5ea0: 76 61 72 29 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74  var);.}..templat
5eb0: 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65  e <typename Node
5ec0: 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f 64 65 43  Type>.void NodeC
5ed0: 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70  ontainer<NodeTyp
5ee0: 65 3e 3a 3a 4d 61 6b 65 44 65 6c 65 74 65 46 75  e>::MakeDeleteFu
5ef0: 6e 63 74 6f 72 28 0a 20 20 20 20 62 6f 6f 73 74  nctor(.    boost
5f00: 3a 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a  ::mutex *mutex,.
5f10: 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69      boost::condi
5f20: 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63  tion_variable *c
5f30: 6f 6e 64 5f 76 61 72 29 20 7b 0a 20 20 64 65 6c  ond_var) {.  del
5f40: 65 74 65 5f 66 75 6e 63 74 6f 72 5f 20 3d 20 73  ete_functor_ = s
5f50: 74 64 3a 3a 62 69 6e 64 28 26 4e 6f 64 65 43 6f  td::bind(&NodeCo
5f60: 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65  ntainer<NodeType
5f70: 3e 3a 3a 44 65 6c 65 74 65 43 61 6c 6c 62 61 63  >::DeleteCallbac
5f80: 6b 2c 20 74 68 69 73 2c 0a 20 20 20 20 20 20 20  k, this,.       
5f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5fa0: 20 20 20 20 20 20 20 61 72 67 73 3a 3a 5f 31 2c         args::_1,
5fb0: 20 6d 75 74 65 78 2c 20 63 6f 6e 64 5f 76 61 72   mutex, cond_var
5fc0: 29 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c  );.}..template <
5fd0: 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70  typename NodeTyp
5fe0: 65 3e 0a 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74  e>.void NodeCont
5ff0: 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a  ainer<NodeType>:
6000: 3a 4d 61 6b 65 55 70 64 61 74 65 46 75 6e 63 74  :MakeUpdateFunct
6010: 6f 72 28 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 6d  or(.    boost::m
6020: 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20 20  utex *mutex,.   
6030: 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69 6f   boost::conditio
6040: 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e 64  n_variable *cond
6050: 5f 76 61 72 29 20 7b 0a 20 20 75 70 64 61 74 65  _var) {.  update
6060: 5f 66 75 6e 63 74 6f 72 5f 20 3d 20 73 74 64 3a  _functor_ = std:
6070: 3a 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e 74 61  :bind(&NodeConta
6080: 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a  iner<NodeType>::
6090: 55 70 64 61 74 65 43 61 6c 6c 62 61 63 6b 2c 20  UpdateCallback, 
60a0: 74 68 69 73 2c 0a 20 20 20 20 20 20 20 20 20 20  this,.          
60b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60c0: 20 20 20 20 61 72 67 73 3a 3a 5f 31 2c 20 6d 75      args::_1, mu
60d0: 74 65 78 2c 20 63 6f 6e 64 5f 76 61 72 29 3b 0a  tex, cond_var);.
60e0: 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70  }..template <typ
60f0: 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a  ename NodeType>.
6100: 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e  void NodeContain
6110: 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 4d 61  er<NodeType>::Ma
6120: 6b 65 46 69 6e 64 56 61 6c 75 65 46 75 6e 63 74  keFindValueFunct
6130: 6f 72 28 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 6d  or(.    boost::m
6140: 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20 20  utex *mutex,.   
6150: 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69 6f   boost::conditio
6160: 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e 64  n_variable *cond
6170: 5f 76 61 72 29 20 7b 0a 20 20 66 69 6e 64 5f 76  _var) {.  find_v
6180: 61 6c 75 65 5f 66 75 6e 63 74 6f 72 5f 20 3d 20  alue_functor_ = 
6190: 73 74 64 3a 3a 62 69 6e 64 28 26 4e 6f 64 65 43  std::bind(&NodeC
61a0: 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70  ontainer<NodeTyp
61b0: 65 3e 3a 3a 46 69 6e 64 56 61 6c 75 65 43 61 6c  e>::FindValueCal
61c0: 6c 62 61 63 6b 2c 0a 20 20 20 20 20 20 20 20 20  lback,.         
61d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61e0: 20 20 20 20 20 20 20 20 20 74 68 69 73 2c 20 61           this, a
61f0: 72 67 73 3a 3a 5f 31 2c 20 6d 75 74 65 78 2c 20  rgs::_1, mutex, 
6200: 63 6f 6e 64 5f 76 61 72 29 3b 0a 7d 0a 0a 74 65  cond_var);.}..te
6210: 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e 61 6d 65  mplate <typename
6220: 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f 69 64 20   NodeType>.void 
6230: 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f  NodeContainer<No
6240: 64 65 54 79 70 65 3e 3a 3a 4d 61 6b 65 46 69 6e  deType>::MakeFin
6250: 64 4e 6f 64 65 73 46 75 6e 63 74 6f 72 28 0a 20  dNodesFunctor(. 
6260: 20 20 20 62 6f 6f 73 74 3a 3a 6d 75 74 65 78 20     boost::mutex 
6270: 2a 6d 75 74 65 78 2c 0a 20 20 20 20 62 6f 6f 73  *mutex,.    boos
6280: 74 3a 3a 63 6f 6e 64 69 74 69 6f 6e 5f 76 61 72  t::condition_var
6290: 69 61 62 6c 65 20 2a 63 6f 6e 64 5f 76 61 72 29  iable *cond_var)
62a0: 20 7b 0a 20 20 66 69 6e 64 5f 6e 6f 64 65 73 5f   {.  find_nodes_
62b0: 66 75 6e 63 74 6f 72 5f 20 3d 20 73 74 64 3a 3a  functor_ = std::
62c0: 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e 74 61 69  bind(&NodeContai
62d0: 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 46  ner<NodeType>::F
62e0: 69 6e 64 4e 6f 64 65 73 43 61 6c 6c 62 61 63 6b  indNodesCallback
62f0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
6300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6310: 20 20 20 20 74 68 69 73 2c 20 61 72 67 73 3a 3a      this, args::
6320: 5f 31 2c 20 61 72 67 73 3a 3a 5f 32 2c 20 6d 75  _1, args::_2, mu
6330: 74 65 78 2c 20 63 6f 6e 64 5f 76 61 72 29 3b 0a  tex, cond_var);.
6340: 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70  }..template <typ
6350: 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a  ename NodeType>.
6360: 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e  void NodeContain
6370: 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 4d 61  er<NodeType>::Ma
6380: 6b 65 47 65 74 43 6f 6e 74 61 63 74 46 75 6e 63  keGetContactFunc
6390: 74 6f 72 28 0a 20 20 20 20 62 6f 6f 73 74 3a 3a  tor(.    boost::
63a0: 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20  mutex *mutex,.  
63b0: 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69    boost::conditi
63c0: 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e  on_variable *con
63d0: 64 5f 76 61 72 29 20 7b 0a 20 20 67 65 74 5f 63  d_var) {.  get_c
63e0: 6f 6e 74 61 63 74 5f 66 75 6e 63 74 6f 72 5f 20  ontact_functor_ 
63f0: 3d 20 73 74 64 3a 3a 62 69 6e 64 28 26 4e 6f 64  = std::bind(&Nod
6400: 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54  eContainer<NodeT
6410: 79 70 65 3e 3a 3a 47 65 74 43 6f 6e 74 61 63 74  ype>::GetContact
6420: 43 61 6c 6c 62 61 63 6b 2c 0a 20 20 20 20 20 20  Callback,.      
6430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6440: 20 20 20 20 20 20 20 20 20 20 20 20 20 74 68 69               thi
6450: 73 2c 20 61 72 67 73 3a 3a 5f 31 2c 20 61 72 67  s, args::_1, arg
6460: 73 3a 3a 5f 32 2c 20 6d 75 74 65 78 2c 20 63 6f  s::_2, mutex, co
6470: 6e 64 5f 76 61 72 29 3b 0a 7d 0a 0a 74 65 6d 70  nd_var);.}..temp
6480: 6c 61 74 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e  late <typename N
6490: 6f 64 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f  odeType>.void No
64a0: 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65  deContainer<Node
64b0: 54 79 70 65 3e 3a 3a 4d 61 6b 65 50 69 6e 67 46  Type>::MakePingF
64c0: 75 6e 63 74 6f 72 28 0a 20 20 20 20 62 6f 6f 73  unctor(.    boos
64d0: 74 3a 3a 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c  t::mutex *mutex,
64e0: 0a 20 20 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64  .    boost::cond
64f0: 69 74 69 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a  ition_variable *
6500: 63 6f 6e 64 5f 76 61 72 29 20 7b 0a 20 20 70 69  cond_var) {.  pi
6510: 6e 67 5f 66 75 6e 63 74 6f 72 5f 20 3d 20 73 74  ng_functor_ = st
6520: 64 3a 3a 62 69 6e 64 28 26 4e 6f 64 65 43 6f 6e  d::bind(&NodeCon
6530: 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e  tainer<NodeType>
6540: 3a 3a 50 69 6e 67 43 61 6c 6c 62 61 63 6b 2c 20  ::PingCallback, 
6550: 74 68 69 73 2c 0a 20 20 20 20 20 20 20 20 20 20  this,.          
6560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6570: 20 20 61 72 67 73 3a 3a 5f 31 2c 20 6d 75 74 65    args::_1, mute
6580: 78 2c 20 63 6f 6e 64 5f 76 61 72 29 3b 0a 7d 0a  x, cond_var);.}.
6590: 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e  .template <typen
65a0: 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f  ame NodeType>.vo
65b0: 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72  id NodeContainer
65c0: 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 4d 61 6b 65  <NodeType>::Make
65d0: 41 6c 6c 43 61 6c 6c 62 61 63 6b 46 75 6e 63 74  AllCallbackFunct
65e0: 6f 72 73 28 0a 20 20 20 20 62 6f 6f 73 74 3a 3a  ors(.    boost::
65f0: 6d 75 74 65 78 20 2a 6d 75 74 65 78 2c 0a 20 20  mutex *mutex,.  
6600: 20 20 62 6f 6f 73 74 3a 3a 63 6f 6e 64 69 74 69    boost::conditi
6610: 6f 6e 5f 76 61 72 69 61 62 6c 65 20 2a 63 6f 6e  on_variable *con
6620: 64 5f 76 61 72 29 20 7b 0a 20 20 4d 61 6b 65 4a  d_var) {.  MakeJ
6630: 6f 69 6e 46 75 6e 63 74 6f 72 28 6d 75 74 65 78  oinFunctor(mutex
6640: 2c 20 63 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 4d  , cond_var);.  M
6650: 61 6b 65 53 74 6f 72 65 46 75 6e 63 74 6f 72 28  akeStoreFunctor(
6660: 6d 75 74 65 78 2c 20 63 6f 6e 64 5f 76 61 72 29  mutex, cond_var)
6670: 3b 0a 20 20 4d 61 6b 65 44 65 6c 65 74 65 46 75  ;.  MakeDeleteFu
6680: 6e 63 74 6f 72 28 6d 75 74 65 78 2c 20 63 6f 6e  nctor(mutex, con
6690: 64 5f 76 61 72 29 3b 0a 20 20 4d 61 6b 65 55 70  d_var);.  MakeUp
66a0: 64 61 74 65 46 75 6e 63 74 6f 72 28 6d 75 74 65  dateFunctor(mute
66b0: 78 2c 20 63 6f 6e 64 5f 76 61 72 29 3b 0a 20 20  x, cond_var);.  
66c0: 4d 61 6b 65 46 69 6e 64 56 61 6c 75 65 46 75 6e  MakeFindValueFun
66d0: 63 74 6f 72 28 6d 75 74 65 78 2c 20 63 6f 6e 64  ctor(mutex, cond
66e0: 5f 76 61 72 29 3b 0a 20 20 4d 61 6b 65 46 69 6e  _var);.  MakeFin
66f0: 64 4e 6f 64 65 73 46 75 6e 63 74 6f 72 28 6d 75  dNodesFunctor(mu
6700: 74 65 78 2c 20 63 6f 6e 64 5f 76 61 72 29 3b 0a  tex, cond_var);.
6710: 20 20 4d 61 6b 65 47 65 74 43 6f 6e 74 61 63 74    MakeGetContact
6720: 46 75 6e 63 74 6f 72 28 6d 75 74 65 78 2c 20 63  Functor(mutex, c
6730: 6f 6e 64 5f 76 61 72 29 3b 0a 20 20 4d 61 6b 65  ond_var);.  Make
6740: 50 69 6e 67 46 75 6e 63 74 6f 72 28 6d 75 74 65  PingFunctor(mute
6750: 78 2c 20 63 6f 6e 64 5f 76 61 72 29 3b 0a 7d 0a  x, cond_var);.}.
6760: 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70 65  ..template <type
6770: 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76  name NodeType>.v
6780: 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65  oid NodeContaine
6790: 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 47 65 74  r<NodeType>::Get
67a0: 41 6e 64 52 65 73 65 74 4a 6f 69 6e 52 65 73 75  AndResetJoinResu
67b0: 6c 74 28 69 6e 74 20 2a 72 65 73 75 6c 74 29 20  lt(int *result) 
67c0: 7b 0a 20 20 69 66 20 28 72 65 73 75 6c 74 29 0a  {.  if (result).
67d0: 20 20 20 20 2a 72 65 73 75 6c 74 20 3d 20 6a 6f      *result = jo
67e0: 69 6e 5f 72 65 73 75 6c 74 5f 3b 0a 20 20 6a 6f  in_result_;.  jo
67f0: 69 6e 5f 72 65 73 75 6c 74 5f 20 3d 20 6b 50 65  in_result_ = kPe
6800: 6e 64 69 6e 67 52 65 73 75 6c 74 3b 0a 7d 0a 0a  ndingResult;.}..
6810: 74 65 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e 61  template <typena
6820: 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f 69  me NodeType>.voi
6830: 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c  d NodeContainer<
6840: 4e 6f 64 65 54 79 70 65 3e 3a 3a 47 65 74 41 6e  NodeType>::GetAn
6850: 64 52 65 73 65 74 53 74 6f 72 65 52 65 73 75 6c  dResetStoreResul
6860: 74 28 69 6e 74 20 2a 72 65 73 75 6c 74 29 20 7b  t(int *result) {
6870: 0a 20 20 69 66 20 28 72 65 73 75 6c 74 29 0a 20  .  if (result). 
6880: 20 20 20 2a 72 65 73 75 6c 74 20 3d 20 73 74 6f     *result = sto
6890: 72 65 5f 72 65 73 75 6c 74 5f 3b 0a 20 20 73 74  re_result_;.  st
68a0: 6f 72 65 5f 72 65 73 75 6c 74 5f 20 3d 20 6b 50  ore_result_ = kP
68b0: 65 6e 64 69 6e 67 52 65 73 75 6c 74 3b 0a 7d 0a  endingResult;.}.
68c0: 0a 74 65 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e  .template <typen
68d0: 61 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f  ame NodeType>.vo
68e0: 69 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72  id NodeContainer
68f0: 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a 47 65 74 41  <NodeType>::GetA
6900: 6e 64 52 65 73 65 74 44 65 6c 65 74 65 52 65 73  ndResetDeleteRes
6910: 75 6c 74 28 69 6e 74 20 2a 72 65 73 75 6c 74 29  ult(int *result)
6920: 20 7b 0a 20 20 69 66 20 28 72 65 73 75 6c 74 29   {.  if (result)
6930: 0a 20 20 20 20 2a 72 65 73 75 6c 74 20 3d 20 64  .    *result = d
6940: 65 6c 65 74 65 5f 72 65 73 75 6c 74 5f 3b 0a 20  elete_result_;. 
6950: 20 64 65 6c 65 74 65 5f 72 65 73 75 6c 74 5f 20   delete_result_ 
6960: 3d 20 6b 50 65 6e 64 69 6e 67 52 65 73 75 6c 74  = kPendingResult
6970: 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74 65 20 3c 74  ;.}..template <t
6980: 79 70 65 6e 61 6d 65 20 4e 6f 64 65 54 79 70 65  ypename NodeType
6990: 3e 0a 76 6f 69 64 20 4e 6f 64 65 43 6f 6e 74 61  >.void NodeConta
69a0: 69 6e 65 72 3c 4e 6f 64 65 54 79 70 65 3e 3a 3a  iner<NodeType>::
69b0: 47 65 74 41 6e 64 52 65 73 65 74 55 70 64 61 74  GetAndResetUpdat
69c0: 65 52 65 73 75 6c 74 28 69 6e 74 20 2a 72 65 73  eResult(int *res
69d0: 75 6c 74 29 20 7b 0a 20 20 69 66 20 28 72 65 73  ult) {.  if (res
69e0: 75 6c 74 29 0a 20 20 20 20 2a 72 65 73 75 6c 74  ult).    *result
69f0: 20 3d 20 75 70 64 61 74 65 5f 72 65 73 75 6c 74   = update_result
6a00: 5f 3b 0a 20 20 75 70 64 61 74 65 5f 72 65 73 75  _;.  update_resu
6a10: 6c 74 5f 20 3d 20 6b 50 65 6e 64 69 6e 67 52 65  lt_ = kPendingRe
6a20: 73 75 6c 74 3b 0a 7d 0a 0a 74 65 6d 70 6c 61 74  sult;.}..templat
6a30: 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f 64 65  e <typename Node
6a40: 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f 64 65 43  Type>.void NodeC
6a50: 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54 79 70  ontainer<NodeTyp
6a60: 65 3e 3a 3a 47 65 74 41 6e 64 52 65 73 65 74 46  e>::GetAndResetF
6a70: 69 6e 64 4e 6f 64 65 73 52 65 73 75 6c 74 28 0a  indNodesResult(.
6a80: 20 20 20 20 69 6e 74 20 2a 72 65 73 75 6c 74 2c      int *result,
6a90: 0a 20 20 20 20 73 74 64 3a 3a 76 65 63 74 6f 72  .    std::vector
6aa0: 3c 43 6f 6e 74 61 63 74 3e 20 2a 63 6c 6f 73 65  <Contact> *close
6ab0: 73 74 5f 6e 6f 64 65 73 29 20 7b 0a 20 20 69 66  st_nodes) {.  if
6ac0: 20 28 72 65 73 75 6c 74 29 0a 20 20 20 20 2a 72   (result).    *r
6ad0: 65 73 75 6c 74 20 3d 20 66 69 6e 64 5f 6e 6f 64  esult = find_nod
6ae0: 65 73 5f 72 65 73 75 6c 74 5f 3b 0a 20 20 69 66  es_result_;.  if
6af0: 20 28 63 6c 6f 73 65 73 74 5f 6e 6f 64 65 73 29   (closest_nodes)
6b00: 0a 20 20 20 20 2a 63 6c 6f 73 65 73 74 5f 6e 6f  .    *closest_no
6b10: 64 65 73 20 3d 20 66 69 6e 64 5f 6e 6f 64 65 73  des = find_nodes
6b20: 5f 63 6c 6f 73 65 73 74 5f 6e 6f 64 65 73 5f 3b  _closest_nodes_;
6b30: 0a 20 20 66 69 6e 64 5f 6e 6f 64 65 73 5f 72 65  .  find_nodes_re
6b40: 73 75 6c 74 5f 20 3d 20 6b 50 65 6e 64 69 6e 67  sult_ = kPending
6b50: 52 65 73 75 6c 74 3b 0a 20 20 66 69 6e 64 5f 6e  Result;.  find_n
6b60: 6f 64 65 73 5f 63 6c 6f 73 65 73 74 5f 6e 6f 64  odes_closest_nod
6b70: 65 73 5f 2e 63 6c 65 61 72 28 29 3b 0a 7d 0a 0a  es_.clear();.}..
6b80: 74 65 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e 61  template <typena
6b90: 6d 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f 69  me NodeType>.voi
6ba0: 64 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c  d NodeContainer<
6bb0: 4e 6f 64 65 54 79 70 65 3e 3a 3a 47 65 74 41 6e  NodeType>::GetAn
6bc0: 64 52 65 73 65 74 46 69 6e 64 56 61 6c 75 65 52  dResetFindValueR
6bd0: 65 73 75 6c 74 28 0a 20 20 20 20 46 69 6e 64 56  esult(.    FindV
6be0: 61 6c 75 65 52 65 74 75 72 6e 73 20 2a 66 69 6e  alueReturns *fin
6bf0: 64 5f 76 61 6c 75 65 5f 72 65 74 75 72 6e 73 29  d_value_returns)
6c00: 20 7b 0a 20 20 69 66 20 28 66 69 6e 64 5f 76 61   {.  if (find_va
6c10: 6c 75 65 5f 72 65 74 75 72 6e 73 29 0a 20 20 20  lue_returns).   
6c20: 20 2a 66 69 6e 64 5f 76 61 6c 75 65 5f 72 65 74   *find_value_ret
6c30: 75 72 6e 73 20 3d 20 66 69 6e 64 5f 76 61 6c 75  urns = find_valu
6c40: 65 5f 72 65 74 75 72 6e 73 5f 3b 0a 20 20 66 69  e_returns_;.  fi
6c50: 6e 64 5f 76 61 6c 75 65 5f 72 65 74 75 72 6e 73  nd_value_returns
6c60: 5f 2e 63 61 63 68 65 64 5f 63 6f 70 79 5f 68 6f  _.cached_copy_ho
6c70: 6c 64 65 72 20 3d 20 43 6f 6e 74 61 63 74 28 29  lder = Contact()
6c80: 3b 0a 20 20 66 69 6e 64 5f 76 61 6c 75 65 5f 72  ;.  find_value_r
6c90: 65 74 75 72 6e 73 5f 2e 63 6c 6f 73 65 73 74 5f  eturns_.closest_
6ca0: 6e 6f 64 65 73 2e 63 6c 65 61 72 28 29 3b 0a 20  nodes.clear();. 
6cb0: 20 66 69 6e 64 5f 76 61 6c 75 65 5f 72 65 74 75   find_value_retu
6cc0: 72 6e 73 5f 2e 6e 65 65 64 73 5f 63 61 63 68 65  rns_.needs_cache
6cd0: 5f 63 6f 70 79 20 3d 20 43 6f 6e 74 61 63 74 28  _copy = Contact(
6ce0: 29 3b 0a 20 20 66 69 6e 64 5f 76 61 6c 75 65 5f  );.  find_value_
6cf0: 72 65 74 75 72 6e 73 5f 2e 72 65 74 75 72 6e 5f  returns_.return_
6d00: 63 6f 64 65 20 3d 20 6b 50 65 6e 64 69 6e 67 52  code = kPendingR
6d10: 65 73 75 6c 74 3b 0a 20 20 66 69 6e 64 5f 76 61  esult;.  find_va
6d20: 6c 75 65 5f 72 65 74 75 72 6e 73 5f 2e 76 61 6c  lue_returns_.val
6d30: 75 65 73 5f 61 6e 64 5f 73 69 67 6e 61 74 75 72  ues_and_signatur
6d40: 65 73 2e 63 6c 65 61 72 28 29 3b 0a 7d 0a 0a 74  es.clear();.}..t
6d50: 65 6d 70 6c 61 74 65 20 3c 74 79 70 65 6e 61 6d  emplate <typenam
6d60: 65 20 4e 6f 64 65 54 79 70 65 3e 0a 76 6f 69 64  e NodeType>.void
6d70: 20 4e 6f 64 65 43 6f 6e 74 61 69 6e 65 72 3c 4e   NodeContainer<N
6d80: 6f 64 65 54 79 70 65 3e 3a 3a 47 65 74 41 6e 64  odeType>::GetAnd
6d90: 52 65 73 65 74 47 65 74 43 6f 6e 74 61 63 74 52  ResetGetContactR
6da0: 65 73 75 6c 74 28 69 6e 74 20 2a 72 65 73 75 6c  esult(int *resul
6db0: 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  t,.             
6dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 43 6f 6e               Con
6df0: 74 61 63 74 20 2a 63 6f 6e 74 61 63 74 29 20 7b  tact *contact) {
6e00: 0a 20 20 69 66 20 28 72 65 73 75 6c 74 29 0a 20  .  if (result). 
6e10: 20 20 20 2a 72 65 73 75 6c 74 20 3d 20 67 65 74     *result = get
6e20: 5f 63 6f 6e 74 61 63 74 5f 72 65 73 75 6c 74 5f  _contact_result_
6e30: 3b 0a 20 20 69 66 20 28 63 6f 6e 74 61 63 74 29  ;.  if (contact)
6e40: 0a 20 20 20 20 2a 63 6f 6e 74 61 63 74 20 3d 20  .    *contact = 
6e50: 67 6f 74 74 65 6e 5f 63 6f 6e 74 61 63 74 5f 3b  gotten_contact_;
6e60: 0a 20 20 67 65 74 5f 63 6f 6e 74 61 63 74 5f 72  .  get_contact_r
6e70: 65 73 75 6c 74 5f 20 3d 20 6b 50 65 6e 64 69 6e  esult_ = kPendin
6e80: 67 52 65 73 75 6c 74 3b 0a 20 20 67 6f 74 74 65  gResult;.  gotte
6e90: 6e 5f 63 6f 6e 74 61 63 74 5f 20 3d 20 43 6f 6e  n_contact_ = Con
6ea0: 74 61 63 74 28 29 3b 0a 7d 0a 0a 74 65 6d 70 6c  tact();.}..templ
6eb0: 61 74 65 20 3c 74 79 70 65 6e 61 6d 65 20 4e 6f  ate <typename No
6ec0: 64 65 54 79 70 65 3e 0a 76 6f 69 64 20 4e 6f 64  deType>.void Nod
6ed0: 65 43 6f 6e 74 61 69 6e 65 72 3c 4e 6f 64 65 54  eContainer<NodeT
6ee0: 79 70 65 3e 3a 3a 47 65 74 41 6e 64 52 65 73 65  ype>::GetAndRese
6ef0: 74 50 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 20  tPingResult(int 
6f00: 2a 72 65 73 75 6c 74 29 20 7b 0a 20 20 69 66 20  *result) {.  if 
6f10: 28 72 65 73 75 6c 74 29 0a 20 20 20 20 2a 72 65  (result).    *re
6f20: 73 75 6c 74 20 3d 20 70 69 6e 67 5f 72 65 73 75  sult = ping_resu
6f30: 6c 74 5f 3b 0a 20 20 70 69 6e 67 5f 72 65 73 75  lt_;.  ping_resu
6f40: 6c 74 5f 20 3d 20 6b 50 65 6e 64 69 6e 67 52 65  lt_ = kPendingRe
6f50: 73 75 6c 74 3b 0a 7d 0a 0a 7d 20 20 2f 2f 20 6e  sult;.}..}  // n
6f60: 61 6d 65 73 70 61 63 65 20 64 68 74 0a 0a 7d 20  amespace dht..} 
6f70: 20 2f 2f 20 6e 61 6d 65 73 70 61 63 65 20 6d 61   // namespace ma
6f80: 69 64 73 61 66 65 0a 0a 23 65 6e 64 69 66 20 20  idsafe..#endif  
6f90: 2f 2f 20 4d 41 49 44 53 41 46 45 5f 44 48 54 5f  // MAIDSAFE_DHT_
6fa0: 4e 4f 44 45 5f 43 4f 4e 54 41 49 4e 45 52 5f 48  NODE_CONTAINER_H
6fb0: 5f 0a                                            _.