mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Addition of libbitdht.
============================================================ This is intended to be a completely independent library from RS, (hosted at sf.net/projects/bitdht) hence is being commited at the top level. As initial further development / testing will be driven by RS integration it is being added to the RS repository. Equally important is ensuring that RS can compile without requiring aux libraries. Once libbitdht is further developed, this section of the repository is expected to be removed... But that will not be for a while, I expect. drbob. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3276 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
9b72977bba
commit
c415bb6158
44
libbitdht/src/bitdht/Makefile
Normal file
44
libbitdht/src/bitdht/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
CPPFLAGS += -g -Wall -D BE_DEBUG -lpthread
|
||||
LDFLAGS += -g -Wall -D BE_DEBUG -lpthread
|
||||
CFLAGS += -g -Wall -D BE_DEBUG
|
||||
CC = g++
|
||||
LIB = -lpthread
|
||||
CPPLIB = -lpthread
|
||||
|
||||
EXEC = bdmsgs_test bdmetric_test bdquery_test bdspace_test bdspace_test2 bdnode_test bdnode_test2 bdstore_test
|
||||
EXEC += bdnode_multitest1 bdmidids_test
|
||||
EXEC += udpbitdht_nettest bencode_test
|
||||
EXEC += bdmgr_multitest
|
||||
#EXEC += bdudp_test
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
OBJ = bencode.o bdmsgs.o bdobj.o
|
||||
OBJ += bdpeer.o bdquery.o bdnode.o bdstore.o bdhash.o
|
||||
OBJ += bdmanager.o bdstddht.o
|
||||
|
||||
# udp base objs
|
||||
OBJ += bdthreads.o udplayer.o udpstack.o
|
||||
OBJ += udpbitdht.o
|
||||
|
||||
bdmsgs_test: $(OBJ) bdmsgs_test.o
|
||||
bdmetric_test: $(OBJ) bdmetric_test.o
|
||||
bdquery_test: $(OBJ) bdquery_test.o
|
||||
bdspace_test: $(OBJ) bdspace_test.o
|
||||
bdspace_test2: $(OBJ) bdspace_test2.o
|
||||
bdnode_test: $(OBJ) bdnode_test.o
|
||||
bdnode_test2: $(OBJ) bdnode_test2.o
|
||||
bdmidids_test: $(OBJ) bdmidids_test.o
|
||||
|
||||
bdnode_multitest1: $(OBJ) bdnode_multitest1.o
|
||||
bdmgr_multitest: $(OBJ) bdmgr_multitest.o
|
||||
|
||||
bdstore_test: $(OBJ) bdstore_test.o
|
||||
bdudp_test: $(OBJ) bdudp_test.o
|
||||
udpbitdht_nettest: $(OBJ) udpbitdht_nettest.o
|
||||
bencode_test: $(OBJ) bencode_test.o
|
||||
|
||||
clean:
|
||||
rm -f *.o core $(EXEC)
|
||||
|
||||
.PHONY: all clean
|
22
libbitdht/src/bitdht/README.txt
Normal file
22
libbitdht/src/bitdht/README.txt
Normal file
@ -0,0 +1,22 @@
|
||||
BitDHT Notes
|
||||
==================================================================
|
||||
|
||||
Compiling
|
||||
------------------------------------------------------------------
|
||||
Should compile on POSIX platforms.
|
||||
|
||||
|
||||
Testing
|
||||
------------------------------------------------------------------
|
||||
Run the program: udpbitdht_nettest to see the
|
||||
|
||||
This requires an up-to-date list of dht peers (in bdboot.txt)
|
||||
|
||||
|
||||
Using BitDHT
|
||||
------------------------------------------------------------------
|
||||
Use udpbitdht_nettest.cc as an example.
|
||||
|
||||
|
||||
|
||||
|
500
libbitdht/src/bitdht/bdboot.txt
Normal file
500
libbitdht/src/bitdht/bdboot.txt
Normal file
@ -0,0 +1,500 @@
|
||||
85.84.48.19 62069
|
||||
188.2.228.28 60928
|
||||
62.83.45.61 11568
|
||||
117.254.136.81 18497
|
||||
98.111.73.242 34446
|
||||
109.60.19.104 37721
|
||||
83.86.184.100 36986
|
||||
95.90.60.246 13411
|
||||
93.103.249.247 17844
|
||||
77.83.229.93 64116
|
||||
24.247.120.140 23842
|
||||
85.132.104.212 30998
|
||||
115.132.178.64 11325
|
||||
85.196.251.212 59225
|
||||
85.173.224.49 36195
|
||||
189.245.47.185 55119
|
||||
75.53.207.9 53187
|
||||
190.213.101.234 26250
|
||||
84.203.43.111 57306
|
||||
96.51.136.17 10484
|
||||
203.165.188.146 14675
|
||||
122.25.24.101 14705
|
||||
114.36.164.228 17732
|
||||
41.226.62.44 53581
|
||||
89.236.15.238 14222
|
||||
210.56.72.100 6881
|
||||
88.88.85.118 27454
|
||||
78.31.244.65 21454
|
||||
89.106.18.4 36678
|
||||
89.156.180.170 14699
|
||||
193.150.220.231 30107
|
||||
188.163.57.203 44741
|
||||
94.231.147.133 36245
|
||||
94.26.10.42 62398
|
||||
123.238.122.209 37115
|
||||
188.168.95.21 61843
|
||||
82.131.119.60 13400
|
||||
187.57.146.165 57592
|
||||
188.36.217.211 7908
|
||||
201.87.57.192 22219
|
||||
173.73.78.128 38903
|
||||
212.75.14.55 10094
|
||||
173.179.220.61 22534
|
||||
96.228.35.250 64059
|
||||
204.9.160.114 12368
|
||||
76.20.112.90 12745
|
||||
178.162.170.237 6837
|
||||
99.225.40.127 64192
|
||||
212.174.9.10 64969
|
||||
68.149.156.129 61517
|
||||
98.227.233.64 62196
|
||||
77.250.125.124 6881
|
||||
62.44.99.141 52068
|
||||
77.37.139.99 26973
|
||||
183.178.58.77 16541
|
||||
109.87.84.249 62000
|
||||
86.156.8.14 31121
|
||||
78.96.204.184 37646
|
||||
95.208.228.12 51852
|
||||
79.181.10.12 19169
|
||||
58.179.100.228 47488
|
||||
70.68.11.80 23032
|
||||
178.122.193.176 18010
|
||||
121.102.167.147 61588
|
||||
89.74.251.47 19639
|
||||
114.37.157.199 22245
|
||||
93.152.182.255 19793
|
||||
217.42.96.8 24111
|
||||
189.25.9.26 20730
|
||||
68.1.165.39 16153
|
||||
83.132.36.86 35107
|
||||
59.2.54.186 22753
|
||||
84.30.228.249 3603
|
||||
190.44.97.178 63549
|
||||
114.27.99.216 7975
|
||||
99.226.153.196 18904
|
||||
24.23.243.23 51030
|
||||
115.252.101.138 51413
|
||||
211.30.223.198 32067
|
||||
113.190.149.88 63726
|
||||
76.232.119.73 61243
|
||||
95.25.155.218 42786
|
||||
99.62.240.185 52482
|
||||
92.113.120.171 10234
|
||||
212.233.134.225 8819
|
||||
70.75.155.80 16019
|
||||
87.110.100.101 10873
|
||||
59.146.201.104 57237
|
||||
201.83.152.32 24543
|
||||
99.99.31.175 52843
|
||||
86.143.252.240 50299
|
||||
201.79.156.40 38331
|
||||
78.146.142.55 18908
|
||||
118.241.39.15 26062
|
||||
61.91.88.16 16880
|
||||
88.178.52.25 20468
|
||||
69.123.232.123 23334
|
||||
220.141.159.163 23769
|
||||
83.98.249.113 12604
|
||||
173.2.225.155 20471
|
||||
66.108.142.1 60204
|
||||
75.68.198.80 14064
|
||||
89.253.185.103 14063
|
||||
82.137.66.237 21717
|
||||
67.215.242.138 6881
|
||||
76.119.206.114 6881
|
||||
188.81.233.217 59939
|
||||
77.95.25.38 6881
|
||||
212.3.131.96 53635
|
||||
70.31.60.158 56555
|
||||
122.164.78.136 31953
|
||||
207.204.107.33 12071
|
||||
83.253.2.148 52645
|
||||
62.162.165.238 11553
|
||||
76.103.80.68 32811
|
||||
90.151.46.103 57998
|
||||
114.43.239.200 9620
|
||||
123.120.130.151 20770
|
||||
118.9.60.210 7813
|
||||
112.205.90.145 27962
|
||||
217.234.194.195 20877
|
||||
212.187.7.68 41823
|
||||
96.252.93.35 10000
|
||||
24.192.137.82 56168
|
||||
174.57.52.107 56989
|
||||
66.203.164.20 16210
|
||||
61.216.174.232 21308
|
||||
78.90.179.122 25664
|
||||
86.162.62.101 24916
|
||||
86.72.3.89 22909
|
||||
81.216.162.216 22372
|
||||
203.100.241.233 17074
|
||||
123.191.63.77 1841
|
||||
61.230.220.21 10879
|
||||
124.64.109.96 20031
|
||||
78.90.245.119 22874
|
||||
91.124.179.132 42780
|
||||
98.111.11.78 50609
|
||||
125.230.40.185 22930
|
||||
78.157.19.76 22610
|
||||
83.237.177.17 51372
|
||||
94.168.245.88 35405
|
||||
188.18.156.133 10346
|
||||
213.216.240.13 62911
|
||||
61.223.205.111 7743
|
||||
220.132.54.41 23993
|
||||
79.158.58.150 25173
|
||||
196.221.102.231 11116
|
||||
62.193.242.154 22820
|
||||
74.133.3.196 25720
|
||||
70.144.143.25 50647
|
||||
88.88.92.13 61596
|
||||
91.122.175.165 37942
|
||||
24.83.16.125 15112
|
||||
95.53.31.85 55555
|
||||
188.186.79.162 58714
|
||||
58.89.250.169 26502
|
||||
41.239.122.211 19233
|
||||
79.86.29.143 34934
|
||||
92.82.94.34 52773
|
||||
118.160.38.186 2470
|
||||
188.220.252.94 61799
|
||||
93.97.70.175 10371
|
||||
88.80.110.116 27521
|
||||
216.232.103.30 51413
|
||||
178.128.25.38 23875
|
||||
71.238.140.152 10899
|
||||
142.68.209.74 10742
|
||||
89.83.235.80 40013
|
||||
76.89.143.130 49160
|
||||
75.82.252.172 63072
|
||||
89.136.253.27 6881
|
||||
114.44.211.193 26085
|
||||
95.156.120.77 15619
|
||||
75.42.217.61 49160
|
||||
68.69.206.227 59769
|
||||
71.77.79.8 10892
|
||||
184.52.59.85 2664
|
||||
85.75.152.112 32480
|
||||
109.58.9.184 47618
|
||||
220.130.128.40 18686
|
||||
95.52.198.215 11043
|
||||
95.84.230.121 53479
|
||||
89.158.220.194 17054
|
||||
79.89.125.107 17636
|
||||
98.215.87.152 45826
|
||||
189.61.163.163 31148
|
||||
95.104.83.111 12834
|
||||
74.58.113.190 30498
|
||||
114.43.212.201 24526
|
||||
24.173.50.164 57812
|
||||
188.27.127.10 21264
|
||||
114.39.71.3 8260
|
||||
112.104.114.13 11403
|
||||
201.86.195.236 15035
|
||||
118.169.68.161 26721
|
||||
80.156.18.64 14332
|
||||
174.96.252.23 43975
|
||||
123.130.186.58 19042
|
||||
187.38.104.144 9879
|
||||
71.17.38.53 52994
|
||||
178.123.27.113 25116
|
||||
90.230.166.70 31359
|
||||
87.150.183.76 52525
|
||||
70.26.68.18 13332
|
||||
94.180.196.210 20700
|
||||
78.238.140.207 10512
|
||||
99.3.148.91 17673
|
||||
83.198.18.142 57125
|
||||
86.185.168.8 20759
|
||||
68.103.186.81 42197
|
||||
190.174.49.173 12198
|
||||
70.78.24.70 50620
|
||||
24.138.37.4 13731
|
||||
85.138.148.57 50005
|
||||
82.180.32.5 56466
|
||||
75.159.68.171 39889
|
||||
220.138.38.116 22904
|
||||
89.41.77.110 60377
|
||||
201.246.195.204 13183
|
||||
90.48.147.199 22636
|
||||
81.30.221.163 24570
|
||||
65.92.202.86 6969
|
||||
84.208.119.213 54480
|
||||
201.67.179.187 10004
|
||||
84.110.116.52 10223
|
||||
70.41.114.21 54838
|
||||
72.73.29.191 14757
|
||||
69.206.173.120 42760
|
||||
197.0.124.143 53121
|
||||
77.31.230.160 17522
|
||||
178.46.54.230 6968
|
||||
66.183.127.122 29982
|
||||
83.132.220.34 50143
|
||||
137.101.221.64 47111
|
||||
186.97.7.96 46409
|
||||
88.118.71.27 47522
|
||||
201.223.40.117 39859
|
||||
118.22.65.110 16460
|
||||
59.189.228.68 8683
|
||||
77.38.5.68 56958
|
||||
92.43.0.11 6881
|
||||
92.135.130.122 35998
|
||||
174.24.169.37 19227
|
||||
123.192.104.68 22971
|
||||
84.126.89.134 54282
|
||||
117.197.52.112 39667
|
||||
203.218.195.79 19524
|
||||
188.126.32.173 60563
|
||||
124.108.58.67 13622
|
||||
60.56.181.126 51044
|
||||
125.224.164.40 15101
|
||||
88.169.91.96 17138
|
||||
74.51.158.228 36152
|
||||
87.223.171.129 44869
|
||||
96.236.181.208 50529
|
||||
86.151.231.115 12800
|
||||
99.188.246.102 59753
|
||||
91.52.152.222 36279
|
||||
79.112.90.188 37635
|
||||
91.124.83.99 12034
|
||||
82.238.89.67 58533
|
||||
83.253.54.19 59453
|
||||
94.233.244.218 63774
|
||||
94.189.141.137 31727
|
||||
38.99.78.30 7914
|
||||
190.179.181.154 53529
|
||||
97.114.106.34 45737
|
||||
77.248.88.206 33146
|
||||
83.226.250.153 11097
|
||||
96.48.14.40 34453
|
||||
41.201.89.51 57110
|
||||
96.250.221.56 19356
|
||||
70.65.153.134 51486
|
||||
211.141.223.132 32004
|
||||
95.64.159.234 16962
|
||||
120.83.209.25 19881
|
||||
66.176.133.161 45717
|
||||
79.111.89.6 31756
|
||||
89.212.42.58 32346
|
||||
203.129.29.223 17051
|
||||
76.23.14.106 13352
|
||||
79.109.129.156 5738
|
||||
98.200.170.188 31325
|
||||
85.76.113.201 14112
|
||||
90.212.89.6 13341
|
||||
187.44.253.130 46324
|
||||
97.102.54.192 63656
|
||||
124.128.119.174 16001
|
||||
80.235.136.233 17866
|
||||
77.201.51.233 12686
|
||||
218.186.107.198 13096
|
||||
81.200.156.184 54547
|
||||
78.70.254.146 18989
|
||||
81.155.161.164 10504
|
||||
98.179.27.15 18674
|
||||
80.217.104.60 47749
|
||||
119.247.219.75 9810
|
||||
87.48.17.225 42002
|
||||
87.221.120.224 23355
|
||||
96.48.69.169 17610
|
||||
116.88.199.8 10231
|
||||
161.184.223.26 37338
|
||||
200.117.60.240 4672
|
||||
85.220.114.184 26414
|
||||
38.99.78.30 9460
|
||||
220.71.161.58 36128
|
||||
190.46.150.58 39162
|
||||
86.74.41.183 8916
|
||||
87.226.36.22 33380
|
||||
69.141.124.24 6799
|
||||
114.44.115.15 24203
|
||||
91.122.57.5 6881
|
||||
95.78.241.143 55568
|
||||
80.212.223.54 34277
|
||||
88.106.14.250 46095
|
||||
80.190.139.91 6899
|
||||
95.37.64.249 34699
|
||||
85.155.20.185 12939
|
||||
219.79.75.139 18716
|
||||
187.13.146.211 42197
|
||||
82.183.119.9 10073
|
||||
87.207.107.103 21022
|
||||
174.88.187.95 23442
|
||||
70.145.187.53 50580
|
||||
188.17.38.90 35691
|
||||
114.43.157.167 26367
|
||||
219.84.231.242 20456
|
||||
121.223.169.207 45625
|
||||
82.67.171.97 17713
|
||||
77.70.29.89 51379
|
||||
88.178.61.229 28038
|
||||
94.139.216.137 10906
|
||||
83.226.36.50 49999
|
||||
72.192.119.73 64855
|
||||
121.186.2.116 64243
|
||||
123.193.84.215 16116
|
||||
78.20.193.150 58408
|
||||
77.87.93.166 59007
|
||||
78.232.112.118 25724
|
||||
88.156.48.177 9585
|
||||
85.173.122.251 36230
|
||||
118.101.5.227 52022
|
||||
173.168.78.83 20187
|
||||
219.205.182.238 12369
|
||||
75.31.126.62 35882
|
||||
120.92.88.19 13448
|
||||
95.28.45.134 41509
|
||||
87.206.178.223 14258
|
||||
76.11.8.174 54491
|
||||
64.180.168.9 32456
|
||||
93.136.190.210 58705
|
||||
95.69.196.253 31010
|
||||
121.110.127.143 56259
|
||||
190.178.87.62 40511
|
||||
118.168.132.95 21413
|
||||
201.41.31.212 14727
|
||||
94.169.49.45 65143
|
||||
94.19.190.4 53965
|
||||
76.64.48.127 18259
|
||||
79.100.172.133 51013
|
||||
201.239.181.200 29658
|
||||
95.27.110.154 35691
|
||||
79.165.186.111 15866
|
||||
90.60.242.211 21502
|
||||
69.123.70.207 42799
|
||||
96.233.61.112 34504
|
||||
178.34.81.203 35691
|
||||
96.53.209.94 50471
|
||||
92.255.207.115 10183
|
||||
218.250.12.65 13837
|
||||
139.168.118.215 20396
|
||||
87.194.212.38 40010
|
||||
88.192.73.144 6881
|
||||
81.30.187.254 62330
|
||||
76.10.163.171 62740
|
||||
91.139.251.30 8376
|
||||
210.194.9.87 61565
|
||||
113.193.104.207 38541
|
||||
201.6.42.113 10101
|
||||
81.129.112.202 17033
|
||||
83.87.119.147 6881
|
||||
87.110.24.173 16166
|
||||
119.152.161.250 7609
|
||||
76.121.94.144 21088
|
||||
81.141.82.27 25454
|
||||
74.210.214.29 23405
|
||||
76.253.65.221 54321
|
||||
81.155.156.214 8856
|
||||
203.188.212.143 25352
|
||||
59.94.244.94 34481
|
||||
72.184.236.214 13526
|
||||
90.192.46.138 16349
|
||||
58.179.42.233 26370
|
||||
222.165.33.19 49875
|
||||
82.225.159.13 33697
|
||||
79.100.116.145 16972
|
||||
218.250.107.167 16743
|
||||
114.186.101.252 20447
|
||||
111.240.223.151 25057
|
||||
89.81.31.122 54510
|
||||
85.50.103.145 64767
|
||||
88.101.181.127 11691
|
||||
213.65.180.73 22326
|
||||
85.130.27.129 10044
|
||||
24.36.224.121 21400
|
||||
201.10.23.83 43773
|
||||
89.42.100.13 39734
|
||||
76.115.138.95 60004
|
||||
193.152.216.83 62411
|
||||
189.138.136.64 53821
|
||||
174.107.128.125 51729
|
||||
193.159.165.146 64735
|
||||
78.157.4.137 16401
|
||||
99.28.186.25 51347
|
||||
58.188.217.223 30147
|
||||
114.42.167.6 8514
|
||||
91.121.142.15 35939
|
||||
87.121.12.164 57469
|
||||
24.245.47.131 52676
|
||||
24.77.213.5 21096
|
||||
95.61.133.212 4658
|
||||
209.226.103.66 51765
|
||||
61.93.30.175 7583
|
||||
24.44.145.176 30911
|
||||
24.236.193.89 60444
|
||||
67.181.2.18 18126
|
||||
99.229.132.47 60053
|
||||
200.72.149.212 26556
|
||||
85.246.174.204 33530
|
||||
121.110.111.149 17487
|
||||
112.119.195.49 12607
|
||||
81.195.84.6 57264
|
||||
98.114.45.206 24295
|
||||
58.165.136.32 39743
|
||||
213.60.164.82 44749
|
||||
188.26.167.182 48135
|
||||
77.206.7.199 61195
|
||||
24.126.56.163 64590
|
||||
75.158.198.166 59643
|
||||
92.14.76.40 16730
|
||||
70.80.204.74 38517
|
||||
64.20.155.53 16351
|
||||
173.33.176.245 49161
|
||||
78.93.64.91 22302
|
||||
87.109.149.40 47695
|
||||
58.96.48.36 37252
|
||||
88.192.134.199 6924
|
||||
78.70.117.209 59473
|
||||
193.193.193.152 32042
|
||||
212.87.181.220 54130
|
||||
69.137.229.210 45681
|
||||
93.148.138.240 22516
|
||||
69.73.255.83 25295
|
||||
72.135.11.99 42315
|
||||
81.100.239.130 29827
|
||||
86.125.142.52 30095
|
||||
93.116.48.180 47676
|
||||
93.90.252.102 53033
|
||||
151.21.226.156 63269
|
||||
89.149.202.125 56351
|
||||
189.22.50.162 51413
|
||||
82.24.181.14 6888
|
||||
83.238.236.178 16049
|
||||
76.111.181.68 18631
|
||||
122.106.62.138 60003
|
||||
221.2.83.190 14418
|
||||
81.154.92.221 35015
|
||||
77.238.244.37 45365
|
||||
83.167.76.124 25705
|
||||
71.32.58.187 61111
|
||||
82.127.5.90 55516
|
||||
114.243.240.89 14022
|
||||
89.100.108.135 42419
|
||||
94.253.85.157 39808
|
||||
71.74.98.133 46791
|
||||
98.166.220.46 31377
|
||||
69.76.179.45 15505
|
||||
201.253.20.230 10063
|
||||
78.235.15.169 52020
|
||||
89.216.250.81 52546
|
||||
99.233.74.84 45147
|
||||
76.19.148.42 48404
|
||||
78.87.184.78 52544
|
||||
182.89.61.7 26752
|
||||
90.25.2.224 16875
|
||||
68.192.125.173 32823
|
||||
71.191.177.11 51413
|
||||
71.117.207.9 53782
|
||||
201.223.75.234 39364
|
||||
94.6.233.187 42289
|
||||
87.229.158.13 55213
|
||||
151.51.38.224 34173
|
||||
85.74.163.171 17165
|
||||
75.70.154.238 48368
|
||||
122.172.14.243 56489
|
||||
94.67.136.84 15686
|
||||
99.192.18.155 42965
|
||||
86.207.159.183 50058
|
||||
85.85.99.46 23409
|
279
libbitdht/src/bitdht/bdhash.cc
Normal file
279
libbitdht/src/bitdht/bdhash.cc
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* bitdht/bdhash.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdhash.h"
|
||||
#include "bdstddht.h"
|
||||
#include <iostream>
|
||||
|
||||
bdHashEntry::bdHashEntry(std::string value, std::string secret, time_t lifetime, time_t store)
|
||||
:mValue(value), mStoreTS(store), mSecret(secret), mLifetime(lifetime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**************************** class bdHashSet ********************************/
|
||||
|
||||
bdHashSet::bdHashSet(bdNodeId *id)
|
||||
:mId(*id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int bdHashSet::search(std::string key, uint32_t maxAge, std::list<bdHashEntry> &entries)
|
||||
{
|
||||
std::multimap<std::string, bdHashEntry>::iterator sit, eit, it;
|
||||
sit = mEntries.lower_bound(key);
|
||||
eit = mEntries.upper_bound(key);
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
for(it = sit; it != eit; it++)
|
||||
{
|
||||
time_t age = now - it->second.mStoreTS;
|
||||
if (age < (int32_t) maxAge)
|
||||
{
|
||||
entries.push_back(it->second);
|
||||
}
|
||||
}
|
||||
return (0 < entries.size());
|
||||
}
|
||||
|
||||
/***
|
||||
* With modification.
|
||||
* If there is no secret -> it cannot be deleted (must timeout), but can be extended.
|
||||
* If there is a secret -> must include it to modify.
|
||||
*
|
||||
* Therefore if identical entry without secret comes along - what do I do?
|
||||
* -> create duplicate?
|
||||
*/
|
||||
|
||||
int bdHashSet::modify(std::string key, bdHashEntry *entry, uint32_t modFlags)
|
||||
{
|
||||
std::multimap<std::string, bdHashEntry>::iterator sit, eit, it;
|
||||
sit = mEntries.lower_bound(key);
|
||||
eit = mEntries.upper_bound(key);
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
bool updated = false;
|
||||
for(it = sit; it != eit; it++)
|
||||
{
|
||||
/* check it all */
|
||||
if (it->second.mValue == entry->mValue)
|
||||
{
|
||||
bool noSecret = (it->second.mSecret == "");
|
||||
bool sameSecret = (it->second.mSecret == entry->mSecret);
|
||||
bool update = false;
|
||||
|
||||
if (noSecret && sameSecret)
|
||||
{
|
||||
/* only allowed to increase lifetime */
|
||||
if (modFlags == BITDHT_HASH_ENTRY_ADD)
|
||||
{
|
||||
time_t existKillTime = it->second.mLifetime + it->second.mStoreTS;
|
||||
time_t newKillTime = entry->mLifetime + now;
|
||||
if (newKillTime > existKillTime)
|
||||
{
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sameSecret)
|
||||
{
|
||||
if (modFlags == BITDHT_HASH_ENTRY_ADD)
|
||||
{
|
||||
update = true;
|
||||
}
|
||||
else if (modFlags == BITDHT_HASH_ENTRY_DELETE)
|
||||
{
|
||||
/* do it here */
|
||||
mEntries.erase(it);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
it->second.mStoreTS = now;
|
||||
it->second.mLifetime = entry->mLifetime;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((!updated) && (modFlags == BITDHT_HASH_ENTRY_ADD))
|
||||
{
|
||||
/* create a new entry */
|
||||
bdHashEntry newEntry(entry->mValue, entry->mSecret, entry->mLifetime, now);
|
||||
mEntries.insert(std::pair<std::string, bdHashEntry>(key, newEntry));
|
||||
updated = true;
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
int bdHashSet::printHashSet(std::ostream &out)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
std::multimap<std::string, bdHashEntry>::iterator it;
|
||||
out << "Hash: ";
|
||||
bdStdPrintNodeId(out, &mId); // Allowing "Std" as we dont need dht functions everywhere.
|
||||
out << std::endl;
|
||||
|
||||
for(it = mEntries.begin(); it != mEntries.end();it++)
|
||||
{
|
||||
time_t age = now - it->second.mStoreTS;
|
||||
out << "\tK:" << bdStdConvertToPrintable(it->first);
|
||||
out << " V:" << bdStdConvertToPrintable(it->second.mValue);
|
||||
out << " A:" << age << " L:" << it->second.mLifetime;
|
||||
out << " S:" << bdStdConvertToPrintable(it->second.mSecret);
|
||||
out << std::endl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int bdHashSet::cleanupHashSet(uint32_t maxAge)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* this is nasty... but don't know how to effectively remove from multimaps
|
||||
* * Must do full repeat for each removal.
|
||||
*/
|
||||
|
||||
std::multimap<std::string, bdHashEntry>::iterator it;
|
||||
for(it = mEntries.begin(); it != mEntries.end();)
|
||||
{
|
||||
time_t age = now - it->second.mStoreTS;
|
||||
if ((age > (int32_t) maxAge) || (age > it->second.mLifetime))
|
||||
{
|
||||
mEntries.erase(it);
|
||||
it = mEntries.begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************* class bdHashSpace ***************************/
|
||||
|
||||
bdHashSpace::bdHashSpace()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
int bdHashSpace::search(bdNodeId *id, std::string key, uint32_t maxAge, std::list<bdHashEntry> &entries)
|
||||
{
|
||||
std::map<bdNodeId, bdHashSet>::iterator it;
|
||||
it = mHashTable.find(*id);
|
||||
if (it == mHashTable.end())
|
||||
{
|
||||
/* no entry */
|
||||
return 1;
|
||||
}
|
||||
|
||||
return it->second.search(key, maxAge, entries);
|
||||
}
|
||||
|
||||
int bdHashSpace::modify(bdNodeId *id, std::string key, bdHashEntry *entry, uint32_t modFlags)
|
||||
{
|
||||
std::map<bdNodeId, bdHashSet>::iterator it;
|
||||
it = mHashTable.find(*id);
|
||||
if (it == mHashTable.end())
|
||||
{
|
||||
if (modFlags == BITDHT_HASH_ENTRY_DELETE)
|
||||
{
|
||||
/* done already */
|
||||
return 1;
|
||||
}
|
||||
|
||||
//mHashTable[*id] = bdHashSet(id);
|
||||
mHashTable.insert(std::pair<bdNodeId, bdHashSet>(*id, bdHashSet(id)));
|
||||
it = mHashTable.find(*id);
|
||||
}
|
||||
|
||||
return it->second.modify(key, entry, modFlags);
|
||||
}
|
||||
|
||||
int bdHashSpace::printHashSpace(std::ostream &out)
|
||||
{
|
||||
std::map<bdNodeId, bdHashSet>::iterator it;
|
||||
out << "bdHashSpace::printHashSpace()" << std::endl;
|
||||
out << "--------------------------------------------" << std::endl;
|
||||
|
||||
for(it = mHashTable.begin(); it != mHashTable.end(); it++)
|
||||
{
|
||||
it->second.printHashSet(out);
|
||||
}
|
||||
out << "--------------------------------------------" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bdHashSpace::cleanHashSpace(bdNodeId *min, bdNodeId *max, time_t maxAge)
|
||||
{
|
||||
std::map<bdNodeId, bdHashSet>::iterator it;
|
||||
std::list<bdNodeId> eraseList;
|
||||
std::list<bdNodeId>::iterator eit;
|
||||
|
||||
for(it = mHashTable.begin(); it != mHashTable.end(); it++)
|
||||
{
|
||||
if ((it->first < *min) ||
|
||||
(*max < it->first))
|
||||
{
|
||||
/* schedule for erasure */
|
||||
eraseList.push_back(it->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clean up Hash Set */
|
||||
it->second.cleanupHashSet(maxAge);
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
while(eraseList.size() > 0)
|
||||
{
|
||||
bdNodeId &eId = eraseList.front();
|
||||
it = mHashTable.find(eId);
|
||||
if (it != mHashTable.end())
|
||||
{
|
||||
mHashTable.erase(it);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
87
libbitdht/src/bitdht/bdhash.h
Normal file
87
libbitdht/src/bitdht/bdhash.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef BITDHT_HASH_SPACE_H
|
||||
#define BITDHT_HASH_SPACE_H
|
||||
|
||||
/*
|
||||
* bitdht/bdhash.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bdpeer.h"
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#define BITDHT_HASH_ENTRY_ADD 1
|
||||
#define BITDHT_HASH_ENTRY_DELETE 2
|
||||
|
||||
class bdHashEntry
|
||||
{
|
||||
public:
|
||||
|
||||
bdHashEntry(std::string value, std::string secret, time_t lifetime, time_t store);
|
||||
std::string mValue;
|
||||
time_t mStoreTS;
|
||||
|
||||
/* These are nice features that OpenDHT had */
|
||||
std::string mSecret;
|
||||
time_t mLifetime;
|
||||
};
|
||||
|
||||
|
||||
class bdHashSet
|
||||
{
|
||||
public:
|
||||
|
||||
bdHashSet(bdNodeId *id);
|
||||
|
||||
int search(std::string key, uint32_t maxAge, std::list<bdHashEntry> &entries);
|
||||
int modify(std::string key, bdHashEntry *entry, uint32_t modFlags);
|
||||
int printHashSet(std::ostream &out);
|
||||
int cleanupHashSet(uint32_t maxAge);
|
||||
|
||||
bdNodeId mId;
|
||||
std::multimap<std::string, bdHashEntry> mEntries;
|
||||
};
|
||||
|
||||
class bdHashSpace
|
||||
{
|
||||
public:
|
||||
|
||||
bdHashSpace();
|
||||
|
||||
/* accessors */
|
||||
int search(bdNodeId *id, std::string key, uint32_t maxAge, std::list<bdHashEntry> &entries);
|
||||
int modify(bdNodeId *id, std::string key, bdHashEntry *entry, uint32_t modFlags);
|
||||
|
||||
int printHashSpace(std::ostream&);
|
||||
int cleanHashSpace(bdNodeId *min, bdNodeId *max, time_t maxAge);
|
||||
|
||||
private:
|
||||
|
||||
std::map<bdNodeId, bdHashSet> mHashTable;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
182
libbitdht/src/bitdht/bdiface.h
Normal file
182
libbitdht/src/bitdht/bdiface.h
Normal file
@ -0,0 +1,182 @@
|
||||
#ifndef BIT_DHT_INTERFACE_H
|
||||
#define BIT_DHT_INTERFACE_H
|
||||
|
||||
/*
|
||||
* bitdht/bdiface.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/*
|
||||
* Functions and Classes required for Interfacing with the BitDht.
|
||||
* This should be the sole header file required to talk to Dht.
|
||||
* ... though setting it up will require including udpbitdht.h as well.
|
||||
*
|
||||
*/
|
||||
|
||||
#define BITDHT_KEY_LEN 20
|
||||
#define BITDHT_KEY_INTLEN 5
|
||||
#define BITDHT_KEY_BITLEN 160
|
||||
|
||||
|
||||
|
||||
|
||||
#define BITDHT_MAX_PKTSIZE 1024
|
||||
|
||||
#define BITDHT_TTL 64
|
||||
|
||||
#define BITDHT_SEARCH_ONE_SHOT 1
|
||||
#define BITDHT_SEARCH_REPEATING 2
|
||||
|
||||
class bdNodeId
|
||||
{
|
||||
public:
|
||||
unsigned char data[BITDHT_KEY_LEN];
|
||||
};
|
||||
|
||||
class bdMetric: public bdNodeId {};
|
||||
|
||||
class bdId
|
||||
{
|
||||
public:
|
||||
|
||||
bdId();
|
||||
bdId(bdNodeId in_id, struct sockaddr_in in_addr);
|
||||
|
||||
struct sockaddr_in addr;
|
||||
bdNodeId id;
|
||||
};
|
||||
|
||||
#define BITDHT_LIKELY_SAME_NO 0x00000000
|
||||
#define BITDHT_LIKELY_SAME_YES 0x00000001
|
||||
#define BITDHT_LIKELY_SAME_PORT_CHANGED 0x00000002
|
||||
#define BITDHT_LIKELY_SAME_LOC_CHANGED 0x00000004
|
||||
#define BITDHT_LIKELY_SAME_IDENTICAL 0x00000008
|
||||
|
||||
|
||||
class bdDhtFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
// bdDhtFunctions();
|
||||
/* setup variables */
|
||||
virtual uint16_t bdNumBuckets() = 0;
|
||||
virtual uint16_t bdNodesPerBucket() = 0; /* used for query + bdspace */
|
||||
virtual uint16_t bdBucketBitSize() = 0;
|
||||
|
||||
virtual int bdDistance(const bdNodeId *n1, const bdNodeId *n2, bdMetric *metric) = 0;
|
||||
virtual int bdBucketDistance(const bdNodeId *n1, const bdNodeId *n2) = 0;
|
||||
virtual int bdBucketDistance(const bdMetric *metric) = 0;
|
||||
|
||||
virtual uint32_t bdLikelySameNode(const bdId *id1, const bdId *id2) = 0;
|
||||
|
||||
virtual void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid) = 0;
|
||||
|
||||
virtual void bdPrintId(std::ostream &out, const bdId *a) = 0;
|
||||
virtual void bdPrintNodeId(std::ostream &out, const bdNodeId *a) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* peer flags
|
||||
* order is important!
|
||||
* higher bits = more priority.
|
||||
* BITDHT_PEER_STATUS_RECVPONG
|
||||
* BITDHT_PEER_STATUS_RECVNODES
|
||||
* BITDHT_PEER_STATUS_RECVHASHES
|
||||
* BITDHT_PEER_STATUS_DHT_ENGINE (dbXXxx)
|
||||
* BITDHT_PEER_STATUS_DHT_APPL (XXRSxx)
|
||||
* BITDHT_PEER_STATUS_DHT_VERSION (XXxx50)
|
||||
*
|
||||
*/
|
||||
|
||||
#define BITDHT_PEER_STATUS_MASK_RECVD 0x000000ff
|
||||
#define BITDHT_PEER_STATUS_MASK_DHT 0x000000ff
|
||||
|
||||
#define BITDHT_PEER_STATUS_RECV_PONG 0x00000001
|
||||
#define BITDHT_PEER_STATUS_RECV_NODES 0x00000002
|
||||
#define BITDHT_PEER_STATUS_RECV_HASHES 0x00000004
|
||||
|
||||
#define BITDHT_PEER_STATUS_DHT_ENGINE 0x00000100
|
||||
#define BITDHT_PEER_STATUS_DHT_APPL 0x00000200
|
||||
#define BITDHT_PEER_STATUS_DHT_VERSION 0x00000400
|
||||
|
||||
|
||||
/* Status options */
|
||||
#define BITDHT_QUERY_QUERYING 1
|
||||
#define BITDHT_QUERY_FAILURE 2
|
||||
#define BITDHT_QUERY_FOUND_CLOSEST 3
|
||||
#define BITDHT_QUERY_PEER_UNREACHABLE 4
|
||||
#define BITDHT_QUERY_SUCCESS 5
|
||||
|
||||
/* Query Flags */
|
||||
#define BITDHT_QFLAGS_NONE 0
|
||||
#define BITDHT_QFLAGS_DISGUISE 1
|
||||
#define BITDHT_QFLAGS_DO_IDLE 2
|
||||
|
||||
class BitDhtCallback
|
||||
{
|
||||
public:
|
||||
// ~BitDhtCallback();
|
||||
|
||||
// dummy cos not needed for standard dht behaviour;
|
||||
virtual int dhtNodeCallback(const bdId *id, uint32_t peerflags) { return 0; }
|
||||
|
||||
// must be implemented.
|
||||
virtual int dhtPeerCallback(const bdNodeId *id, uint32_t status) = 0;
|
||||
virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status) = 0;
|
||||
};
|
||||
|
||||
|
||||
class BitDhtInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/***** Request Lookup (DHT Peer & Keyword) *****/
|
||||
virtual void addFindNode(bdNodeId *id, uint32_t mode) = 0;
|
||||
virtual void removeFindNode(bdNodeId *id) = 0;
|
||||
virtual void findDhtValue(bdNodeId *id, std::string key, uint32_t mode) = 0;
|
||||
|
||||
/***** Add / Remove Callback Clients *****/
|
||||
virtual void addCallback(BitDhtCallback *cb) = 0;
|
||||
virtual void removeCallback(BitDhtCallback *cb) = 0;
|
||||
|
||||
/***** Get Results Details *****/
|
||||
virtual int getDhtPeerAddress(bdNodeId *id, struct sockaddr_in &from) = 0;
|
||||
virtual int getDhtValue(bdNodeId *id, std::string key, std::string &value) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
741
libbitdht/src/bitdht/bdmanager.cc
Normal file
741
libbitdht/src/bitdht/bdmanager.cc
Normal file
@ -0,0 +1,741 @@
|
||||
/*
|
||||
* bitdht/bdmanager.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*******
|
||||
* Node Manager.
|
||||
******/
|
||||
|
||||
/******************************************
|
||||
* 1) Maintains a list of ids to search for.
|
||||
* 2) Sets up initial search for own node.
|
||||
* 3) Checks on status of queries.
|
||||
* 4) Callback on successful searches.
|
||||
*
|
||||
* This is pretty specific to RS requirements.
|
||||
****/
|
||||
|
||||
#include "bdiface.h"
|
||||
#include "bdstddht.h"
|
||||
#include "bdmanager.h"
|
||||
#include "bdmsgs.h"
|
||||
#include "bencode.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/***
|
||||
* #define DEBUG_MGR 1
|
||||
* #define DEBUG_MGR_PKT 1
|
||||
***/
|
||||
|
||||
//#define DEBUG_MGR 1
|
||||
|
||||
bdNodeManager::bdNodeManager(bdNodeId *id, std::string dhtVersion, std::string bootfile, bdDhtFunctions *fns)
|
||||
:bdNode(id, dhtVersion, bootfile, fns)
|
||||
{
|
||||
mMode = BITDHT_MGR_STATE_STARTUP;
|
||||
mFns = fns;
|
||||
|
||||
/* setup a query for self */
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::bdNodeManager() ID: ";
|
||||
mFns->bdPrintNodeId(std::cerr, id);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void bdNodeManager::addFindNode(bdNodeId *id, uint32_t qflags)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::addFindNode() ";
|
||||
mFns->bdPrintNodeId(std::cerr, id);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* check if exists already */
|
||||
std::map<bdNodeId, bdQueryPeer>::iterator it;
|
||||
it = mActivePeers.find(*id);
|
||||
if (it != mActivePeers.end())
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::addFindNode() Found existing....";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* add to map */
|
||||
bdQueryPeer peer;
|
||||
peer.mId.id = (*id);
|
||||
peer.mStatus = BITDHT_QUERY_QUERYING;
|
||||
peer.mQFlags = qflags;
|
||||
mActivePeers[*id] = peer;
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::addFindNode() Added QueryPeer....";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
addQuery(id, qflags | BITDHT_QFLAGS_DISGUISE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void bdNodeManager::removeFindNode(bdNodeId *id)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::removeFindNode() ";
|
||||
mFns->bdPrintNodeId(std::cerr, id);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
std::map<bdNodeId, bdQueryPeer>::iterator it;
|
||||
it = mActivePeers.find(*id);
|
||||
if (it == mActivePeers.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* cleanup any actions */
|
||||
clearQuery(&(it->first));
|
||||
//clearPing(&(it->first));
|
||||
|
||||
/* remove from map */
|
||||
mActivePeers.erase(it);
|
||||
return;
|
||||
}
|
||||
|
||||
void bdNodeManager::iteration()
|
||||
{
|
||||
|
||||
time_t now = time(NULL);
|
||||
time_t modeAge = now - mModeTS;
|
||||
switch(mMode)
|
||||
{
|
||||
case BITDHT_MGR_STATE_STARTUP:
|
||||
/* 10 seconds startup .... then switch to ACTIVE */
|
||||
if (modeAge > MAX_STARTUP_TIME)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::iteration(): STARTUP ";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
bdNodeId id;
|
||||
getOwnId(&id);
|
||||
addQuery(&id, BITDHT_QFLAGS_DO_IDLE | BITDHT_QFLAGS_DISGUISE);
|
||||
|
||||
//mMode = BITDHT_MGR_STATE_ACTIVE;
|
||||
mMode = BITDHT_MGR_STATE_REFRESH;
|
||||
mModeTS = now;
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_MGR_STATE_ACTIVE:
|
||||
if (modeAge > MAX_REFRESH_TIME)
|
||||
{
|
||||
mMode = BITDHT_MGR_STATE_REFRESH;
|
||||
mModeTS = now;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BITDHT_MGR_STATE_REFRESH:
|
||||
{
|
||||
/* select random ids, and perform searchs to refresh space */
|
||||
mMode = BITDHT_MGR_STATE_ACTIVE;
|
||||
mModeTS = now;
|
||||
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::iteration(): Updating Stores";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
updateStore();
|
||||
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::iteration(): REFRESH ";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
status();
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_MGR_STATE_QUIET:
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* tick parent */
|
||||
bdNode::iteration();
|
||||
}
|
||||
|
||||
|
||||
int bdNodeManager::status()
|
||||
{
|
||||
/* do status of bdNode */
|
||||
printState();
|
||||
|
||||
checkStatus();
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int bdNodeManager::checkStatus()
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* check queries */
|
||||
std::map<bdNodeId, bdQueryStatus>::iterator it;
|
||||
std::map<bdNodeId, bdQueryStatus> queryStatus;
|
||||
|
||||
|
||||
QueryStatus(queryStatus);
|
||||
|
||||
for(it = queryStatus.begin(); it != queryStatus.end(); it++)
|
||||
{
|
||||
bool doPing = false;
|
||||
bool doRemove = false;
|
||||
bool doCallback = false;
|
||||
uint32_t callbackStatus = 0;
|
||||
|
||||
switch(it->second.mStatus)
|
||||
{
|
||||
default:
|
||||
case BITDHT_QUERY_QUERYING:
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Query in Progress id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_QUERY_FAILURE:
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Query Failed: id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
// BAD.
|
||||
doRemove = true;
|
||||
doCallback = true;
|
||||
callbackStatus = BITDHT_MGR_QUERY_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_QUERY_FOUND_CLOSEST:
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Found Closest: id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
doRemove = true;
|
||||
doCallback = true;
|
||||
callbackStatus = BITDHT_MGR_QUERY_PEER_OFFLINE;
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_QUERY_PEER_UNREACHABLE:
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() the Peer Online but Unreachable: id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
doRemove = true;
|
||||
doCallback = true;
|
||||
callbackStatus = BITDHT_MGR_QUERY_PEER_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_QUERY_SUCCESS:
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Found Query: id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
//foundId =
|
||||
doRemove = true;
|
||||
doCallback = true;
|
||||
callbackStatus = BITDHT_MGR_QUERY_PEER_ONLINE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* remove done queries */
|
||||
if (doRemove)
|
||||
{
|
||||
if (it->second.mQFlags & BITDHT_QFLAGS_DO_IDLE)
|
||||
{
|
||||
doRemove = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (doRemove)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Removing query: id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
clearQuery(&(it->first));
|
||||
}
|
||||
|
||||
/* FIND in activePeers */
|
||||
std::map<bdNodeId, bdQueryPeer>::iterator pit;
|
||||
pit = mActivePeers.find(it->first);
|
||||
|
||||
if (pit == mActivePeers.end())
|
||||
{
|
||||
/* only internal! - disable Callback / Ping */
|
||||
doPing = false;
|
||||
doCallback = false;
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Internal: no cb for id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else if (pit->second.mStatus == it->second.mStatus)
|
||||
{
|
||||
/* status is unchanged */
|
||||
doPing = false;
|
||||
doCallback = false;
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Status unchanged for : ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << " status: " << it->second.mStatus;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Updating External Status for : ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << " to: " << it->second.mStatus;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* update status */
|
||||
pit->second.mStatus = it->second.mStatus;
|
||||
}
|
||||
|
||||
|
||||
/* add successful queries to ping list */
|
||||
if (doPing)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Starting Ping (TODO): id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* add first matching peer */
|
||||
//addPeerPing(foundId);
|
||||
}
|
||||
|
||||
/* callback on new successful queries */
|
||||
if (doCallback)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::checkStatus() Doing Callback: id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(it->first));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
doPeerCallback(&(it->first), callbackStatus);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bdNodeManager::checkPingStatus()
|
||||
{
|
||||
|
||||
/* check queries */
|
||||
std::map<bdNodeId, bdPingStatus>::iterator it;
|
||||
std::map<bdNodeId, bdPingStatus> pingStatus;
|
||||
|
||||
PingStatus(pingStatus);
|
||||
|
||||
for(it = pingStatus.begin(); it != pingStatus.end(); it++)
|
||||
{
|
||||
switch(it->second.mStatus)
|
||||
{
|
||||
case BITDHT_QUERY_QUERYING:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_QUERY_FAILURE:
|
||||
{
|
||||
// BAD.
|
||||
doRemove = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_QUERY_FOUND_CLOSEST:
|
||||
{
|
||||
|
||||
doRemove = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case BITDHT_QUERY_SUCCESS:
|
||||
{
|
||||
foundId =
|
||||
doRemove = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* remove done queries */
|
||||
if (doRemove)
|
||||
{
|
||||
clearQuery(it->first);
|
||||
}
|
||||
|
||||
/* add successful queries to ping list */
|
||||
if (doPing)
|
||||
{
|
||||
/* add first matching peer */
|
||||
addPeerPing(foundId);
|
||||
}
|
||||
|
||||
/* callback on new successful queries */
|
||||
if (doCallback)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int bdNodeManager::SearchOutOfDate()
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::SearchOutOfDate()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<bdNodeId, bdQueryPeer>::iterator it;
|
||||
|
||||
/* search for out-of-date peers */
|
||||
for(it = mActivePeers.begin(); it != mActivePeers.end(); it++)
|
||||
{
|
||||
#if 0
|
||||
if (old)
|
||||
{
|
||||
addQuery(it->first);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***** Functions to Call down to bdNodeManager ****/
|
||||
/* Request DHT Peer Lookup */
|
||||
/* Request Keyword Lookup */
|
||||
|
||||
void bdNodeManager::findDhtValue(bdNodeId *id, std::string key, uint32_t mode)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::findDhtValue() TODO";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***** Get Results Details *****/
|
||||
int bdNodeManager::getDhtPeerAddress(bdNodeId *id, struct sockaddr_in &from)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::getDhtPeerAddress() Id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, id);
|
||||
std::cerr << " ... ? TODO" << std::endl;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bdNodeManager::getDhtValue(bdNodeId *id, std::string key, std::string &value)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::getDhtValue() Id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, id);
|
||||
std::cerr << " key: " << key;
|
||||
std::cerr << " ... ? TODO" << std::endl;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***** Add / Remove Callback Clients *****/
|
||||
void bdNodeManager::addCallback(BitDhtCallback *cb)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::addCallback()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* search list */
|
||||
std::list<BitDhtCallback *>::iterator it;
|
||||
it = std::find(mCallbacks.begin(), mCallbacks.end(), cb);
|
||||
if (it == mCallbacks.end())
|
||||
{
|
||||
/* add it */
|
||||
mCallbacks.push_back(cb);
|
||||
}
|
||||
}
|
||||
|
||||
void bdNodeManager::removeCallback(BitDhtCallback *cb)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::removeCallback()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* search list */
|
||||
std::list<BitDhtCallback *>::iterator it;
|
||||
it = std::find(mCallbacks.begin(), mCallbacks.end(), cb);
|
||||
if (it == mCallbacks.end())
|
||||
{
|
||||
/* not found! */
|
||||
return;
|
||||
}
|
||||
it = mCallbacks.erase(it);
|
||||
}
|
||||
|
||||
|
||||
void bdNodeManager::addPeer(const bdId *id, uint32_t peerflags)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::addPeer() Overloaded (doing Callback)";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
doNodeCallback(id, peerflags);
|
||||
|
||||
// call parent.
|
||||
bdNode::addPeer(id, peerflags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void bdNodeManager::doNodeCallback(const bdId *id, uint32_t peerflags)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::doPeerCallback()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* search list */
|
||||
std::list<BitDhtCallback *>::iterator it;
|
||||
for(it = mCallbacks.begin(); it != mCallbacks.end(); it++)
|
||||
{
|
||||
(*it)->dhtNodeCallback(id, peerflags);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void bdNodeManager::doPeerCallback(const bdNodeId *id, uint32_t status)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::doPeerCallback()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* search list */
|
||||
std::list<BitDhtCallback *>::iterator it;
|
||||
for(it = mCallbacks.begin(); it != mCallbacks.end(); it++)
|
||||
{
|
||||
(*it)->dhtPeerCallback(id, status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void bdNodeManager::doValueCallback(const bdNodeId *id, std::string key, uint32_t status)
|
||||
{
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::doValueCallback()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* search list */
|
||||
std::list<BitDhtCallback *>::iterator it;
|
||||
for(it = mCallbacks.begin(); it != mCallbacks.end(); it++)
|
||||
{
|
||||
(*it)->dhtPeerCallback(id, status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/******************* Internals *************************/
|
||||
int bdNodeManager::isBitDhtPacket(char *data, int size, struct sockaddr_in &from)
|
||||
|
||||
{
|
||||
#ifdef DEBUG_MGR_PKT
|
||||
std::cerr << "bdNodeManager::isBitDhtPacket() *******************************";
|
||||
std::cerr << " from " << inet_ntoa(from.sin_addr);
|
||||
std::cerr << ":" << ntohs(from.sin_port);
|
||||
std::cerr << std::endl;
|
||||
{
|
||||
/* print the fucker... only way to catch bad ones */
|
||||
std::ostringstream out;
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
if (isascii(data[i]))
|
||||
{
|
||||
out << data[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "[";
|
||||
out << std::setw(2) << std::setfill('0')
|
||||
<< std::hex << (uint32_t) data[i];
|
||||
out << "]";
|
||||
}
|
||||
if ((i % 16 == 0) && (i != 0))
|
||||
{
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
std::cerr << out.str();
|
||||
}
|
||||
std::cerr << "bdNodeManager::isBitDhtPacket() *******************************";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* try to parse it! */
|
||||
/* convert to a be_node */
|
||||
be_node *node = be_decoden(data, size);
|
||||
if (!node)
|
||||
{
|
||||
/* invalid decode */
|
||||
#ifdef DEBUG_MGR
|
||||
std::cerr << "bdNodeManager::isBitDhtPacket() be_decode failed. dropping";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "bdNodeManager::BadPacket ******************************";
|
||||
std::cerr << " from " << inet_ntoa(from.sin_addr);
|
||||
std::cerr << ":" << ntohs(from.sin_port);
|
||||
std::cerr << std::endl;
|
||||
{
|
||||
/* print the fucker... only way to catch bad ones */
|
||||
std::ostringstream out;
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
if (isascii(data[i]))
|
||||
{
|
||||
out << data[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "[";
|
||||
out << std::setw(2) << std::setfill('0')
|
||||
<< std::hex << (uint32_t) data[i];
|
||||
out << "]";
|
||||
}
|
||||
if ((i % 16 == 0) && (i != 0))
|
||||
{
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
std::cerr << out.str();
|
||||
}
|
||||
std::cerr << "bdNodeManager::BadPacket ******************************";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* find message type */
|
||||
uint32_t beType = beMsgType(node);
|
||||
int ans = (beType != BITDHT_MSG_TYPE_UNKNOWN);
|
||||
be_free(node);
|
||||
|
||||
#ifdef DEBUG_MGR_PKT
|
||||
if (ans)
|
||||
{
|
||||
std::cerr << "bdNodeManager::isBitDhtPacket() YES";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "bdNodeManager::isBitDhtPacket() NO: Unknown Type";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
bdDebugCallback::~bdDebugCallback()
|
||||
{
|
||||
}
|
||||
|
||||
int bdDebugCallback::dhtPeerCallback(const bdNodeId *id, uint32_t status)
|
||||
{
|
||||
std::cerr << "bdDebugCallback::dhtPeerCallback() Id: ";
|
||||
bdStdPrintNodeId(std::cerr, id);
|
||||
std::cerr << " status: " << std::hex << status << std::dec << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bdDebugCallback::dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status)
|
||||
{
|
||||
std::cerr << "bdDebugCallback::dhtValueCallback() Id: ";
|
||||
bdStdPrintNodeId(std::cerr, id);
|
||||
std::cerr << " key: " << key;
|
||||
std::cerr << " status: " << std::hex << status << std::dec << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
156
libbitdht/src/bitdht/bdmanager.h
Normal file
156
libbitdht/src/bitdht/bdmanager.h
Normal file
@ -0,0 +1,156 @@
|
||||
#ifndef BITDHT_MANAGER_H
|
||||
#define BITDHT_MANAGER_H
|
||||
|
||||
/*
|
||||
* bitdht/bdmanager.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*******
|
||||
* Node Manager.
|
||||
******/
|
||||
|
||||
/******************************************
|
||||
* 1) Maintains a list of ids to search for.
|
||||
* 2) Sets up initial search for own node.
|
||||
* 3) Checks on status of queries.
|
||||
* 4) Callback on successful searches.
|
||||
*
|
||||
* This is pretty specific to RS requirements.
|
||||
****/
|
||||
|
||||
#define BITDHT_PS_MASK_ACTIONS (0x000000ff)
|
||||
#define BITDHT_PS_MASK_STATE (0x0000ff00)
|
||||
|
||||
#define BITDHT_PS_ACTION_SEARCHING (0x00000001)
|
||||
#define BITDHT_PS_ACTION_WAITING (0x00000002)
|
||||
#define BITDHT_PS_ACTION_PINGING (0x00000004)
|
||||
|
||||
#define BITDHT_PS_STATE_UNKNOWN (0x00000100)
|
||||
#define BITDHT_PS_STATE_OFFLINE (0x00000200)
|
||||
#define BITDHT_PS_STATE_ONLINE (0x00000400)
|
||||
#define BITDHT_PS_STATE_CONNECTED (0x00000800)
|
||||
|
||||
#include "bdiface.h"
|
||||
#include "bdnode.h"
|
||||
|
||||
|
||||
|
||||
class bdQueryPeer
|
||||
{
|
||||
public:
|
||||
bdId mId;
|
||||
uint32_t mStatus;
|
||||
uint32_t mQFlags;
|
||||
time_t mLastQuery;
|
||||
time_t mLastFound;
|
||||
};
|
||||
|
||||
|
||||
#define BITDHT_MGR_STATE_STARTUP 1
|
||||
#define BITDHT_MGR_STATE_ACTIVE 2
|
||||
#define BITDHT_MGR_STATE_REFRESH 3
|
||||
#define BITDHT_MGR_STATE_QUIET 4
|
||||
|
||||
#define MAX_STARTUP_TIME 10
|
||||
#define MAX_REFRESH_TIME 30
|
||||
|
||||
#define BITDHT_MGR_QUERY_FAILURE 1
|
||||
#define BITDHT_MGR_QUERY_PEER_OFFLINE 2
|
||||
#define BITDHT_MGR_QUERY_PEER_UNREACHABLE 3
|
||||
#define BITDHT_MGR_QUERY_PEER_ONLINE 4
|
||||
|
||||
|
||||
/*** NB: Nothing in here is protected by mutexes
|
||||
* must be done at a higher level!
|
||||
***/
|
||||
|
||||
class bdNodeManager: public bdNode, public BitDhtInterface
|
||||
{
|
||||
public:
|
||||
bdNodeManager(bdNodeId *id, std::string dhtVersion, std::string bootfile, bdDhtFunctions *fns);
|
||||
|
||||
|
||||
void iteration();
|
||||
|
||||
/***** Functions to Call down to bdNodeManager ****/
|
||||
/* Request DHT Peer Lookup */
|
||||
/* Request Keyword Lookup */
|
||||
virtual void addFindNode(bdNodeId *id, uint32_t mode);
|
||||
virtual void removeFindNode(bdNodeId *id);
|
||||
virtual void findDhtValue(bdNodeId *id, std::string key, uint32_t mode);
|
||||
|
||||
/***** Add / Remove Callback Clients *****/
|
||||
virtual void addCallback(BitDhtCallback *cb);
|
||||
virtual void removeCallback(BitDhtCallback *cb);
|
||||
|
||||
/***** Get Results Details *****/
|
||||
virtual int getDhtPeerAddress(bdNodeId *id, struct sockaddr_in &from);
|
||||
virtual int getDhtValue(bdNodeId *id, std::string key, std::string &value);
|
||||
|
||||
/******************* Internals *************************/
|
||||
|
||||
// Overloaded from bdnode for external node callback.
|
||||
virtual void addPeer(const bdId *id, uint32_t peerflags);
|
||||
|
||||
|
||||
int isBitDhtPacket(char *data, int size, struct sockaddr_in &from);
|
||||
private:
|
||||
|
||||
|
||||
void doNodeCallback(const bdId *id, uint32_t peerflags);
|
||||
void doPeerCallback(const bdNodeId *id, uint32_t status);
|
||||
void doValueCallback(const bdNodeId *id, std::string key, uint32_t status);
|
||||
|
||||
int status();
|
||||
int checkStatus();
|
||||
int checkPingStatus();
|
||||
int SearchOutOfDate();
|
||||
|
||||
std::map<bdNodeId, bdQueryPeer> mActivePeers;
|
||||
std::list<BitDhtCallback *> mCallbacks;
|
||||
|
||||
uint32_t mMode;
|
||||
time_t mModeTS;
|
||||
|
||||
bdDhtFunctions *mFns;
|
||||
|
||||
/* future node functions */
|
||||
//addPeerPing(foundId);
|
||||
//clearPing(it->first);
|
||||
//PingStatus(it->first);
|
||||
};
|
||||
|
||||
class bdDebugCallback: public BitDhtCallback
|
||||
{
|
||||
public:
|
||||
~bdDebugCallback();
|
||||
virtual int dhtPeerCallback(const bdNodeId *id, uint32_t status);
|
||||
virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
820
libbitdht/src/bitdht/bdmsgs.cc
Normal file
820
libbitdht/src/bitdht/bdmsgs.cc
Normal file
@ -0,0 +1,820 @@
|
||||
/*
|
||||
* bitdht/bdmsgs.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "bencode.h"
|
||||
#include "bdmsgs.h"
|
||||
|
||||
|
||||
int create_ping_message();
|
||||
int response_ping_message();
|
||||
|
||||
int find_node_message();
|
||||
int response_node_message();
|
||||
|
||||
int get_peers_message();
|
||||
int response_peers_message();
|
||||
int response_closestnodes_message();
|
||||
|
||||
/*
|
||||
ping Query = {"t":"aa", "y":"q", "q":"ping", "a":{"id":"abcdefghij0123456789"}}
|
||||
bencoded = d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe
|
||||
*/
|
||||
|
||||
/****
|
||||
* #define DEBUG_MSG_DUMP 1
|
||||
* #define DEBUG_MSG_TYPE 1
|
||||
* #define DEBUG_MSGS 1
|
||||
****/
|
||||
|
||||
|
||||
int bitdht_create_ping_msg(bdToken *tid, bdNodeId *id, char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_create_ping_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
be_node *iddict = be_create_dict();
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
|
||||
be_add_keypair(iddict, "id", idnode);
|
||||
|
||||
be_node *pingnode = be_create_str("ping");
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
be_node *qynode = be_create_str("q");
|
||||
|
||||
be_add_keypair(dict, "a", iddict);
|
||||
|
||||
be_add_keypair(dict, "q", pingnode);
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", qynode);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
return blen;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Response = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}}
|
||||
bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re
|
||||
*/
|
||||
|
||||
int bitdht_response_ping_msg(bdToken *tid, bdNodeId *id, bdToken *vid,
|
||||
char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_response_ping_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
|
||||
be_node *iddict = be_create_dict();
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
be_node *yqrnode = be_create_str("r");
|
||||
|
||||
be_node *vnode = be_create_str_wlen((char *) vid->data, vid->len);
|
||||
|
||||
be_add_keypair(iddict, "id", idnode);
|
||||
be_add_keypair(dict, "r", iddict);
|
||||
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", yqrnode);
|
||||
be_add_keypair(dict, "V", vnode);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
find_node Query = {"t":"aa", "y":"q", "q":"find_node", "a": {"id":"abcdefghij0123456789", "target":"mnopqrstuvwxyz123456"}}
|
||||
bencoded = d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe
|
||||
*/
|
||||
|
||||
|
||||
int bitdht_find_node_msg(bdToken *tid, bdNodeId *id, bdNodeId *target,
|
||||
char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_find_node_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
|
||||
be_node *iddict = be_create_dict();
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
be_node *targetnode = be_create_str_wlen((char *) target->data, BITDHT_KEY_LEN);
|
||||
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
be_node *yqrnode = be_create_str("q");
|
||||
be_node *findnode = be_create_str("find_node");
|
||||
|
||||
be_add_keypair(iddict, "id", idnode);
|
||||
be_add_keypair(iddict, "target", targetnode);
|
||||
be_add_keypair(dict, "a", iddict);
|
||||
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", yqrnode);
|
||||
be_add_keypair(dict, "q", findnode);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Response = {"t":"aa", "y":"r", "r": {"id":"0123456789abcdefghij", "nodes": "def456..."}}
|
||||
bencoded = d1:rd2:id20:0123456789abcdefghij5:nodes9:def456...e1:t2:aa1:y1:re
|
||||
*/
|
||||
|
||||
int bitdht_resp_node_msg(bdToken *tid, bdNodeId *id, std::list<bdId> &nodes,
|
||||
char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_resp_node_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
|
||||
be_node *replydict = be_create_dict();
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
|
||||
be_node *peersnode = makeCompactNodeIdString(nodes);
|
||||
|
||||
be_node *yqrnode = be_create_str("r");
|
||||
|
||||
be_add_keypair(replydict, "id", idnode);
|
||||
be_add_keypair(replydict, "nodes", peersnode);
|
||||
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", yqrnode);
|
||||
be_add_keypair(dict, "r", replydict);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
fprintf(stderr, "bitdht_resp_node_msg() len = %d / %d\n", blen, avail);
|
||||
#endif
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
get_peers Query = {"t":"aa", "y":"q", "q":"get_peers", "a": {"id":"abcdefghij0123456789", "info_hash":"mnopqrstuvwxyz123456"}}
|
||||
bencoded = d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe
|
||||
*/
|
||||
|
||||
int bitdht_get_peers_msg(bdToken *tid, bdNodeId *id, bdNodeId *info_hash,
|
||||
char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_get_peers_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
|
||||
be_node *iddict = be_create_dict();
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
be_node *hashnode = be_create_str_wlen((char *) info_hash->data, BITDHT_KEY_LEN);
|
||||
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
be_node *yqrnode = be_create_str("q");
|
||||
be_node *findnode = be_create_str("get_peers");
|
||||
|
||||
be_add_keypair(iddict, "id", idnode);
|
||||
be_add_keypair(iddict, "info_hash", hashnode);
|
||||
be_add_keypair(dict, "a", iddict);
|
||||
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", yqrnode);
|
||||
be_add_keypair(dict, "q", findnode);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Response with peers = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "values": ["axje.u", "idhtnm"]}}
|
||||
bencoded = d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:axje.u6:idhtnmee1:t2:aa1:y1:re
|
||||
*/
|
||||
|
||||
int bitdht_peers_reply_hash_msg(bdToken *tid, bdNodeId *id,
|
||||
bdToken *token, std::list<std::string> &values,
|
||||
char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_peers_reply_hash_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
|
||||
be_node *replydict = be_create_dict();
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
be_node *tokennode = be_create_str_wlen((char *) token->data, token->len);
|
||||
be_node *valuesnode = makeCompactPeerIds(values);
|
||||
|
||||
be_node *yqrnode = be_create_str("r");
|
||||
|
||||
be_add_keypair(replydict, "id", idnode);
|
||||
be_add_keypair(replydict, "token", tokennode);
|
||||
be_add_keypair(replydict, "values", valuesnode);
|
||||
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", yqrnode);
|
||||
be_add_keypair(dict, "r", replydict);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Response with closest nodes = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "nodes": "def456..."}}
|
||||
bencoded = d1:rd2:id20:abcdefghij01234567895:nodes9:def456...5:token8:aoeusnthe1:t2:aa1:y1:re
|
||||
|
||||
**/
|
||||
|
||||
|
||||
int bitdht_peers_reply_closest_msg(bdToken *tid, bdNodeId *id,
|
||||
bdToken *token, std::list<bdId> &nodes,
|
||||
char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_peers_reply_closest_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
|
||||
be_node *replydict = be_create_dict();
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
be_node *tokennode = be_create_str_wlen((char *) token->data, token->len);
|
||||
|
||||
be_node *peersnode = makeCompactNodeIdString(nodes);
|
||||
|
||||
be_node *yqrnode = be_create_str("r");
|
||||
|
||||
be_add_keypair(replydict, "id", idnode);
|
||||
be_add_keypair(replydict, "token", tokennode);
|
||||
be_add_keypair(replydict, "nodes", peersnode);
|
||||
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", yqrnode);
|
||||
be_add_keypair(dict, "r", replydict);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**** FINAL TWO MESSAGES! ***/
|
||||
|
||||
/****
|
||||
announce_peers Query = {"t":"aa", "y":"q", "q":"announce_peer", "a": {"id":"abcdefghij0123456789", "info_hash":"mnopqrstuvwxyz123456", "port": 6881, "token": "aoeusnth"}}
|
||||
bencoded = d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe
|
||||
|
||||
****/
|
||||
|
||||
int bitdht_announce_peers_msg(bdToken *tid, bdNodeId *id, bdNodeId *info_hash, uint32_t port, bdToken *token, char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_announce_peers_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
be_node *iddict = be_create_dict();
|
||||
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
|
||||
be_node *hashnode = be_create_str_wlen((char *) info_hash->data, BITDHT_KEY_LEN);
|
||||
be_node *portnode = be_create_int(port);
|
||||
be_node *tokennode = be_create_str_wlen((char *) token->data, token->len);
|
||||
|
||||
be_add_keypair(iddict, "id", idnode);
|
||||
be_add_keypair(iddict, "info_hash", hashnode);
|
||||
be_add_keypair(iddict, "port", portnode);
|
||||
be_add_keypair(iddict, "token", tokennode);
|
||||
|
||||
be_node *announcenode = be_create_str("announce_peer");
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
be_node *qynode = be_create_str("q");
|
||||
|
||||
be_add_keypair(dict, "a", iddict);
|
||||
|
||||
be_add_keypair(dict, "q", announcenode);
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", qynode);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
return blen;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*****
|
||||
Response to Announce Peers = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}}
|
||||
bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re
|
||||
****/
|
||||
|
||||
/****
|
||||
* NB: This is the same as a PONG msg!
|
||||
***/
|
||||
|
||||
int bitdht_reply_announce_msg(bdToken *tid, bdNodeId *id,
|
||||
char *msg, int avail)
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
fprintf(stderr, "bitdht_response_ping_msg()\n");
|
||||
#endif
|
||||
|
||||
be_node *dict = be_create_dict();
|
||||
|
||||
be_node *iddict = be_create_dict();
|
||||
be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN);
|
||||
|
||||
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
|
||||
be_node *yqrnode = be_create_str("r");
|
||||
|
||||
be_add_keypair(iddict, "id", idnode);
|
||||
be_add_keypair(dict, "r", iddict);
|
||||
|
||||
be_add_keypair(dict, "t", tidnode);
|
||||
be_add_keypair(dict, "y", yqrnode);
|
||||
|
||||
#ifdef DEBUG_MSG_DUMP
|
||||
/* dump answer */
|
||||
be_dump(dict);
|
||||
#endif
|
||||
|
||||
int blen = be_encode(dict, msg, avail);
|
||||
be_free(dict);
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************ Parsing Messages *********************
|
||||
*
|
||||
*/
|
||||
|
||||
be_node *beMsgGetDictNode(be_node *node, const char *key)
|
||||
{
|
||||
/* make sure its a dictionary */
|
||||
if (node->type != BE_DICT)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get dictionary entry 'y' */
|
||||
int i;
|
||||
for(i = 0; node->val.d[i].val; i++)
|
||||
{
|
||||
if (0 == strcmp(key, node->val.d[i].key))
|
||||
{
|
||||
return node->val.d[i].val;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int beMsgMatchString(be_node *n, const char *str, int len)
|
||||
{
|
||||
if (n->type != BE_STR)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (len != be_str_len(n))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
if (n->val.s[i] != str[i])
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint32_t beMsgGetY(be_node *n)
|
||||
{
|
||||
be_node *val = beMsgGetDictNode(n, "y");
|
||||
if (val->type != BE_STR)
|
||||
{
|
||||
return BE_Y_UNKNOWN;
|
||||
}
|
||||
|
||||
if (val->val.s[0] == 'q')
|
||||
{
|
||||
return BE_Y_Q;
|
||||
}
|
||||
else if (val->val.s[0] == 'r')
|
||||
{
|
||||
return BE_Y_R;
|
||||
}
|
||||
|
||||
return BE_Y_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t beMsgType(be_node *n)
|
||||
{
|
||||
/* check for
|
||||
* y: q or r
|
||||
*/
|
||||
uint32_t beY = beMsgGetY(n);
|
||||
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() beY: " << beY << std::endl;
|
||||
#endif
|
||||
|
||||
if (beY == BE_Y_UNKNOWN)
|
||||
{
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() UNKNOWN MSG TYPE" << std::endl;
|
||||
#endif
|
||||
|
||||
return BITDHT_MSG_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (beY == BE_Y_Q) /* query */
|
||||
{
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() QUERY MSG TYPE" << std::endl;
|
||||
#endif
|
||||
be_node *query = beMsgGetDictNode(n, "q");
|
||||
|
||||
if (beMsgMatchString(query, "ping", 4))
|
||||
{
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() QUERY:ping MSG TYPE" << std::endl;
|
||||
#endif
|
||||
return BITDHT_MSG_TYPE_PING;
|
||||
}
|
||||
else if (beMsgMatchString(query, "find_node", 9))
|
||||
{
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() QUERY:find_node MSG TYPE" << std::endl;
|
||||
#endif
|
||||
return BITDHT_MSG_TYPE_FIND_NODE;
|
||||
}
|
||||
else if (beMsgMatchString(query, "get_peers", 9))
|
||||
{
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() QUERY:get_peers MSG TYPE" << std::endl;
|
||||
#endif
|
||||
return BITDHT_MSG_TYPE_GET_HASH;
|
||||
}
|
||||
else if (beMsgMatchString(query, "announce_peer", 13))
|
||||
{
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() QUERY:announce_peer MSG TYPE" << std::endl;
|
||||
#endif
|
||||
return BITDHT_MSG_TYPE_POST_HASH;
|
||||
}
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() QUERY:UNKNOWN MSG TYPE, dumping dict" << std::endl;
|
||||
/* dump answer */
|
||||
be_dump(n);
|
||||
#endif
|
||||
return BITDHT_MSG_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (beY != BE_Y_R)
|
||||
{
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() UNKNOWN2 MSG TYPE" << std::endl;
|
||||
#endif
|
||||
return BITDHT_MSG_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MSG_TYPE
|
||||
std::cerr << "bsMsgType() REPLY MSG TYPE" << std::endl;
|
||||
#endif
|
||||
|
||||
/* otherwise a reply or - invalid
|
||||
pong {"id":"mnopqrstuvwxyz123456"}
|
||||
reply_neigh { "id":"0123456789abcdefghij", "nodes": "def456..."}}
|
||||
reply_hash { "id":"abcdefghij0123456789", "token":"aoeusnth", "values": ["axje.u", "idhtnm"]}}
|
||||
reply_near { "id":"abcdefghij0123456789", "token":"aoeusnth", "nodes": "def456..."}
|
||||
*/
|
||||
|
||||
be_node *reply = beMsgGetDictNode(n, "r");
|
||||
if (!reply)
|
||||
{
|
||||
return BITDHT_MSG_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
be_node *id = beMsgGetDictNode(reply, "id");
|
||||
be_node *token = beMsgGetDictNode(reply, "token");
|
||||
be_node *values = beMsgGetDictNode(reply, "values");
|
||||
be_node *nodes = beMsgGetDictNode(reply, "nodes");
|
||||
|
||||
if (!id)
|
||||
{
|
||||
return BITDHT_MSG_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (token && values)
|
||||
{
|
||||
/* reply hash */
|
||||
return BITDHT_MSG_TYPE_REPLY_HASH;
|
||||
}
|
||||
else if (token && nodes)
|
||||
{
|
||||
/* reply near */
|
||||
return BITDHT_MSG_TYPE_REPLY_NEAR;
|
||||
}
|
||||
else if (nodes)
|
||||
{
|
||||
/* reply neigh */
|
||||
return BITDHT_MSG_TYPE_REPLY_NODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pong */
|
||||
return BITDHT_MSG_TYPE_PONG;
|
||||
}
|
||||
/* TODO reply_post */
|
||||
//return BITDHT_MSG_TYPE_REPLY_POST;
|
||||
/* can't get here! */
|
||||
return BITDHT_MSG_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/* extract specific types here */
|
||||
|
||||
int beMsgGetToken(be_node *n, bdToken &token)
|
||||
{
|
||||
if (n->type != BE_STR)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int len = be_str_len(n);
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
token.data[i] = n->val.s[i];
|
||||
}
|
||||
token.len = len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int beMsgGetNodeId(be_node *n, bdNodeId &nodeId)
|
||||
{
|
||||
if (n->type != BE_STR)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int len = be_str_len(n);
|
||||
if (len != BITDHT_KEY_LEN)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
nodeId.data[i] = n->val.s[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
be_node *makeCompactNodeIdString(std::list<bdId> &nodes)
|
||||
{
|
||||
int len = BITDHT_COMPACTNODEID_LEN * nodes.size();
|
||||
std::string cni;
|
||||
std::list<bdId>::iterator it;
|
||||
for(it = nodes.begin(); it != nodes.end(); it++)
|
||||
{
|
||||
cni += encodeCompactNodeId(&(*it));
|
||||
}
|
||||
|
||||
|
||||
be_node *cninode = be_create_str_wlen((char *) cni.c_str(), len);
|
||||
return cninode;
|
||||
}
|
||||
|
||||
be_node *makeCompactPeerIds(std::list<std::string> &values)
|
||||
{
|
||||
be_node *valuesnode = be_create_list();
|
||||
std::list<std::string>::iterator it;
|
||||
for(it = values.begin(); it != values.end(); it++)
|
||||
{
|
||||
be_node *val1 = be_create_str_wlen((char *) it->c_str(), it->length());
|
||||
be_add_list(valuesnode, val1);
|
||||
}
|
||||
return valuesnode;
|
||||
}
|
||||
|
||||
|
||||
int beMsgGetListBdIds(be_node *n, std::list<bdId> &nodes)
|
||||
{
|
||||
/* extract the string pointer, and size */
|
||||
/* split into parts */
|
||||
|
||||
if (n->type != BE_STR)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int len = be_str_len(n);
|
||||
int count = len / BITDHT_COMPACTNODEID_LEN;
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
bdId id;
|
||||
if (decodeCompactNodeId(&id, &(n->val.s[i*BITDHT_COMPACTNODEID_LEN]), BITDHT_COMPACTNODEID_LEN))
|
||||
{
|
||||
nodes.push_back(id);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string encodeCompactNodeId(bdId *id)
|
||||
{
|
||||
std::string enc;
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
enc += id->id.data[i];
|
||||
}
|
||||
/* convert ip address (already in network order) */
|
||||
enc += encodeCompactPeerId(&(id->addr));
|
||||
return enc;
|
||||
}
|
||||
|
||||
int decodeCompactNodeId(bdId *id, char *enc, int len)
|
||||
{
|
||||
if (len < BITDHT_COMPACTNODEID_LEN)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
id->id.data[i] = enc[i];
|
||||
}
|
||||
|
||||
char *ipenc = &(enc[BITDHT_COMPACTNODEID_LEN - BITDHT_COMPACTPEERID_LEN]);
|
||||
if (!decodeCompactPeerId(&(id->addr), ipenc, BITDHT_COMPACTPEERID_LEN))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string encodeCompactPeerId(struct sockaddr_in *addr)
|
||||
{
|
||||
std::string encstr;
|
||||
char enc[BITDHT_COMPACTPEERID_LEN];
|
||||
uint32_t *ip = (uint32_t *) (enc);
|
||||
uint16_t *port = (uint16_t *) (&enc[4]);
|
||||
(*ip) = addr->sin_addr.s_addr;
|
||||
(*port) = addr->sin_port;
|
||||
|
||||
encstr.append(enc, BITDHT_COMPACTPEERID_LEN);
|
||||
return encstr;
|
||||
}
|
||||
|
||||
int decodeCompactPeerId(struct sockaddr_in *addr, char *enc, int len)
|
||||
{
|
||||
if (len < BITDHT_COMPACTPEERID_LEN)
|
||||
return 0;
|
||||
|
||||
memset(addr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
uint32_t *ip = (uint32_t *) (enc);
|
||||
uint16_t *port = (uint16_t *) (&enc[4]);
|
||||
addr->sin_addr.s_addr = (*ip);
|
||||
addr->sin_port = (*port);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int beMsgGetListStrings(be_node *n, std::list<std::string> &values)
|
||||
{
|
||||
if (n->type != BE_LIST)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for(int i = 0; n->val.l[i] != NULL; i++)
|
||||
{
|
||||
be_node *val = n->val.l[i];
|
||||
if (val->type != BE_STR)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int len = be_str_len(val);
|
||||
std::string str;
|
||||
str.append(val->val.s, len);
|
||||
values.push_back(str);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int beMsgGetUInt32(be_node *n, uint32_t *port)
|
||||
{
|
||||
if (n->type != BE_INT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*port = n->val.i;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
111
libbitdht/src/bitdht/bdmsgs.h
Normal file
111
libbitdht/src/bitdht/bdmsgs.h
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef BITDHT_MSGS_H
|
||||
#define BITDHT_MSGS_H
|
||||
|
||||
/*
|
||||
* bitdht/bdmsgs.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <list>
|
||||
#include "bencode.h"
|
||||
#include "bdobj.h"
|
||||
#include "bdpeer.h"
|
||||
|
||||
#define BITDHT_MSG_TYPE_UNKNOWN 0
|
||||
#define BITDHT_MSG_TYPE_PING 1
|
||||
#define BITDHT_MSG_TYPE_PONG 2
|
||||
#define BITDHT_MSG_TYPE_FIND_NODE 3
|
||||
#define BITDHT_MSG_TYPE_REPLY_NODE 4
|
||||
#define BITDHT_MSG_TYPE_GET_HASH 5
|
||||
#define BITDHT_MSG_TYPE_REPLY_HASH 6
|
||||
#define BITDHT_MSG_TYPE_REPLY_NEAR 7
|
||||
#define BITDHT_MSG_TYPE_POST_HASH 8
|
||||
#define BITDHT_MSG_TYPE_REPLY_POST 9
|
||||
|
||||
#define BITDHT_COMPACTNODEID_LEN 26
|
||||
#define BITDHT_COMPACTPEERID_LEN 6
|
||||
|
||||
#define BE_Y_UNKNOWN 0
|
||||
#define BE_Y_R 1
|
||||
#define BE_Y_Q 2
|
||||
|
||||
|
||||
/****** Known BD Version Strings ******/
|
||||
|
||||
#define BITDHT_VID_RS1 1
|
||||
#define BITDHT_VID_UT 2
|
||||
|
||||
|
||||
int bitdht_create_ping_msg(bdToken *tid, bdNodeId *id, char *msg, int avail);
|
||||
int bitdht_response_ping_msg(bdToken *tid, bdNodeId *id, bdToken *vid, char *msg, int avail);
|
||||
int bitdht_find_node_msg(bdToken *tid, bdNodeId *id, bdNodeId *target, char *msg, int avail);
|
||||
int bitdht_resp_node_msg(bdToken *tid, bdNodeId *id, std::list<bdId> &nodes,
|
||||
char *msg, int avail);
|
||||
int bitdht_get_peers_msg(bdToken *tid, bdNodeId *id, bdNodeId *info_hash,
|
||||
char *msg, int avail);
|
||||
int bitdht_peers_reply_hash_msg(bdToken *tid, bdNodeId *id,
|
||||
bdToken *token, std::list<std::string> &values,
|
||||
char *msg, int avail);
|
||||
int bitdht_peers_reply_closest_msg(bdToken *tid, bdNodeId *id,
|
||||
bdToken *token, std::list<bdId> &nodes,
|
||||
char *msg, int avail);
|
||||
int bitdht_announce_peers_msg(bdToken *tid, bdNodeId *id, bdNodeId *info_hash,
|
||||
uint32_t port, bdToken *token, char *msg, int avail);
|
||||
int bitdht_reply_announce_msg(bdToken *tid, bdNodeId *id,
|
||||
char *msg, int avail);
|
||||
|
||||
|
||||
//int response_peers_message()
|
||||
//int response_closestnodes_message()
|
||||
|
||||
be_node *beMsgGetDictNode(be_node *node, const char *key);
|
||||
int beMsgMatchString(be_node *n, const char *str, int len);
|
||||
uint32_t beMsgGetY(be_node *n);
|
||||
uint32_t beMsgType(be_node *n);
|
||||
|
||||
|
||||
uint32_t convertBdVersionToVID(bdVersion *version);
|
||||
|
||||
be_node *makeCompactPeerIds(std::list<std::string> &values);
|
||||
be_node *makeCompactNodeIdString(std::list<bdId> &nodes);
|
||||
|
||||
int beMsgGetToken(be_node *n, bdToken &token);
|
||||
int beMsgGetNodeId(be_node *n, bdNodeId &nodeId);
|
||||
int beMsgGetListBdIds(be_node *n, std::list<bdId> &nodes);
|
||||
|
||||
int beMsgGetListStrings(be_node *n, std::list<std::string> &values);
|
||||
int beMsgGetUInt32(be_node *n, uint32_t *port);
|
||||
|
||||
/* Low Level conversion functions */
|
||||
int decodeCompactPeerId(struct sockaddr_in *addr, char *enc, int len);
|
||||
std::string encodeCompactPeerId(struct sockaddr_in *addr);
|
||||
|
||||
int decodeCompactNodeId(bdId *id, char *enc, int len);
|
||||
std::string encodeCompactNodeId(bdId *id);
|
||||
|
||||
|
||||
|
||||
#endif
|
1561
libbitdht/src/bitdht/bdnode.cc
Normal file
1561
libbitdht/src/bitdht/bdnode.cc
Normal file
File diff suppressed because it is too large
Load Diff
235
libbitdht/src/bitdht/bdnode.h
Normal file
235
libbitdht/src/bitdht/bdnode.h
Normal file
@ -0,0 +1,235 @@
|
||||
#ifndef BITDHT_NODE_H
|
||||
#define BITDHT_NODE_H
|
||||
|
||||
/*
|
||||
* bitdht/bdnode.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdpeer.h"
|
||||
#include "bdquery.h"
|
||||
#include "bdstore.h"
|
||||
#include "bdobj.h"
|
||||
#include "bdhash.h"
|
||||
|
||||
|
||||
#define BD_QUERY_NEIGHBOURS 1
|
||||
#define BD_QUERY_HASH 2
|
||||
|
||||
/**********************************
|
||||
* Running a node....
|
||||
*
|
||||
* run().
|
||||
* loops through and checks out of date peers.
|
||||
* handles searches.
|
||||
* prints out dht Table.
|
||||
*
|
||||
|
||||
The node handles the i/o traffic from peers.
|
||||
It
|
||||
|
||||
|
||||
|
||||
ping, return
|
||||
peers, return
|
||||
hash store, return
|
||||
hash get, return
|
||||
|
||||
|
||||
|
||||
respond queue.
|
||||
|
||||
query queue.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
input -> call into recvFunction()
|
||||
output -> call back to Udp().
|
||||
|
||||
|
||||
|
||||
|
||||
*********/
|
||||
|
||||
class bdNodeNetMsg
|
||||
{
|
||||
|
||||
public:
|
||||
bdNodeNetMsg(char *data, int size, struct sockaddr_in *addr);
|
||||
~bdNodeNetMsg();
|
||||
|
||||
void print(std::ostream &out);
|
||||
|
||||
char *data;
|
||||
int mSize;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
};
|
||||
|
||||
class bdNode
|
||||
{
|
||||
public:
|
||||
|
||||
bdNode(bdNodeId *id, std::string dhtVersion, std::string bootfile,
|
||||
bdDhtFunctions *fns);
|
||||
|
||||
// virtual so manager can do callback.
|
||||
// peer flags defined in bdiface.h
|
||||
virtual void addPeer(const bdId *id, uint32_t peerflags);
|
||||
|
||||
void printState();
|
||||
void checkPotentialPeer(bdId *id);
|
||||
void addPotentialPeer(bdId *id);
|
||||
|
||||
void addQuery(const bdNodeId *id, uint32_t qflags);
|
||||
void clearQuery(const bdNodeId *id);
|
||||
void QueryStatus(std::map<bdNodeId, bdQueryStatus> &statusMap);
|
||||
|
||||
void iteration();
|
||||
void processRemoteQuery();
|
||||
void updateStore();
|
||||
|
||||
|
||||
/* interaction with outside world */
|
||||
int outgoingMsg(struct sockaddr_in *addr, char *msg, int *len);
|
||||
void incomingMsg(struct sockaddr_in *addr, char *msg, int len);
|
||||
|
||||
/* internal interaction with network */
|
||||
void sendPkt(char *msg, int len, struct sockaddr_in addr);
|
||||
void recvPkt(char *msg, int len, struct sockaddr_in addr);
|
||||
|
||||
|
||||
/* output functions (send msg) */
|
||||
void msgout_ping(bdId *id, bdToken *transId);
|
||||
void msgout_pong(bdId *id, bdToken *transId);
|
||||
void msgout_find_node(bdId *id, bdToken *transId, bdNodeId *query);
|
||||
void msgout_reply_find_node(bdId *id, bdToken *transId,
|
||||
std::list<bdId> &peers);
|
||||
void msgout_get_hash(bdId *id, bdToken *transId, bdNodeId *info_hash);
|
||||
void msgout_reply_hash(bdId *id, bdToken *transId,
|
||||
bdToken *token, std::list<std::string> &values);
|
||||
void msgout_reply_nearest(bdId *id, bdToken *transId,
|
||||
bdToken *token, std::list<bdId> &peers);
|
||||
|
||||
void msgout_post_hash(bdId *id, bdToken *transId, bdNodeId *info_hash,
|
||||
uint32_t port, bdToken *token);
|
||||
void msgout_reply_post(bdId *id, bdToken *transId);
|
||||
|
||||
|
||||
/* input functions (once mesg is parsed) */
|
||||
void msgin_ping(bdId *id, bdToken *token);
|
||||
void msgin_pong(bdId *id, bdToken *transId, bdToken *versionId);
|
||||
|
||||
void msgin_find_node(bdId *id, bdToken *transId, bdNodeId *query);
|
||||
void msgin_reply_find_node(bdId *id, bdToken *transId,
|
||||
std::list<bdId> &entries);
|
||||
|
||||
void msgin_get_hash(bdId *id, bdToken *transId, bdNodeId *nodeid);
|
||||
void msgin_reply_hash(bdId *id, bdToken *transId,
|
||||
bdToken *token, std::list<std::string> &values);
|
||||
void msgin_reply_nearest(bdId *id, bdToken *transId,
|
||||
bdToken *token, std::list<bdId> &nodes);
|
||||
|
||||
void msgin_post_hash(bdId *id, bdToken *transId,
|
||||
bdNodeId *info_hash, uint32_t port, bdToken *token);
|
||||
void msgin_reply_post(bdId *id, bdToken *transId);
|
||||
|
||||
|
||||
|
||||
/* token handling */
|
||||
void genNewToken(bdToken *token);
|
||||
int queueQuery(bdId *id, bdNodeId *query, bdToken *transId, uint32_t query_type);
|
||||
|
||||
/* transId handling */
|
||||
void genNewTransId(bdToken *token);
|
||||
void registerOutgoingMsg(bdId *id, bdToken *transId, uint32_t msgType);
|
||||
uint32_t checkIncomingMsg(bdId *id, bdToken *transId, uint32_t msgType);
|
||||
void cleanupTransIdRegister();
|
||||
|
||||
void getOwnId(bdNodeId *id);
|
||||
|
||||
void doStats();
|
||||
void printStats(std::ostream &out);
|
||||
void printQueries();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
bdNodeId mOwnId;
|
||||
bdId mLikelyOwnId; // Try to workout own id address.
|
||||
bdSpace mNodeSpace;
|
||||
bdStore mStore;
|
||||
std::string mDhtVersion;
|
||||
|
||||
bdDhtFunctions *mFns;
|
||||
|
||||
bdHashSpace mHashSpace;
|
||||
|
||||
std::list<bdQuery> mLocalQueries;
|
||||
std::list<bdRemoteQuery> mRemoteQueries;
|
||||
|
||||
std::list<bdId> mPotentialPeers;
|
||||
|
||||
std::list<bdNodeNetMsg *> mOutgoingMsgs;
|
||||
std::list<bdNodeNetMsg *> mIncomingMsgs;
|
||||
|
||||
// Statistics.
|
||||
double mCounterOutOfDatePing;
|
||||
double mCounterPings;
|
||||
double mCounterPongs;
|
||||
double mCounterQueryNode;
|
||||
double mCounterQueryHash;
|
||||
double mCounterReplyFindNode;
|
||||
double mCounterReplyQueryHash;
|
||||
|
||||
double mCounterRecvPing;
|
||||
double mCounterRecvPong;
|
||||
double mCounterRecvQueryNode;
|
||||
double mCounterRecvQueryHash;
|
||||
double mCounterRecvReplyFindNode;
|
||||
double mCounterRecvReplyQueryHash;
|
||||
|
||||
double mLpfOutOfDatePing;
|
||||
double mLpfPings;
|
||||
double mLpfPongs;
|
||||
double mLpfQueryNode;
|
||||
double mLpfQueryHash;
|
||||
double mLpfReplyFindNode;
|
||||
double mLpfReplyQueryHash;
|
||||
|
||||
double mLpfRecvPing;
|
||||
double mLpfRecvPong;
|
||||
double mLpfRecvQueryNode;
|
||||
double mLpfRecvQueryHash;
|
||||
double mLpfRecvReplyFindNode;
|
||||
double mLpfRecvReplyQueryHash;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BITDHT_NODE_H
|
51
libbitdht/src/bitdht/bdobj.cc
Normal file
51
libbitdht/src/bitdht/bdobj.cc
Normal file
@ -0,0 +1,51 @@
|
||||
#include "bdobj.h"
|
||||
|
||||
/*
|
||||
* bitdht/bdobj.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void bdPrintTransId(std::ostream &out, bdToken *transId)
|
||||
{
|
||||
out << transId->data;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void bdPrintToken(std::ostream &out, bdToken *token)
|
||||
{
|
||||
for(unsigned int i = 0; i < token->len; i++)
|
||||
{
|
||||
out << std::hex << (uint32_t) token->data[i];
|
||||
}
|
||||
out << std::dec;
|
||||
}
|
||||
|
||||
void bdPrintCompactPeerId(std::ostream &out, std::string cpi)
|
||||
{
|
||||
out << "DummyCompactPeerId";
|
||||
}
|
||||
|
||||
|
61
libbitdht/src/bitdht/bdobj.h
Normal file
61
libbitdht/src/bitdht/bdobj.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef BITDHT_OBJECTS_H
|
||||
#define BITDHT_OBJECTS_H
|
||||
|
||||
/*
|
||||
* bitdht/bdobj.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define BITDHT_TOKEN_MAX_LEN 20
|
||||
|
||||
#include <iostream>
|
||||
#include <inttypes.h>
|
||||
|
||||
class bdToken
|
||||
{
|
||||
public:
|
||||
uint32_t len;
|
||||
unsigned char data[BITDHT_TOKEN_MAX_LEN];
|
||||
};
|
||||
|
||||
class bdCompactIds
|
||||
{
|
||||
public:
|
||||
uint32_t len;
|
||||
unsigned char data[BITDHT_TOKEN_MAX_LEN];
|
||||
};
|
||||
|
||||
class bdVersion
|
||||
{
|
||||
public:
|
||||
uint32_t len;
|
||||
unsigned char data[BITDHT_TOKEN_MAX_LEN];
|
||||
};
|
||||
|
||||
void bdPrintTransId(std::ostream &out, bdToken *transId);
|
||||
void bdPrintToken(std::ostream &out, bdToken *transId);
|
||||
void bdPrintCompactPeerId(std::ostream &out, std::string cpi);
|
||||
|
||||
#endif
|
||||
|
739
libbitdht/src/bitdht/bdpeer.cc
Normal file
739
libbitdht/src/bitdht/bdpeer.cc
Normal file
@ -0,0 +1,739 @@
|
||||
/*
|
||||
* bitdht/bdpeer.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdpeer.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
/**
|
||||
* #define BITDHT_DEBUG 1
|
||||
**/
|
||||
|
||||
bdId::bdId()
|
||||
{
|
||||
/* blank everything */
|
||||
memset(&addr, 0, sizeof(struct sockaddr_in));
|
||||
memset(&id.data, 0, BITDHT_KEY_LEN);
|
||||
}
|
||||
|
||||
bdId::bdId(bdNodeId in_id, struct sockaddr_in in_addr)
|
||||
{
|
||||
addr = in_addr;
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
id.data[i] = in_id.data[i];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void bdZeroNodeId(bdNodeId *id)
|
||||
{
|
||||
uint32_t *a_data = (uint32_t *) id->data;
|
||||
for(int i = 0; i < BITDHT_KEY_INTLEN; i++)
|
||||
{
|
||||
a_data[i] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int operator<(const bdNodeId &a, const bdNodeId &b)
|
||||
{
|
||||
#if 0
|
||||
std::cerr << "operator<(");
|
||||
bdPrintNodeId(std::cerr, &a);
|
||||
std::cerr << ",";
|
||||
bdPrintNodeId(std::cerr, &b);
|
||||
std::cerr << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
uint8_t *a_data = (uint8_t *) a.data;
|
||||
uint8_t *b_data = (uint8_t *) b.data;
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
if (*a_data < *b_data)
|
||||
{
|
||||
//fprintf(stderr, "Return 1, at i = %d\n", i);
|
||||
return 1;
|
||||
}
|
||||
else if (*a_data > *b_data)
|
||||
{
|
||||
//fprintf(stderr, "Return 0, at i = %d\n", i);
|
||||
return 0;
|
||||
}
|
||||
a_data++;
|
||||
b_data++;
|
||||
}
|
||||
//fprintf(stderr, "Return 0, at i = KEYLEN\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int operator<(const struct sockaddr_in &a, const struct sockaddr_in &b)
|
||||
{
|
||||
/* else NodeIds the same - check id addresses */
|
||||
if (a.sin_addr.s_addr < b.sin_addr.s_addr)
|
||||
return 1;
|
||||
if (b.sin_addr.s_addr > a.sin_addr.s_addr)
|
||||
return 0;
|
||||
|
||||
if (a.sin_port < b.sin_port)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int operator<(const bdId &a, const bdId &b)
|
||||
{
|
||||
if (a.id < b.id)
|
||||
return 1;
|
||||
if (b.id < a.id)
|
||||
return 0;
|
||||
|
||||
/* else NodeIds the same - check id addresses */
|
||||
if (a.addr.sin_addr.s_addr < b.addr.sin_addr.s_addr)
|
||||
return 1;
|
||||
if (b.addr.sin_addr.s_addr > a.addr.sin_addr.s_addr)
|
||||
return 0;
|
||||
|
||||
if (a.addr.sin_port < b.addr.sin_port)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int operator==(const bdNodeId &a, const bdNodeId &b)
|
||||
{
|
||||
uint8_t *a_data = (uint8_t *) a.data;
|
||||
uint8_t *b_data = (uint8_t *) b.data;
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
if (*a_data < *b_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (*a_data > *b_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
a_data++;
|
||||
b_data++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int operator==(const bdId &a, const bdId &b)
|
||||
{
|
||||
if (a.id == b.id)
|
||||
return 1;
|
||||
|
||||
if ((a.addr.sin_addr.s_addr == b.addr.sin_addr.s_addr) &&
|
||||
(a.addr.sin_port == b.addr.sin_port))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void bdRandomId(bdId *id)
|
||||
{
|
||||
bdRandomNodeId(&(id->id));
|
||||
|
||||
id->addr.sin_addr.s_addr = rand();
|
||||
id->addr.sin_port = rand();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void bdRandomNodeId(bdNodeId *id)
|
||||
{
|
||||
uint32_t *a_data = (uint32_t *) id->data;
|
||||
for(int i = 0; i < BITDHT_KEY_INTLEN; i++)
|
||||
{
|
||||
a_data[i] = rand();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* fills in dbNodeId r, with XOR of a and b */
|
||||
int bdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r)
|
||||
{
|
||||
uint8_t *a_data = (uint8_t *) a->data;
|
||||
uint8_t *b_data = (uint8_t *) b->data;
|
||||
uint8_t *ans = (uint8_t *) r->data;
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
*(ans++) = *(a_data++) ^ *(b_data++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *midId)
|
||||
{
|
||||
bdMetric dist;
|
||||
|
||||
/* get distance between a & c */
|
||||
bdDistance(target, other, &dist);
|
||||
|
||||
/* generate Random Id */
|
||||
bdRandomNodeId(midId);
|
||||
|
||||
/* zero bits of Random Id until under 1/2 of distance
|
||||
* done in bytes for ease... matches one extra byte than distance = 0
|
||||
* -> hence wierd order of operations
|
||||
*/
|
||||
bool done = false;
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
midId->data[i] = target->data[i];
|
||||
|
||||
if (dist.data[i] != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string bdConvertToPrintable(std::string input)
|
||||
{
|
||||
std::ostringstream out;
|
||||
for(uint32_t i = 0; i < input.length(); i++)
|
||||
{
|
||||
/* sensible chars */
|
||||
if ((input[i] > 31) && (input[i] < 127))
|
||||
{
|
||||
out << input[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "[0x" << std::hex << (uint32_t) input[i] << "]";
|
||||
out << std::dec;
|
||||
}
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void bdPrintNodeId(std::ostream &out, const bdNodeId *a)
|
||||
{
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
out << std::setw(2) << std::setfill('0') << std::hex << (uint32_t) (a->data)[i];
|
||||
}
|
||||
out << std::dec;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void bdPrintId(std::ostream &out, const bdId *a)
|
||||
{
|
||||
bdPrintNodeId(out, &(a->id));
|
||||
out << " ip:" << inet_ntoa(a->addr.sin_addr);
|
||||
out << ":" << ntohs(a->addr.sin_port);
|
||||
return;
|
||||
}
|
||||
|
||||
/* returns 0-160 depending on bucket */
|
||||
int bdBucketDistance(const bdNodeId *a, const bdNodeId *b)
|
||||
{
|
||||
bdMetric m;
|
||||
bdDistance(a, b, &m);
|
||||
return bdBucketDistance(&m);
|
||||
}
|
||||
|
||||
/* returns 0-160 depending on bucket */
|
||||
int bdBucketDistance(const bdMetric *m)
|
||||
{
|
||||
for(int i = 0; i < BITDHT_KEY_BITLEN; i++)
|
||||
{
|
||||
int bit = BITDHT_KEY_BITLEN - i - 1;
|
||||
int byte = i / 8;
|
||||
int bbit = 7 - (i % 8);
|
||||
unsigned char comp = (1 << bbit);
|
||||
|
||||
#ifdef BITDHT_DEBUG
|
||||
fprintf(stderr, "bdBucketDistance: bit:%d byte:%d bbit:%d comp:%x, data:%x\n", bit, byte, bbit, comp, m->data[byte]);
|
||||
#endif
|
||||
|
||||
if (comp & m->data[byte])
|
||||
{
|
||||
return bit;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
bdBucket::bdBucket()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bdSpace::bdSpace(bdNodeId *ownId, bdDhtFunctions *fns)
|
||||
:mOwnId(*ownId), mFns(fns)
|
||||
{
|
||||
/* make some space for data */
|
||||
buckets.resize(mFns->bdNumBuckets());
|
||||
return;
|
||||
}
|
||||
|
||||
int bdSpace::find_nearest_nodes(const bdNodeId *id, int number, std::list<bdId> excluding, std::multimap<bdMetric, bdId> &nearest)
|
||||
{
|
||||
std::multimap<bdMetric, bdId> closest;
|
||||
std::multimap<bdMetric, bdId>::iterator mit;
|
||||
|
||||
bdMetric dist;
|
||||
mFns->bdDistance(id, &(mOwnId), &dist);
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
int bucket = mFns->bdBucketDistance(&dist);
|
||||
|
||||
std::cerr << "bdSpace::find_nearest_nodes(NodeId:";
|
||||
mFns->bdPrintNodeId(std::cerr, id);
|
||||
|
||||
std::cerr << " Number: " << number;
|
||||
std::cerr << " Query Bucket #: " << bucket;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::vector<bdBucket>::iterator it;
|
||||
std::list<bdPeer>::iterator eit;
|
||||
/* iterate through the buckets, and sort by distance */
|
||||
for(it = buckets.begin(); it != buckets.end(); it++)
|
||||
{
|
||||
for(eit = it->entries.begin(); eit != it->entries.end(); eit++)
|
||||
{
|
||||
mFns->bdDistance(id, &(eit->mPeerId.id), &dist);
|
||||
closest.insert(std::pair<bdMetric, bdId>(dist, eit->mPeerId));
|
||||
|
||||
#if 0
|
||||
std::cerr << "Added NodeId: ";
|
||||
bdPrintNodeId(std::cerr, &(eit->mPeerId.id));
|
||||
std::cerr << " Metric: ";
|
||||
bdPrintNodeId(std::cerr, &(dist));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* take the first number of nodes */
|
||||
int i = 0;
|
||||
for(mit = closest.begin(); (mit != closest.end()) && (i < number); mit++, i++)
|
||||
{
|
||||
mFns->bdDistance(&(mOwnId), &(mit->second.id), &dist);
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
int iBucket = mFns->bdBucketDistance(&(mit->first));
|
||||
|
||||
std::cerr << "Closest " << i << ": ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(mit->second.id));
|
||||
std::cerr << " Bucket: " << iBucket;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
std::cerr << "\tNodeId: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(mit->second.id));
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << "\tOwn Id: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(mOwnId));
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << " Us Metric: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &dist);
|
||||
std::cerr << " Bucket: " << oBucket;
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << "\tFindId: ";
|
||||
mFns->bdPrintNodeId(std::cerr, id);
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << " Id Metric: ";
|
||||
mFns->bdPrintNodeId(std::cerr, &(mit->first));
|
||||
std::cerr << " Bucket: " << iBucket;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
nearest.insert(*mit);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
std::cerr << "#Nearest: " << (int) nearest.size();
|
||||
std::cerr << " #Closest: " << (int) closest.size();
|
||||
std::cerr << " #Requested: " << number;
|
||||
std::cerr << std::endl << std::endl;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int bdSpace::out_of_date_peer(bdId &id)
|
||||
{
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
std::map<bdMetric, bdId> closest;
|
||||
std::map<bdMetric, bdId>::iterator mit;
|
||||
|
||||
std::vector<bdBucket>::iterator it;
|
||||
std::list<bdPeer>::iterator eit;
|
||||
time_t ts = time(NULL);
|
||||
|
||||
/* iterate through the buckets, and sort by distance */
|
||||
for(it = buckets.begin(); it != buckets.end(); it++)
|
||||
{
|
||||
for(eit = it->entries.begin(); eit != it->entries.end(); eit++)
|
||||
{
|
||||
/* timeout on last send time! */
|
||||
if (ts - eit->mLastSendTime > BITDHT_MAX_SEND_PERIOD )
|
||||
{
|
||||
id = eit->mPeerId;
|
||||
eit->mLastSendTime = ts;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called to add or update peer.
|
||||
* sorts bucket lists by lastRecvTime.
|
||||
* updates requested node.
|
||||
*/
|
||||
|
||||
/* peer flags
|
||||
* order is important!
|
||||
* higher bits = more priority.
|
||||
* BITDHT_PEER_STATUS_RECVPONG
|
||||
* BITDHT_PEER_STATUS_RECVNODES
|
||||
* BITDHT_PEER_STATUS_RECVHASHES
|
||||
* BITDHT_PEER_STATUS_DHT_ENGINE (dbXXxx)
|
||||
* BITDHT_PEER_STATUS_DHT_APPL (XXRSxx)
|
||||
* BITDHT_PEER_STATUS_DHT_VERSION (XXxx50)
|
||||
*
|
||||
*/
|
||||
|
||||
int bdSpace::add_peer(const bdId *id, uint32_t peerflags)
|
||||
{
|
||||
/* find the peer */
|
||||
bool add = false;
|
||||
time_t ts = time(NULL);
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
fprintf(stderr, "bdSpace::add_peer()\n");
|
||||
#endif
|
||||
|
||||
/* calculate metric */
|
||||
bdMetric met;
|
||||
mFns->bdDistance(&(mOwnId), &(id->id), &met);
|
||||
int bucket = mFns->bdBucketDistance(&met);
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
fprintf(stderr, "peer:");
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
fprintf(stderr, " bucket: %d", bucket);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
/* select correct bucket */
|
||||
bdBucket &buck = buckets[bucket];
|
||||
|
||||
|
||||
std::list<bdPeer>::iterator it;
|
||||
|
||||
/* calculate the score for this new peer */
|
||||
uint32_t minScore = peerflags;
|
||||
|
||||
/* loop through ids, to find it */
|
||||
for(it = buck.entries.begin(); it != buck.entries.end(); it++)
|
||||
{
|
||||
if (*id == it->mPeerId)
|
||||
// should check addr too!
|
||||
{
|
||||
bdPeer peer = *it;
|
||||
it = buck.entries.erase(it);
|
||||
|
||||
peer.mLastRecvTime = ts;
|
||||
peer.mPeerFlags |= peerflags; /* must be cumulative ... so can do online, replynodes, etc */
|
||||
|
||||
buck.entries.push_back(peer);
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
std::cerr << "Peer already in bucket: moving to back of the list" << std::endl;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* find lowest score */
|
||||
if (it->mPeerFlags < minScore)
|
||||
{
|
||||
minScore = it->mPeerFlags;
|
||||
}
|
||||
}
|
||||
|
||||
/* not in the list! */
|
||||
|
||||
if (buck.entries.size() < mFns->bdNodesPerBucket())
|
||||
{
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
std::cerr << "Bucket not full: allowing add" << std::endl;
|
||||
#endif
|
||||
add = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check head of list */
|
||||
bdPeer &peer = buck.entries.front();
|
||||
if (peer.mLastRecvTime - ts > BITDHT_MAX_RECV_PERIOD)
|
||||
{
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
std::cerr << "Dropping Out-of-Date peer in bucket" << std::endl;
|
||||
#endif
|
||||
buck.entries.pop_front();
|
||||
add = true;
|
||||
}
|
||||
else if (peerflags > minScore)
|
||||
{
|
||||
/* find one to drop */
|
||||
for(it = buck.entries.begin(); it != buck.entries.end(); it++)
|
||||
{
|
||||
if (it->mPeerFlags == minScore)
|
||||
{
|
||||
/* delete low priority peer */
|
||||
it = buck.entries.erase(it);
|
||||
add = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
std::cerr << "Inserting due to Priority: minScore: " << minScore
|
||||
<< " new Peer Score: " << peerscore << << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
std::cerr << "No Out-Of-Date peers in bucket... dropping new entry" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
bdPeer newPeer;
|
||||
|
||||
newPeer.mPeerId = *id;
|
||||
newPeer.mLastRecvTime = ts;
|
||||
newPeer.mLastSendTime = ts; //????
|
||||
newPeer.mPeerFlags = peerflags;
|
||||
|
||||
buck.entries.push_back(newPeer);
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
#endif
|
||||
/* useful debug */
|
||||
std::cerr << "bdSpace::add_peer() Added Bucket[";
|
||||
std::cerr << bucket << "] Entry: ";
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
return add;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* print tables.
|
||||
*/
|
||||
|
||||
int bdSpace::printDHT()
|
||||
{
|
||||
std::map<bdMetric, bdId> closest;
|
||||
std::map<bdMetric, bdId>::iterator mit;
|
||||
|
||||
std::vector<bdBucket>::iterator it;
|
||||
std::list<bdPeer>::iterator eit;
|
||||
|
||||
fprintf(stderr, "bdSpace::printDHT()\n");
|
||||
/* iterate through the buckets, and sort by distance */
|
||||
int i = 0;
|
||||
for(it = buckets.begin(); it != buckets.end(); it++, i++)
|
||||
{
|
||||
if (it->entries.size() > 0)
|
||||
{
|
||||
fprintf(stderr, "Bucket %d ----------------------------\n", i);
|
||||
}
|
||||
|
||||
for(eit = it->entries.begin(); eit != it->entries.end(); eit++)
|
||||
{
|
||||
bdMetric dist;
|
||||
mFns->bdDistance(&(mOwnId), &(eit->mPeerId.id), &dist);
|
||||
|
||||
fprintf(stderr, " Metric: ");
|
||||
mFns->bdPrintNodeId(std::cerr, &(dist));
|
||||
fprintf(stderr, " Id: ");
|
||||
mFns->bdPrintId(std::cerr, &(eit->mPeerId));
|
||||
fprintf(stderr, " PeerFlags: %08x", eit->mPeerFlags);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "--------------------------------------\n");
|
||||
fprintf(stderr, "Summary ------------------------------\n");
|
||||
|
||||
/* little summary */
|
||||
unsigned long long sum = 0;
|
||||
unsigned long long no_peers = 0;
|
||||
uint32_t count = 0;
|
||||
bool doPrint = false;
|
||||
bool doAvg = false;
|
||||
|
||||
i = 0;
|
||||
for(it = buckets.begin(); it != buckets.end(); it++, i++)
|
||||
{
|
||||
int size = it->entries.size();
|
||||
int shift = BITDHT_KEY_BITLEN - i;
|
||||
bool toBig = false;
|
||||
|
||||
if (shift > BITDHT_ULLONG_BITS - mFns->bdBucketBitSize() - 1)
|
||||
{
|
||||
toBig = true;
|
||||
shift = BITDHT_ULLONG_BITS - mFns->bdBucketBitSize() - 1;
|
||||
}
|
||||
unsigned long long no_nets = ((unsigned long long) 1 << shift);
|
||||
|
||||
/* use doPrint so it acts as a single switch */
|
||||
if (size && !doAvg && !doPrint)
|
||||
{
|
||||
doAvg = true;
|
||||
}
|
||||
|
||||
if (size && !doPrint)
|
||||
{
|
||||
doPrint = true;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
/* reset counters - if empty slot - to discount outliers in average */
|
||||
sum = 0;
|
||||
no_peers = 0;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
if (doPrint)
|
||||
{
|
||||
if (size)
|
||||
fprintf(stderr, "Bucket %d: %d peers: ", i, size);
|
||||
#ifdef BITDHT_DEBUG
|
||||
else
|
||||
fprintf(stderr, "Bucket %d: %d peers: ", i, size);
|
||||
#endif
|
||||
}
|
||||
if (toBig)
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
if (doPrint)
|
||||
fprintf(stderr, "Estimated NetSize >> %llu\n", no_nets);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BITDHT_DEBUG
|
||||
if (doPrint)
|
||||
fprintf(stderr, " Bucket = Net / >> %llu\n", no_nets);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
no_peers = no_nets * size;
|
||||
if (size)
|
||||
{
|
||||
if (doPrint)
|
||||
fprintf(stderr, "Estimated NetSize = %llu\n", no_peers);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifdef BITDHT_DEBUG
|
||||
if (doPrint)
|
||||
fprintf(stderr, " Bucket = Net / %llu\n", no_nets);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
if (doPrint && doAvg && !toBig)
|
||||
{
|
||||
if (size == mFns->bdNodesPerBucket())
|
||||
{
|
||||
/* last average */
|
||||
doAvg = false;
|
||||
}
|
||||
if (no_peers != 0)
|
||||
{
|
||||
sum += no_peers;
|
||||
count++;
|
||||
#ifdef BITDHT_DEBUG
|
||||
fprintf(stderr, "Est: %d: %llu => %llu / %d\n",
|
||||
i, no_peers, sum, count);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
fprintf(stderr, "Zero Network Size (count = 0)\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Estimated Network Size = (%llu / %d) = %llu\n", sum, count, sum / count);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
171
libbitdht/src/bitdht/bdpeer.h
Normal file
171
libbitdht/src/bitdht/bdpeer.h
Normal file
@ -0,0 +1,171 @@
|
||||
#ifndef BITDHT_PEER_H
|
||||
#define BITDHT_PEER_H
|
||||
|
||||
/*
|
||||
* bitdht/bdpeer.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdiface.h"
|
||||
|
||||
/*******
|
||||
* These type of parameters are now DHT Function dependent
|
||||
*
|
||||
#define BITDHT_BUCKET_SIZE 20
|
||||
#define BITDHT_BUCKET_SIZE_BITS 5
|
||||
|
||||
#define BITDHT_N_BUCKETS BITDHT_KEY_BITLEN
|
||||
*
|
||||
*
|
||||
***/
|
||||
|
||||
/***
|
||||
* DEFINED in bdiface.h
|
||||
* #define BITDHT_KEY_LEN 20
|
||||
* #define BITDHT_KEY_INTLEN 5
|
||||
* #define BITDHT_KEY_BITLEN 160
|
||||
***/
|
||||
|
||||
#define BITDHT_ULLONG_BITS 64
|
||||
|
||||
#define BITDHT_MAX_SEND_PERIOD 600 // retry every 10 secs.
|
||||
#define BITDHT_MAX_RECV_PERIOD 1500 // out-of-date
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
/****
|
||||
* DEFINED in bdiface.h
|
||||
*
|
||||
* class bdNodeId
|
||||
* {
|
||||
* public:
|
||||
* unsigned char data[BITDHT_KEY_LEN];
|
||||
* };
|
||||
****/
|
||||
|
||||
|
||||
/****
|
||||
* DEFINED in bdiface.h
|
||||
*
|
||||
|
||||
class bdMetric: public bdNodeId {};
|
||||
|
||||
class bdId
|
||||
{
|
||||
public:
|
||||
|
||||
bdId();
|
||||
bdId(bdNodeId in_id, struct sockaddr_in in_addr);
|
||||
|
||||
struct sockaddr_in addr;
|
||||
bdNodeId id;
|
||||
};
|
||||
*
|
||||
*********/
|
||||
|
||||
|
||||
|
||||
//void bdRandomNodeId(bdNodeId *id);
|
||||
|
||||
// Only Functions that are common for all Dhts.
|
||||
// zero, basic comparisons..
|
||||
void bdZeroNodeId(bdNodeId *id);
|
||||
|
||||
//void bdRandomId(bdId *id);
|
||||
//int bdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r);
|
||||
//int bdBucketDistance(const bdMetric *m);
|
||||
//int bdBucketDistance(const bdNodeId *a, const bdNodeId *b);
|
||||
//int operator<(const bdMetric &a, const bdMetric &b);
|
||||
|
||||
//int operator<(const struct sockaddr_in &a, const struct sockaddr_in &b);
|
||||
|
||||
int operator<(const bdNodeId &a, const bdNodeId &b);
|
||||
int operator<(const bdId &a, const bdId &b);
|
||||
int operator==(const bdNodeId &a, const bdNodeId &b);
|
||||
int operator==(const bdId &a, const bdId &b);
|
||||
|
||||
//void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid);
|
||||
|
||||
//void bdPrintId(std::ostream &out, const bdId *a);
|
||||
//void bdPrintNodeId(std::ostream &out, const bdNodeId *a);
|
||||
|
||||
//std::string bdConvertToPrintable(std::string input);
|
||||
|
||||
class bdPeer
|
||||
{
|
||||
public:
|
||||
|
||||
bdId mPeerId;
|
||||
uint32_t mPeerFlags;
|
||||
time_t mLastSendTime;
|
||||
time_t mLastRecvTime;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class bdBucket
|
||||
{
|
||||
public:
|
||||
|
||||
bdBucket();
|
||||
|
||||
/* list so we can queue properly */
|
||||
std::list<bdPeer> entries;
|
||||
};
|
||||
|
||||
class bdSpace
|
||||
{
|
||||
public:
|
||||
|
||||
bdSpace(bdNodeId *ownId, bdDhtFunctions *fns);
|
||||
|
||||
/* accessors */
|
||||
int find_nearest_nodes(const bdNodeId *id, int number,
|
||||
std::list<bdId> excluding, std::multimap<bdMetric, bdId> &nearest);
|
||||
|
||||
int out_of_date_peer(bdId &id); // side-effect updates, send flag on peer.
|
||||
int add_peer(const bdId *id, uint32_t mode);
|
||||
int printDHT();
|
||||
|
||||
/* to add later */
|
||||
int updateOwnId(bdNodeId *newOwnId);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<bdBucket> buckets;
|
||||
bdNodeId mOwnId;
|
||||
bdDhtFunctions *mFns;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
577
libbitdht/src/bitdht/bdquery.cc
Normal file
577
libbitdht/src/bitdht/bdquery.cc
Normal file
@ -0,0 +1,577 @@
|
||||
|
||||
/*
|
||||
* bitdht/bdquery.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdquery.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* #define DEBUG_QUERY 1
|
||||
**/
|
||||
|
||||
//#define DEBUG_QUERY 1
|
||||
|
||||
#define EXPECTED_REPLY 10
|
||||
#define QUERY_IDLE_RETRY_PEER_PERIOD (mFns->bdNodesPerBucket() * 15)
|
||||
|
||||
|
||||
/************************************************************
|
||||
* bdQuery logic:
|
||||
* 1) as replies come in ... maintain list of M closest peers to ID.
|
||||
* 2) select non-queried peer from list, and query.
|
||||
* 3) halt when we have asked all M closest peers about the ID.
|
||||
*
|
||||
* Flags can be set to disguise the target of the search.
|
||||
* This involves
|
||||
*/
|
||||
|
||||
bdQuery::bdQuery(const bdNodeId *id, std::list<bdId> &startList, uint32_t queryFlags, bdDhtFunctions *fns)
|
||||
{
|
||||
/* */
|
||||
mId = *id;
|
||||
mFns = fns;
|
||||
|
||||
std::list<bdId>::iterator it;
|
||||
for(it = startList.begin(); it != startList.end(); it++)
|
||||
{
|
||||
bdPeer peer;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = 0;
|
||||
peer.mPeerId = *it;
|
||||
|
||||
bdMetric dist;
|
||||
|
||||
mFns->bdDistance(&mId, &(peer.mPeerId.id), &dist);
|
||||
|
||||
mClosest.insert(std::pair<bdMetric, bdPeer>(dist, peer));
|
||||
|
||||
|
||||
}
|
||||
|
||||
mState = BITDHT_QUERY_QUERYING;
|
||||
mQueryFlags = queryFlags;
|
||||
mQueryTS = time(NULL);
|
||||
|
||||
/* setup the limit of the search
|
||||
* by default it is setup to 000000 = exact match
|
||||
*/
|
||||
bdZeroNodeId(&mLimit);
|
||||
}
|
||||
|
||||
bool bdQuery::result(std::list<bdId> &answer)
|
||||
{
|
||||
/* get all the matches to our query */
|
||||
std::multimap<bdMetric, bdPeer>::iterator sit, eit;
|
||||
sit = mClosest.begin();
|
||||
eit = mClosest.upper_bound(mLimit);
|
||||
int i = 0;
|
||||
for(; sit != eit; sit++, i++)
|
||||
{
|
||||
answer.push_back(sit->second.mPeerId);
|
||||
}
|
||||
return (i > 0);
|
||||
}
|
||||
|
||||
|
||||
int bdQuery::nextQuery(bdId &id, bdNodeId &targetNodeId)
|
||||
{
|
||||
if ((mState != BITDHT_QUERY_QUERYING) && !(mQueryFlags & BITDHT_QFLAGS_DO_IDLE))
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() Query is done\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* search through through list, find closest not queried */
|
||||
time_t now = time(NULL);
|
||||
bool notFinished = false;
|
||||
std::multimap<bdMetric, bdPeer>::iterator it;
|
||||
for(it = mClosest.begin(); it != mClosest.end(); it++)
|
||||
{
|
||||
bool queryPeer = false;
|
||||
|
||||
/* if never queried */
|
||||
if (it->second.mLastSendTime == 0)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() Found non-sent peer. queryPeer = true : ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
queryPeer = true;
|
||||
}
|
||||
|
||||
/* re-request every so often */
|
||||
if ((mQueryFlags & BITDHT_QFLAGS_DO_IDLE) && (now - it->second.mLastSendTime > QUERY_IDLE_RETRY_PEER_PERIOD))
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() Found out-of-date. queryPeer = true : ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
queryPeer = true;
|
||||
}
|
||||
|
||||
/* expecting every peer to be up-to-date is too hard...
|
||||
* enough just to have received lists from each
|
||||
* - replacement policy will still work.
|
||||
*/
|
||||
if (it->second.mLastRecvTime == 0)
|
||||
//if (it->second.mLastRecvTime < it->second.mLastSendTime)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() Never Received: notFinished = true: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
notFinished = true;
|
||||
}
|
||||
|
||||
if (queryPeer)
|
||||
{
|
||||
id = it->second.mPeerId;
|
||||
it->second.mLastSendTime = now;
|
||||
|
||||
if (mQueryFlags & BITDHT_QFLAGS_DISGUISE)
|
||||
{
|
||||
/* calc Id mid point between Target and Peer */
|
||||
bdNodeId midRndId;
|
||||
mFns->bdRandomMidId(&mId, &(id.id), &midRndId);
|
||||
|
||||
targetNodeId = midRndId;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetNodeId = mId;
|
||||
}
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() Querying Peer: ");
|
||||
mFns->bdPrintId(std::cerr, &id);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* allow query to run for a minimal amount of time
|
||||
* This is important as startup - when we might not have any peers.
|
||||
* Probably should be handled elsewhere.
|
||||
*/
|
||||
time_t age = now - mQueryTS;
|
||||
|
||||
if (age < BITDHT_MIN_QUERY_AGE)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() under Min Time: Query not finished / No Query\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (age > BITDHT_MAX_QUERY_AGE)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() under Min Time: Query not finished / No Query\n");
|
||||
#endif
|
||||
/* fall through and stop */
|
||||
}
|
||||
else if ((mClosest.size() < mFns->bdNodesPerBucket()) || (notFinished))
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() notFinished | !size(): Query not finished / No Query\n");
|
||||
#endif
|
||||
/* not full yet... */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "NextQuery() Finished\n");
|
||||
#endif
|
||||
|
||||
/* if we get here - query finished */
|
||||
|
||||
/* check if we found the node */
|
||||
if (mClosest.size() > 0)
|
||||
{
|
||||
if ((mClosest.begin()->second).mPeerId.id == mId)
|
||||
{
|
||||
mState = BITDHT_QUERY_SUCCESS;
|
||||
}
|
||||
else if ((mPotentialClosest.begin()->second).mPeerId.id == mId)
|
||||
{
|
||||
mState = BITDHT_QUERY_PEER_UNREACHABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mState = BITDHT_QUERY_FOUND_CLOSEST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mState = BITDHT_QUERY_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int bdQuery::addPeer(const bdId *id, uint32_t mode)
|
||||
{
|
||||
bdMetric dist;
|
||||
time_t ts = time(NULL);
|
||||
|
||||
mFns->bdDistance(&mId, &(id->id), &dist);
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "bdQuery::addPeer(");
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
fprintf(stderr, ", %u)\n", mode);
|
||||
#endif
|
||||
|
||||
std::multimap<bdMetric, bdPeer>::iterator it, sit, eit;
|
||||
sit = mClosest.lower_bound(dist);
|
||||
eit = mClosest.upper_bound(dist);
|
||||
int i = 0;
|
||||
int actualCloser = 0;
|
||||
int toDrop = 0;
|
||||
for(it = mClosest.begin(); it != sit; it++, i++, actualCloser++)
|
||||
{
|
||||
time_t sendts = ts - it->second.mLastSendTime;
|
||||
bool hasSent = (it->second.mLastSendTime != 0);
|
||||
//bool hasReply = (it->second.mLastRecvTime != 0);
|
||||
bool hasReply = (it->second.mLastRecvTime >= it->second.mLastSendTime);
|
||||
if ((hasSent) && (!hasReply) && (sendts > EXPECTED_REPLY))
|
||||
{
|
||||
i--; /* dont count this one */
|
||||
toDrop++;
|
||||
}
|
||||
}
|
||||
// Counts where we are.
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Searching.... %di = %d - %d peers closer than this one\n", i, actualCloser, toDrop);
|
||||
#endif
|
||||
|
||||
if (i > mFns->bdNodesPerBucket() - 1)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Distance to far... dropping\n");
|
||||
#endif
|
||||
/* drop it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(it = sit; it != eit; it++, i++)
|
||||
{
|
||||
/* full id check */
|
||||
if (it->second.mPeerId == *id)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer Already here!\n");
|
||||
#endif
|
||||
if (mode & BITDHT_PEER_STATUS_RECV_NODES)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Updating LastRecvTime\n");
|
||||
#endif
|
||||
it->second.mLastRecvTime = ts;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer not in Query\n");
|
||||
#endif
|
||||
/* firstly drop unresponded (bit ugly - but hard structure to extract from) */
|
||||
int j;
|
||||
for(j = 0; j < toDrop; j++)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Dropping Peer that dont reply\n");
|
||||
#endif
|
||||
bool removed = false;
|
||||
for(it = mClosest.begin(); (!removed) && (it != mClosest.end()); it++)
|
||||
{
|
||||
time_t sendts = ts - it->second.mLastSendTime;
|
||||
bool hasSent = (it->second.mLastSendTime != 0);
|
||||
//bool hasReply = (it->second.mLastRecvTime != 0);
|
||||
bool hasReply = (it->second.mLastRecvTime >= it->second.mLastSendTime);
|
||||
if ((hasSent) && (!hasReply) && (sendts > EXPECTED_REPLY))
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Dropped: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
mClosest.erase(it);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* trim it back */
|
||||
while(mClosest.size() > (uint32_t) (mFns->bdNodesPerBucket() - 1))
|
||||
{
|
||||
std::multimap<bdMetric, bdPeer>::iterator it;
|
||||
it = mClosest.end();
|
||||
if (mClosest.begin() != mClosest.end())
|
||||
{
|
||||
it--;
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Removing Furthest Peer: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
mClosest.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "bdQuery::addPeer(): Closer Peer!: ");
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* add it in */
|
||||
bdPeer peer;
|
||||
peer.mPeerId = *id;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = 0;
|
||||
if (mode & BITDHT_PEER_STATUS_RECV_NODES)
|
||||
{
|
||||
peer.mLastRecvTime = ts;
|
||||
}
|
||||
mClosest.insert(std::pair<bdMetric, bdPeer>(dist, peer));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* we also want to track unreachable node ... this allows us
|
||||
* to detect if peer are online - but uncontactible by dht.
|
||||
*
|
||||
* simple list of closest.
|
||||
*/
|
||||
|
||||
int bdQuery::addPotentialPeer(const bdId *id, uint32_t mode)
|
||||
{
|
||||
bdMetric dist;
|
||||
time_t ts = time(NULL);
|
||||
|
||||
mFns->bdDistance(&mId, &(id->id), &dist);
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "bdQuery::addPotentialPeer(");
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
fprintf(stderr, ", %u)\n", mode);
|
||||
#endif
|
||||
|
||||
/* first we check if this is a worthy potential peer....
|
||||
* if it is already in mClosest -> false. old peer.
|
||||
* if it is > mClosest.rbegin() -> false. too far way.
|
||||
*/
|
||||
int retval = 1;
|
||||
|
||||
std::multimap<bdMetric, bdPeer>::iterator it, sit, eit;
|
||||
sit = mClosest.lower_bound(dist);
|
||||
eit = mClosest.upper_bound(dist);
|
||||
|
||||
for(it = sit; it != eit; it++)
|
||||
{
|
||||
if (it->second.mPeerId == *id)
|
||||
{
|
||||
/* already there */
|
||||
retval = 0;
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer already in mClosest\n");
|
||||
#endif
|
||||
}
|
||||
//empty loop.
|
||||
}
|
||||
|
||||
/* check if outside range, & bucket is full */
|
||||
if ((sit == mClosest.end()) && (mClosest.size() >= mFns->bdNodesPerBucket()))
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer to far away for Potential\n");
|
||||
#endif
|
||||
retval = 0; /* too far way */
|
||||
}
|
||||
|
||||
/* return if false; */
|
||||
if (!retval)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Flagging as Not a Potential Peer!\n");
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* finally if a worthy & new peer -> add into potential closest
|
||||
* and repeat existance tests with PotentialPeers
|
||||
*/
|
||||
|
||||
sit = mPotentialClosest.lower_bound(dist);
|
||||
eit = mPotentialClosest.upper_bound(dist);
|
||||
int i = 0;
|
||||
for(it = mPotentialClosest.begin(); it != sit; it++, i++)
|
||||
{
|
||||
//empty loop.
|
||||
}
|
||||
|
||||
if (i > mFns->bdNodesPerBucket() - 1)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Distance to far... dropping\n");
|
||||
fprintf(stderr, "Flagging as Potential Peer!\n");
|
||||
#endif
|
||||
/* outside the list - so we won't add to mPotentialClosest
|
||||
* but inside mClosest still - so should still try it
|
||||
*/
|
||||
retval = 1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
for(it = sit; it != eit; it++, i++)
|
||||
{
|
||||
if (it->second.mPeerId == *id)
|
||||
{
|
||||
/* this means its already been pinged */
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer Already here in mPotentialClosest!\n");
|
||||
#endif
|
||||
if (mode & BITDHT_PEER_STATUS_RECV_NODES)
|
||||
{
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Updating LastRecvTime\n");
|
||||
#endif
|
||||
it->second.mLastRecvTime = ts;
|
||||
}
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Flagging as Not a Potential Peer!\n");
|
||||
#endif
|
||||
retval = 0;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Peer not in Query\n");
|
||||
#endif
|
||||
|
||||
|
||||
/* trim it back */
|
||||
while(mPotentialClosest.size() > (uint32_t) (mFns->bdNodesPerBucket() - 1))
|
||||
{
|
||||
std::multimap<bdMetric, bdPeer>::iterator it;
|
||||
it = mPotentialClosest.end();
|
||||
if (mPotentialClosest.begin() != mPotentialClosest.end())
|
||||
{
|
||||
it--;
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Removing Furthest Peer: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
mPotentialClosest.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "bdQuery::addPotentialPeer(): Closer Peer!: ");
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* add it in */
|
||||
bdPeer peer;
|
||||
peer.mPeerId = *id;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = ts;
|
||||
mPotentialClosest.insert(std::pair<bdMetric, bdPeer>(dist, peer));
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
fprintf(stderr, "Flagging as Potential Peer!\n");
|
||||
#endif
|
||||
retval = 1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* print query.
|
||||
*/
|
||||
|
||||
int bdQuery::printQuery()
|
||||
{
|
||||
|
||||
fprintf(stderr, "bdQuery::printQuery()\n");
|
||||
time_t ts = time(NULL);
|
||||
fprintf(stderr, "Query for: ");
|
||||
mFns->bdPrintNodeId(std::cerr, &mId);
|
||||
fprintf(stderr, " Query State: %d", mState);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Closest Available Peers:\n");
|
||||
std::multimap<bdMetric, bdPeer>::iterator it;
|
||||
for(it = mClosest.begin(); it != mClosest.end(); it++)
|
||||
{
|
||||
fprintf(stderr, "Id: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, " Bucket: %d ", mFns->bdBucketDistance(&(it->first)));
|
||||
fprintf(stderr," LastSent: %ld ago", ts-it->second.mLastSendTime);
|
||||
fprintf(stderr," LastRecv: %ld ago", ts-it->second.mLastRecvTime);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "\nClosest Potential Peers:\n");
|
||||
for(it = mPotentialClosest.begin(); it != mPotentialClosest.end(); it++)
|
||||
{
|
||||
fprintf(stderr, "Id: ");
|
||||
mFns->bdPrintId(std::cerr, &(it->second.mPeerId));
|
||||
fprintf(stderr, " Bucket: %d ", mFns->bdBucketDistance(&(it->first)));
|
||||
fprintf(stderr," LastSent: %ld ago", ts-it->second.mLastSendTime);
|
||||
fprintf(stderr," LastRecv: %ld ago", ts-it->second.mLastRecvTime);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************* Remote Query **************************************/
|
||||
bdRemoteQuery::bdRemoteQuery(bdId *id, bdNodeId *query, bdToken *transId, uint32_t query_type)
|
||||
:mId(*id), mQuery(*query), mTransId(*transId), mQueryType(query_type)
|
||||
{
|
||||
mQueryTS = time(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
98
libbitdht/src/bitdht/bdquery.h
Normal file
98
libbitdht/src/bitdht/bdquery.h
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef BITDHT_QUERY_H
|
||||
#define BITDHT_QUERY_H
|
||||
|
||||
/*
|
||||
* bitdht/bdquery.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdiface.h"
|
||||
#include "bdpeer.h"
|
||||
#include "bdobj.h"
|
||||
|
||||
/* Query result flags are in bdiface.h */
|
||||
|
||||
#define BITDHT_MIN_QUERY_AGE 10
|
||||
#define BITDHT_MAX_QUERY_AGE 300
|
||||
|
||||
class bdQuery
|
||||
{
|
||||
public:
|
||||
bdQuery(const bdNodeId *id, std::list<bdId> &startList, uint32_t queryFlags,
|
||||
bdDhtFunctions *fns);
|
||||
|
||||
// get the answer.
|
||||
bool result(std::list<bdId> &answer);
|
||||
|
||||
// returning results get passed to all queries.
|
||||
//void addNode(const bdId *id, int mode);
|
||||
int nextQuery(bdId &id, bdNodeId &targetId);
|
||||
int addPeer(const bdId *id, uint32_t mode);
|
||||
int addPotentialPeer(const bdId *id, uint32_t mode);
|
||||
int printQuery();
|
||||
|
||||
// searching for
|
||||
bdNodeId mId;
|
||||
bdMetric mLimit;
|
||||
uint32_t mState;
|
||||
time_t mQueryTS;
|
||||
uint32_t mQueryFlags;
|
||||
|
||||
private:
|
||||
|
||||
// closest peers
|
||||
std::multimap<bdMetric, bdPeer> mClosest;
|
||||
std::multimap<bdMetric, bdPeer> mPotentialClosest;
|
||||
|
||||
bdDhtFunctions *mFns;
|
||||
};
|
||||
|
||||
class bdQueryStatus
|
||||
{
|
||||
public:
|
||||
uint32_t mStatus;
|
||||
uint32_t mQFlags;
|
||||
std::list<bdId> mResults;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* this is just a container class.
|
||||
* we locally seach for this, once then discard.
|
||||
*/
|
||||
class bdRemoteQuery
|
||||
{
|
||||
public:
|
||||
bdRemoteQuery(bdId *id, bdNodeId *query, bdToken *transId, uint32_t query_type);
|
||||
|
||||
bdId mId;
|
||||
bdNodeId mQuery;
|
||||
bdToken mTransId;
|
||||
uint32_t mQueryType;
|
||||
|
||||
time_t mQueryTS;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
253
libbitdht/src/bitdht/bdstddht.cc
Normal file
253
libbitdht/src/bitdht/bdstddht.cc
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* bitdht/bdstddht.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdstddht.h"
|
||||
#include "bdpeer.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
/**
|
||||
* #define BITDHT_DEBUG 1
|
||||
**/
|
||||
|
||||
void bdStdRandomId(bdId *id)
|
||||
{
|
||||
bdStdRandomNodeId(&(id->id));
|
||||
|
||||
id->addr.sin_addr.s_addr = rand();
|
||||
id->addr.sin_port = rand();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void bdStdRandomNodeId(bdNodeId *id)
|
||||
{
|
||||
uint32_t *a_data = (uint32_t *) id->data;
|
||||
for(int i = 0; i < BITDHT_KEY_INTLEN; i++)
|
||||
{
|
||||
a_data[i] = rand();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void bdStdZeroNodeId(bdNodeId *id)
|
||||
{
|
||||
uint32_t *a_data = (uint32_t *) id->data;
|
||||
for(int i = 0; i < BITDHT_KEY_INTLEN; i++)
|
||||
{
|
||||
a_data[i] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bdStdLikelySameNode(const bdId *n1, const bdId *n2)
|
||||
{
|
||||
if (*n1 == *n2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* fills in bdNodeId r, with XOR of a and b */
|
||||
int bdStdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r)
|
||||
{
|
||||
uint8_t *a_data = (uint8_t *) a->data;
|
||||
uint8_t *b_data = (uint8_t *) b->data;
|
||||
uint8_t *ans = (uint8_t *) r->data;
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
*(ans++) = *(a_data++) ^ *(b_data++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void bdStdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *midId)
|
||||
{
|
||||
bdMetric dist;
|
||||
|
||||
/* get distance between a & c */
|
||||
bdStdDistance(target, other, &dist);
|
||||
|
||||
/* generate Random Id */
|
||||
bdStdRandomNodeId(midId);
|
||||
|
||||
/* zero bits of Random Id until under 1/2 of distance
|
||||
* done in bytes for ease... matches one extra byte than distance = 0
|
||||
* -> hence wierd order of operations
|
||||
*/
|
||||
//bool done = false;
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
midId->data[i] = target->data[i];
|
||||
|
||||
if (dist.data[i] != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string bdStdConvertToPrintable(std::string input)
|
||||
{
|
||||
std::ostringstream out;
|
||||
for(uint32_t i = 0; i < input.length(); i++)
|
||||
{
|
||||
/* sensible chars */
|
||||
if ((input[i] > 31) && (input[i] < 127))
|
||||
{
|
||||
out << input[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "[0x" << std::hex << (uint32_t) input[i] << "]";
|
||||
out << std::dec;
|
||||
}
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void bdStdPrintNodeId(std::ostream &out, const bdNodeId *a)
|
||||
{
|
||||
for(int i = 0; i < BITDHT_KEY_LEN; i++)
|
||||
{
|
||||
out << std::setw(2) << std::setfill('0') << std::hex << (uint32_t) (a->data)[i];
|
||||
}
|
||||
out << std::dec;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void bdStdPrintId(std::ostream &out, const bdId *a)
|
||||
{
|
||||
bdStdPrintNodeId(out, &(a->id));
|
||||
out << " ip:" << inet_ntoa(a->addr.sin_addr);
|
||||
out << ":" << ntohs(a->addr.sin_port);
|
||||
return;
|
||||
}
|
||||
|
||||
/* returns 0-160 depending on bucket */
|
||||
int bdStdBucketDistance(const bdNodeId *a, const bdNodeId *b)
|
||||
{
|
||||
bdMetric m;
|
||||
bdStdDistance(a, b, &m);
|
||||
return bdStdBucketDistance(&m);
|
||||
}
|
||||
|
||||
/* returns 0-160 depending on bucket */
|
||||
int bdStdBucketDistance(const bdMetric *m)
|
||||
{
|
||||
for(int i = 0; i < BITDHT_KEY_BITLEN; i++)
|
||||
{
|
||||
int bit = BITDHT_KEY_BITLEN - i - 1;
|
||||
int byte = i / 8;
|
||||
int bbit = 7 - (i % 8);
|
||||
unsigned char comp = (1 << bbit);
|
||||
|
||||
#ifdef BITDHT_DEBUG
|
||||
fprintf(stderr, "bdStdBucketDistance: bit:%d byte:%d bbit:%d comp:%x, data:%x\n", bit, byte, bbit, comp, m->data[byte]);
|
||||
#endif
|
||||
|
||||
if (comp & m->data[byte])
|
||||
{
|
||||
return bit;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bdStdDht::bdStdDht()
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* setup variables */
|
||||
uint16_t bdStdDht::bdNumBuckets()
|
||||
{
|
||||
|
||||
return BITDHT_STANDARD_N_BUCKETS;
|
||||
}
|
||||
|
||||
uint16_t bdStdDht::bdNodesPerBucket() /* used for query + bdspace */
|
||||
{
|
||||
return BITDHT_STANDARD_BUCKET_SIZE;
|
||||
}
|
||||
uint16_t bdStdDht::bdBucketBitSize()
|
||||
{
|
||||
return BITDHT_STANDARD_BUCKET_SIZE_BITS;
|
||||
}
|
||||
|
||||
int bdStdDht::bdDistance(const bdNodeId *n1, const bdNodeId *n2, class bdMetric *metric)
|
||||
{
|
||||
return bdStdDistance(n1, n2, metric);
|
||||
}
|
||||
|
||||
int bdStdDht::bdBucketDistance(const bdNodeId *n1, const bdNodeId *n2)
|
||||
{
|
||||
return bdStdBucketDistance(n1, n2);
|
||||
}
|
||||
|
||||
int bdStdDht::bdBucketDistance(const bdMetric *metric)
|
||||
{
|
||||
return bdStdBucketDistance(metric);
|
||||
}
|
||||
|
||||
|
||||
uint32_t bdStdDht::bdLikelySameNode(const bdId *id1, const bdId *id2)
|
||||
{
|
||||
return bdStdLikelySameNode(id1, id2);
|
||||
}
|
||||
|
||||
|
||||
void bdStdDht::bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid)
|
||||
{
|
||||
return bdStdRandomMidId(target, other, mid);
|
||||
}
|
||||
|
||||
|
||||
void bdStdDht::bdPrintId(std::ostream &out, const bdId *a)
|
||||
{
|
||||
return bdStdPrintId(out, a);
|
||||
}
|
||||
|
||||
void bdStdDht::bdPrintNodeId(std::ostream &out, const bdNodeId *a)
|
||||
{
|
||||
return bdStdPrintNodeId(out, a);
|
||||
}
|
||||
|
||||
|
||||
|
92
libbitdht/src/bitdht/bdstddht.h
Normal file
92
libbitdht/src/bitdht/bdstddht.h
Normal file
@ -0,0 +1,92 @@
|
||||
#ifndef BITDHT_STANDARD_DHT_H
|
||||
#define BITDHT_STANDARD_DHT_H
|
||||
|
||||
/*
|
||||
* bitdht/bdstddht.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdiface.h"
|
||||
|
||||
#define BITDHT_STANDARD_BUCKET_SIZE 20
|
||||
#define BITDHT_STANDARD_BUCKET_SIZE_BITS 5
|
||||
|
||||
#define BITDHT_STANDARD_N_BUCKETS BITDHT_KEY_BITLEN
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
|
||||
void bdStdRandomNodeId(bdNodeId *id);
|
||||
void bdStdZeroNodeId(bdNodeId *id);
|
||||
|
||||
void bdStdRandomId(bdId *id);
|
||||
int bdStdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r);
|
||||
int bdStdBucketDistance(const bdMetric *m);
|
||||
int bdStdBucketDistance(const bdNodeId *a, const bdNodeId *b);
|
||||
|
||||
void bdStdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid);
|
||||
|
||||
void bdStdPrintId(std::ostream &out, const bdId *a);
|
||||
void bdStdPrintNodeId(std::ostream &out, const bdNodeId *a);
|
||||
|
||||
std::string bdStdConvertToPrintable(std::string input);
|
||||
|
||||
uint32_t bdStdLikelySameNode(const bdId*, const bdId*);
|
||||
|
||||
|
||||
class bdStdDht: public bdDhtFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
bdStdDht();
|
||||
/* setup variables */
|
||||
virtual uint16_t bdNumBuckets();
|
||||
virtual uint16_t bdNodesPerBucket(); /* used for query + bdspace */
|
||||
virtual uint16_t bdBucketBitSize();
|
||||
|
||||
virtual int bdDistance(const bdNodeId *n1, const bdNodeId *n2, bdMetric *metric);
|
||||
virtual int bdBucketDistance(const bdNodeId *n1, const bdNodeId *n2);
|
||||
virtual int bdBucketDistance(const bdMetric *metric);
|
||||
|
||||
virtual uint32_t bdLikelySameNode(const bdId *id1, const bdId *id2);
|
||||
|
||||
virtual void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid);
|
||||
|
||||
virtual void bdPrintId(std::ostream &out, const bdId *a);
|
||||
virtual void bdPrintNodeId(std::ostream &out, const bdNodeId *a);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
199
libbitdht/src/bitdht/bdstore.cc
Normal file
199
libbitdht/src/bitdht/bdstore.cc
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* bitdht/bdstore.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bdstore.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
//#define DEBUG_STORE 1
|
||||
|
||||
bdStore::bdStore(std::string file, bdDhtFunctions *fns)
|
||||
:mFns(fns)
|
||||
{
|
||||
#ifdef DEBUG_STORE
|
||||
std::cerr << "bdStore::bdStore(" << file << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* read data from file */
|
||||
mIndex = 0;
|
||||
mStoreFile = file;
|
||||
|
||||
FILE *fd = fopen(file.c_str(), "r");
|
||||
if (!fd)
|
||||
{
|
||||
fprintf(stderr, "Failed to Open File: %s ... No Peers\n", file.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
char line[10240];
|
||||
char addr_str[10240];
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = PF_INET;
|
||||
unsigned short port;
|
||||
|
||||
while(line == fgets(line, 10240, fd))
|
||||
{
|
||||
if (2 == sscanf(line, "%s %hd", addr_str, &port))
|
||||
{
|
||||
if (inet_aton(addr_str, &(addr.sin_addr)))
|
||||
{
|
||||
addr.sin_port = htons(port);
|
||||
bdPeer peer;
|
||||
//bdZeroNodeId(&(peer.mPeerId.id));
|
||||
peer.mPeerId.addr = addr;
|
||||
peer.mLastSendTime = 0;
|
||||
peer.mLastRecvTime = 0;
|
||||
store.push_back(peer);
|
||||
#ifdef DEBUG_STORE
|
||||
fprintf(stderr, "Read: %s %d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
|
||||
#ifdef DEBUG_STORE
|
||||
fprintf(stderr, "Read %ld Peers\n", (long) store.size());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int bdStore::getPeer(bdPeer *peer)
|
||||
{
|
||||
#ifdef DEBUG_STORE
|
||||
fprintf(stderr, "bdStore::getPeer() %ld Peers left\n", (long) store.size());
|
||||
#endif
|
||||
|
||||
std::list<bdPeer>::iterator it;
|
||||
int i = 0;
|
||||
for(it = store.begin(); (it != store.end()) && (i < mIndex); it++, i++);
|
||||
if (it != store.end())
|
||||
{
|
||||
*peer = *it;
|
||||
mIndex++;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_ENTRIES 500
|
||||
|
||||
/* maintain a sorted list */
|
||||
void bdStore::addStore(bdPeer *peer)
|
||||
{
|
||||
#ifdef DEBUG_STORE
|
||||
std::cerr << "bdStore::addStore() ";
|
||||
mFns->bdPrintId(std::cerr, &(peer->mPeerId));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* remove old entry */
|
||||
bool removed = false;
|
||||
|
||||
std::list<bdPeer>::iterator it;
|
||||
for(it = store.begin(); it != store.end(); )
|
||||
{
|
||||
if ((it->mPeerId.addr.sin_addr.s_addr == peer->mPeerId.addr.sin_addr.s_addr) &&
|
||||
(it->mPeerId.addr.sin_port == peer->mPeerId.addr.sin_port))
|
||||
{
|
||||
removed = true;
|
||||
#ifdef DEBUG_STORE
|
||||
std::cerr << "bdStore::addStore() Removed Existing Entry: ";
|
||||
mFns->bdPrintId(std::cerr, &(it->mPeerId));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
it = store.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_STORE
|
||||
std::cerr << "bdStore::addStore() Push_back";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
store.push_back(*peer);
|
||||
|
||||
while(store.size() > MAX_ENTRIES)
|
||||
{
|
||||
#ifdef DEBUG_STORE
|
||||
std::cerr << "bdStore::addStore() pop_front()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
store.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void bdStore::writeStore(std::string file)
|
||||
{
|
||||
/* write out store */
|
||||
#ifdef DEBUG_STORE
|
||||
fprintf(stderr, "bdStore::writeStore(%s) = %d entries\n", file.c_str(), store.size());
|
||||
#endif
|
||||
|
||||
FILE *fd = fopen(file.c_str(), "w");
|
||||
|
||||
if (!fd)
|
||||
{
|
||||
#ifdef DEBUG_STORE
|
||||
#endif
|
||||
fprintf(stderr, "bdStore::writeStore() FAILED to Open File\n");
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<bdPeer>::iterator it;
|
||||
for(it = store.begin(); it != store.end(); it++)
|
||||
{
|
||||
fprintf(fd, "%s %d\n", inet_ntoa(it->mPeerId.addr.sin_addr), ntohs(it->mPeerId.addr.sin_port));
|
||||
#ifdef DEBUG_STORE
|
||||
fprintf(stderr, "Storing Peer Address: %s %d\n", inet_ntoa(it->mPeerId.addr.sin_addr), ntohs(it->mPeerId.addr.sin_port));
|
||||
#endif
|
||||
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
void bdStore::writeStore()
|
||||
{
|
||||
#if 0
|
||||
if (mStoreFile == "")
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
return writeStore(mStoreFile);
|
||||
}
|
||||
|
52
libbitdht/src/bitdht/bdstore.h
Normal file
52
libbitdht/src/bitdht/bdstore.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef BITDHT_STORE_H
|
||||
#define BITDHT_STORE_H
|
||||
|
||||
/*
|
||||
* bitdht/bdstore.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <string>
|
||||
#include "bdiface.h"
|
||||
#include "bdpeer.h"
|
||||
|
||||
class bdStore
|
||||
{
|
||||
public:
|
||||
|
||||
bdStore(std::string file, bdDhtFunctions *fns);
|
||||
int getPeer(bdPeer *peer);
|
||||
void addStore(bdPeer *peer);
|
||||
void writeStore(std::string file);
|
||||
void writeStore();
|
||||
|
||||
private:
|
||||
std::string mStoreFile;
|
||||
std::list<bdPeer> store;
|
||||
int mIndex;
|
||||
bdDhtFunctions *mFns;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
602
libbitdht/src/bitdht/bencode.c
Normal file
602
libbitdht/src/bitdht/bencode.c
Normal file
@ -0,0 +1,602 @@
|
||||
/*
|
||||
* C implementation of a bencode decoder.
|
||||
* This is the format defined by BitTorrent:
|
||||
* http://wiki.theory.org/BitTorrentSpecification#bencoding
|
||||
*
|
||||
* The only external requirements are a few [standard] function calls and
|
||||
* the long long type. Any sane system should provide all of these things.
|
||||
*
|
||||
* See the bencode.h header file for usage information.
|
||||
*
|
||||
* This is released into the public domain.
|
||||
* Written by Mike Frysinger <vapier@gmail.com>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This implementation isn't optimized at all as I wrote it to support
|
||||
* a bogus system. I have no real interest in this format. Feel free
|
||||
* to send me patches (so long as you don't copyright them and you release
|
||||
* your changes into the public domain as well).
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* malloc() realloc() free() strtoll() */
|
||||
#include <string.h> /* memset() */
|
||||
|
||||
#include "bencode.h"
|
||||
|
||||
/***
|
||||
* #define BE_DEBUG_DECODE 1
|
||||
***/
|
||||
|
||||
//#define BE_DEBUG_DECODE 1
|
||||
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
#include <stdio.h> /* debug */
|
||||
#endif
|
||||
|
||||
static be_node *be_alloc(be_type type)
|
||||
{
|
||||
be_node *ret = (be_node *) malloc(sizeof(*ret));
|
||||
if (ret) {
|
||||
memset(ret, 0x00, sizeof(*ret));
|
||||
ret->type = type;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long long _be_decode_int(const char **data, long long *data_len)
|
||||
{
|
||||
char *endp;
|
||||
long long ret = strtoll(*data, &endp, 10);
|
||||
*data_len -= (endp - *data);
|
||||
*data = endp;
|
||||
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode_int(pnt: %p, rem: %lld) = %lld\n", *data, *data_len, ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
long long be_str_len(be_node *node)
|
||||
{
|
||||
long long ret = 0;
|
||||
if (node->val.s)
|
||||
memcpy(&ret, node->val.s - sizeof(ret), sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *_be_decode_str(const char **data, long long *data_len)
|
||||
{
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode_str(pnt: %p, rem: %lld)\n", *data, *data_len);
|
||||
#endif
|
||||
long long sllen = _be_decode_int(data, data_len);
|
||||
long slen = sllen;
|
||||
unsigned long len;
|
||||
char *ret = NULL;
|
||||
|
||||
/* slen is signed, so negative values get rejected */
|
||||
if (sllen < 0)
|
||||
{
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode_str() reject bad length\n");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* reject attempts to allocate large values that overflow the
|
||||
* size_t type which is used with malloc()
|
||||
*/
|
||||
if (sizeof(long long) != sizeof(long))
|
||||
if (sllen != slen)
|
||||
{
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode_str() reject large_values\n");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* make sure we have enough data left */
|
||||
if (sllen > *data_len - 1)
|
||||
{
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode_str() reject large_values\n");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* switch from signed to unsigned so we don't overflow below */
|
||||
len = slen;
|
||||
|
||||
if (**data == ':') {
|
||||
char *_ret = (char *) malloc(sizeof(sllen) + len + 1);
|
||||
memcpy(_ret, &sllen, sizeof(sllen));
|
||||
ret = _ret + sizeof(sllen);
|
||||
memcpy(ret, *data + 1, len);
|
||||
ret[len] = '\0';
|
||||
*data += len + 1;
|
||||
*data_len -= len + 1;
|
||||
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode_str() read %ld bytes\n", len+1);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode_str() reject missing :\n");
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static be_node *_be_decode(const char **data, long long *data_len)
|
||||
{
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode(pnt: %p, rem: %lld)\n", *data, *data_len);
|
||||
#endif
|
||||
be_node *ret = NULL;
|
||||
|
||||
if (!*data_len)
|
||||
{
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() reject invalid datalen\n");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (**data) {
|
||||
/* lists */
|
||||
case 'l': {
|
||||
unsigned int i = 0;
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() found list\n");
|
||||
#endif
|
||||
|
||||
ret = be_alloc(BE_LIST);
|
||||
|
||||
--(*data_len);
|
||||
++(*data);
|
||||
while (**data != 'e') {
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() list get item (%d)\n", i);
|
||||
#endif
|
||||
ret->val.l = (be_node **) realloc(ret->val.l, (i + 2) * sizeof(*ret->val.l));
|
||||
ret->val.l[i] = _be_decode(data, data_len);
|
||||
if (ret->val.l[i] == NULL)
|
||||
{
|
||||
/* failed decode - kill decode */
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() failed list decode - kill\n");
|
||||
#endif
|
||||
be_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
--(*data_len);
|
||||
++(*data);
|
||||
|
||||
/* empty list case. */
|
||||
if (i == 0)
|
||||
{
|
||||
ret->val.l = (be_node **) realloc(ret->val.l, 1 * sizeof(*ret->val.l));
|
||||
}
|
||||
|
||||
ret->val.l[i] = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* dictionaries */
|
||||
case 'd': {
|
||||
unsigned int i = 0;
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() found dictionary\n");
|
||||
#endif
|
||||
|
||||
ret = be_alloc(BE_DICT);
|
||||
|
||||
--(*data_len);
|
||||
++(*data);
|
||||
while (**data != 'e') {
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() dictionary get key (%d)\n", i);
|
||||
#endif
|
||||
ret->val.d = (be_dict *) realloc(ret->val.d, (i + 2) * sizeof(*ret->val.d));
|
||||
ret->val.d[i].key = _be_decode_str(data, data_len);
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() dictionary get val\n");
|
||||
#endif
|
||||
ret->val.d[i].val = _be_decode(data, data_len);
|
||||
|
||||
if ((ret->val.d[i].key == NULL) || (ret->val.d[i].val == NULL))
|
||||
{
|
||||
/* failed decode - kill decode */
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() failed dict decode - kill\n");
|
||||
#endif
|
||||
be_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
--(*data_len);
|
||||
++(*data);
|
||||
|
||||
/* empty dictionary case. */
|
||||
if (i == 0)
|
||||
{
|
||||
ret->val.d = (be_dict *) realloc(ret->val.d, 1 * sizeof(*ret->val.d));
|
||||
}
|
||||
|
||||
|
||||
ret->val.d[i].val = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* integers */
|
||||
case 'i': {
|
||||
ret = be_alloc(BE_INT);
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() found int\n");
|
||||
#endif
|
||||
|
||||
--(*data_len);
|
||||
++(*data);
|
||||
ret->val.i = _be_decode_int(data, data_len);
|
||||
if (**data != 'e')
|
||||
{
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() reject data != e - kill\n");
|
||||
#endif
|
||||
be_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
--(*data_len);
|
||||
++(*data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* byte strings */
|
||||
case '0'...'9': {
|
||||
ret = be_alloc(BE_STR);
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() found string\n");
|
||||
#endif
|
||||
|
||||
ret->val.s = _be_decode_str(data, data_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* invalid */
|
||||
default:
|
||||
#ifdef BE_DEBUG_DECODE
|
||||
fprintf(stderr, "bencode::_be_decode() found invalid - kill\n");
|
||||
#endif
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
be_node *be_decoden(const char *data, long long len)
|
||||
{
|
||||
return _be_decode(&data, &len);
|
||||
}
|
||||
|
||||
be_node *be_decode(const char *data)
|
||||
{
|
||||
return be_decoden(data, strlen(data));
|
||||
}
|
||||
|
||||
static inline void _be_free_str(char *str)
|
||||
{
|
||||
if (str)
|
||||
free(str - sizeof(long long));
|
||||
}
|
||||
void be_free(be_node *node)
|
||||
{
|
||||
switch (node->type) {
|
||||
case BE_STR:
|
||||
_be_free_str(node->val.s);
|
||||
break;
|
||||
|
||||
case BE_INT:
|
||||
break;
|
||||
|
||||
case BE_LIST: {
|
||||
unsigned int i;
|
||||
for (i = 0; node->val.l[i]; ++i)
|
||||
be_free(node->val.l[i]);
|
||||
free(node->val.l);
|
||||
break;
|
||||
}
|
||||
|
||||
case BE_DICT: {
|
||||
unsigned int i;
|
||||
for (i = 0; node->val.d[i].val; ++i) {
|
||||
_be_free_str(node->val.d[i].key);
|
||||
be_free(node->val.d[i].val);
|
||||
}
|
||||
free(node->val.d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
|
||||
#ifdef BE_DEBUG
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static void _be_dump_indent(ssize_t indent)
|
||||
{
|
||||
while (indent-- > 0)
|
||||
printf(" ");
|
||||
}
|
||||
static void _be_dump(be_node *node, ssize_t indent)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
_be_dump_indent(indent);
|
||||
indent = abs(indent);
|
||||
|
||||
switch (node->type) {
|
||||
case BE_STR:
|
||||
be_dump_str(node);
|
||||
//printf("str = %s (len = %lli)\n", node->val.s, be_str_len(node));
|
||||
break;
|
||||
|
||||
case BE_INT:
|
||||
printf("int = %lli\n", node->val.i);
|
||||
break;
|
||||
|
||||
case BE_LIST:
|
||||
puts("list [");
|
||||
|
||||
for (i = 0; node->val.l[i]; ++i)
|
||||
_be_dump(node->val.l[i], indent + 1);
|
||||
|
||||
_be_dump_indent(indent);
|
||||
puts("]");
|
||||
break;
|
||||
|
||||
case BE_DICT:
|
||||
puts("dict {");
|
||||
|
||||
for (i = 0; node->val.d[i].val; ++i) {
|
||||
_be_dump_indent(indent + 1);
|
||||
printf("%s => ", node->val.d[i].key);
|
||||
_be_dump(node->val.d[i].val, -(indent + 1));
|
||||
}
|
||||
|
||||
_be_dump_indent(indent);
|
||||
puts("}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void be_dump(be_node *node)
|
||||
{
|
||||
_be_dump(node, 0);
|
||||
}
|
||||
|
||||
void be_dump_str(be_node *node)
|
||||
{
|
||||
if (node->type != BE_STR)
|
||||
{
|
||||
printf("be_dump_str(): error not a string\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int len = be_str_len(node);
|
||||
printf("str[%d] = ", len);
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
/* sensible chars */
|
||||
if ((node->val.s[i] > 31) && (node->val.s[i] < 127))
|
||||
{
|
||||
printf("%c", node->val.s[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[%d]", node->val.s[i]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/******************** New Functions added by drBob *************
|
||||
* Output bencode
|
||||
*
|
||||
*/
|
||||
|
||||
int be_encode(be_node *node, char *str, int len)
|
||||
{
|
||||
size_t i;
|
||||
int loc = 0;
|
||||
|
||||
switch (node->type) {
|
||||
case BE_STR:
|
||||
snprintf(str, len, "%lli:", be_str_len(node));
|
||||
loc += strlen(&(str[loc]));
|
||||
|
||||
memcpy(&(str[loc]), node->val.s, be_str_len(node));
|
||||
loc += be_str_len(node);
|
||||
break;
|
||||
|
||||
case BE_INT:
|
||||
snprintf(str, len, "i%llie", node->val.i);
|
||||
loc += strlen(&(str[loc]));
|
||||
break;
|
||||
|
||||
case BE_LIST:
|
||||
|
||||
snprintf(str, len, "l");
|
||||
loc += 1;
|
||||
|
||||
for (i = 0; node->val.l[i]; ++i)
|
||||
{
|
||||
loc += be_encode(node->val.l[i], &(str[loc]), len-loc);
|
||||
}
|
||||
|
||||
snprintf(&(str[loc]), len - loc, "e");
|
||||
loc += 1;
|
||||
|
||||
break;
|
||||
|
||||
case BE_DICT:
|
||||
snprintf(str, len, "d");
|
||||
loc += 1;
|
||||
|
||||
for (i = 0; node->val.d[i].val; ++i) {
|
||||
|
||||
/* assumption that key must be ascii! */
|
||||
snprintf(&(str[loc]), len-loc, "%i:%s",
|
||||
(int) strlen(node->val.d[i].key),
|
||||
node->val.d[i].key);
|
||||
loc += strlen(&(str[loc]));
|
||||
loc += be_encode(node->val.d[i].val, &(str[loc]), len-loc);
|
||||
}
|
||||
|
||||
snprintf(&(str[loc]), len - loc, "e");
|
||||
loc += 1;
|
||||
|
||||
break;
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
/* hackish way to create nodes! */
|
||||
be_node *be_create_dict()
|
||||
{
|
||||
be_node *n = be_decode("de");
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
be_node *be_create_list()
|
||||
{
|
||||
be_node *n = be_decode("le");
|
||||
return n;
|
||||
}
|
||||
|
||||
be_node *be_create_str(const char *str)
|
||||
{
|
||||
|
||||
/* must */
|
||||
be_node *n = be_alloc(BE_STR);
|
||||
int len = strlen(str);
|
||||
long long int sllen = len;
|
||||
char *_ret = (char *) malloc(sizeof(sllen) + len + 1);
|
||||
char *ret = NULL;
|
||||
|
||||
memcpy(_ret, &sllen, sizeof(sllen));
|
||||
ret = _ret + sizeof(sllen);
|
||||
memcpy(ret, str, len);
|
||||
ret[len] = '\0';
|
||||
|
||||
n->val.s = ret;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
be_node *be_create_str_wlen(const char *str, int len) /* not including \0 */
|
||||
{
|
||||
|
||||
/* must */
|
||||
be_node *n = be_alloc(BE_STR);
|
||||
long long int sllen = len;
|
||||
char *_ret = (char *) malloc(sizeof(sllen) + len + 1);
|
||||
char *ret = NULL;
|
||||
|
||||
memcpy(_ret, &sllen, sizeof(sllen));
|
||||
ret = _ret + sizeof(sllen);
|
||||
memcpy(ret, str, len);
|
||||
ret[len] = '\0';
|
||||
|
||||
n->val.s = ret;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
be_node *be_create_int(long long int num)
|
||||
{
|
||||
/* must */
|
||||
be_node *n = be_alloc(BE_INT);
|
||||
n->val.i = num;
|
||||
return n;
|
||||
}
|
||||
|
||||
int be_add_keypair(be_node *dict, const char *str, be_node *node)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* only if dict type */
|
||||
if (dict->type != BE_DICT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get to end of dict.
|
||||
for(i = 0; dict->val.d[i].val; i++);
|
||||
|
||||
//fprintf(stderr, "be_add_keypair() i = %d\n",i);
|
||||
|
||||
/* realloc space */
|
||||
dict->val.d = (be_dict *) realloc(dict->val.d, (i + 2) * sizeof(*dict->val.d));
|
||||
|
||||
/* stupid key storage system */
|
||||
int len = strlen(str);
|
||||
long long int sllen = len;
|
||||
char *_ret = (char *) malloc(sizeof(sllen) + len + 1);
|
||||
char *ret = NULL;
|
||||
|
||||
//fprintf(stderr, "be_add_keypair() key len = %d\n",len);
|
||||
|
||||
memcpy(_ret, &sllen, sizeof(sllen));
|
||||
ret = _ret + sizeof(sllen);
|
||||
memcpy(ret, str, len);
|
||||
ret[len] = '\0';
|
||||
|
||||
dict->val.d[i].key = ret;
|
||||
dict->val.d[i].val = node;
|
||||
i++;
|
||||
dict->val.d[i].val = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int be_add_list(be_node *list, be_node *node)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* only if dict type */
|
||||
if (list->type != BE_LIST)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get to end of dict.
|
||||
for(i = 0; list->val.l[i]; i++);
|
||||
|
||||
/* realloc space */
|
||||
list->val.l = (be_node **) realloc(list->val.l, (i + 2) * sizeof(*list->val.l));
|
||||
list->val.l[i] = node;
|
||||
++i;
|
||||
list->val.l[i] = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
82
libbitdht/src/bitdht/bencode.h
Normal file
82
libbitdht/src/bitdht/bencode.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* C implementation of a bencode decoder.
|
||||
* This is the format defined by BitTorrent:
|
||||
* http://wiki.theory.org/BitTorrentSpecification#bencoding
|
||||
*
|
||||
* The only external requirements are a few [standard] function calls and
|
||||
* the long long type. Any sane system should provide all of these things.
|
||||
*
|
||||
* This is released into the public domain.
|
||||
* Written by Mike Frysinger <vapier@gmail.com>.
|
||||
*/
|
||||
|
||||
/* USAGE:
|
||||
* - pass the string full of the bencoded data to be_decode()
|
||||
* - parse the resulting tree however you like
|
||||
* - call be_free() on the tree to release resources
|
||||
*/
|
||||
|
||||
#ifndef _BENCODE_H
|
||||
#define _BENCODE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
BE_STR,
|
||||
BE_INT,
|
||||
BE_LIST,
|
||||
BE_DICT,
|
||||
} be_type;
|
||||
|
||||
struct be_dict;
|
||||
struct be_node;
|
||||
|
||||
/*
|
||||
* XXX: the "val" field of be_dict and be_node can be confusing ...
|
||||
*/
|
||||
|
||||
typedef struct be_dict {
|
||||
char *key;
|
||||
struct be_node *val;
|
||||
} be_dict;
|
||||
|
||||
typedef struct be_node {
|
||||
be_type type;
|
||||
union {
|
||||
char *s;
|
||||
long long i;
|
||||
struct be_node **l;
|
||||
struct be_dict *d;
|
||||
} val;
|
||||
} be_node;
|
||||
|
||||
extern long long be_str_len(be_node *node);
|
||||
// This function uses strlen, so is unreliable.
|
||||
//extern be_node *be_decode(const char *bencode);
|
||||
extern be_node *be_decoden(const char *bencode, long long bencode_len);
|
||||
extern void be_free(be_node *node);
|
||||
extern void be_dump(be_node *node);
|
||||
extern void be_dump_str(be_node *node);
|
||||
|
||||
// New Functions for the other half of the work - encoding */
|
||||
|
||||
extern int be_encode(be_node *node, char *str, int len);
|
||||
|
||||
|
||||
// Creating the data structure.
|
||||
extern int be_add_list(be_node *list, be_node *node);
|
||||
extern int be_add_keypair(be_node *dict, const char *str, be_node *node);
|
||||
extern be_node *be_create_int(long long int num);
|
||||
extern be_node *be_create_list();
|
||||
extern be_node *be_create_str(const char *str);
|
||||
extern be_node *be_create_str_wlen(const char *str, int len); /* not including \0 */
|
||||
extern be_node *be_create_dict();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
108
libbitdht/src/libbitdht.pro
Normal file
108
libbitdht/src/libbitdht.pro
Normal file
@ -0,0 +1,108 @@
|
||||
TEMPLATE = lib
|
||||
CONFIG += staticlib release
|
||||
CONFIG -= qt
|
||||
TARGET = bitdht
|
||||
QMAKE_CXXFLAGS *= -Wall -DBE_DEBUG
|
||||
|
||||
profiling {
|
||||
QMAKE_CXXFLAGS -= -fomit-frame-pointer
|
||||
QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer
|
||||
}
|
||||
|
||||
release {
|
||||
# not much here yet.
|
||||
}
|
||||
|
||||
#CONFIG += debug
|
||||
debug {
|
||||
QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer
|
||||
QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer
|
||||
}
|
||||
|
||||
################################# Linux ##########################################
|
||||
linux-* {
|
||||
DESTDIR = lib
|
||||
QMAKE_CC = g++
|
||||
}
|
||||
|
||||
linux-g++ {
|
||||
OBJECTS_DIR = temp/linux-g++/obj
|
||||
}
|
||||
|
||||
linux-g++-64 {
|
||||
OBJECTS_DIR = temp/linux-g++-64/obj
|
||||
}
|
||||
|
||||
#################### Cross compilation for windows under Linux ####################
|
||||
|
||||
win32-x-g++ {
|
||||
OBJECTS_DIR = temp/win32xgcc/obj
|
||||
DESTDIR = lib.win32xgcc
|
||||
DEFINES *= WINDOWS_SYS WIN32 WIN_CROSS_UBUNTU
|
||||
QMAKE_CXXFLAGS *= -Wmissing-include-dirs
|
||||
QMAKE_CC = i586-mingw32msvc-g++
|
||||
QMAKE_LIB = i586-mingw32msvc-ar
|
||||
QMAKE_AR = i586-mingw32msvc-ar
|
||||
DEFINES *= STATICLIB WIN32
|
||||
|
||||
INCLUDEPATH *= /usr/i586-mingw32msvc/include ${HOME}/.wine/drive_c/pthreads/include/
|
||||
}
|
||||
################################# Windows ##########################################
|
||||
|
||||
win32 {
|
||||
QMAKE_CC = g++
|
||||
OBJECTS_DIR = temp/obj
|
||||
MOC_DIR = temp/moc
|
||||
DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW
|
||||
DESTDIR = lib
|
||||
}
|
||||
|
||||
################################# MacOSX ##########################################
|
||||
|
||||
mac {
|
||||
QMAKE_CC = g++
|
||||
OBJECTS_DIR = temp/obj
|
||||
MOC_DIR = temp/moc
|
||||
DESTDIR = lib
|
||||
}
|
||||
|
||||
################################### COMMON stuff ##################################
|
||||
################################### COMMON stuff ##################################
|
||||
|
||||
#DEPENDPATH += . \
|
||||
INCLUDEPATH += . \
|
||||
|
||||
HEADERS += \
|
||||
bitdht/bdiface.h \
|
||||
bitdht/bencode.h \
|
||||
bitdht/bdobj.h \
|
||||
bitdht/bdmsgs.h \
|
||||
bitdht/bdpeer.h \
|
||||
bitdht/bdquery.h \
|
||||
bitdht/bdhash.h \
|
||||
bitdht/bdstore.h \
|
||||
bitdht/bdnode.h \
|
||||
bitdht/bdmanager.h \
|
||||
bitdht/bdstddht.h \
|
||||
util/bdthreads.h \
|
||||
udp/udplayer.h \
|
||||
udp/udpstack.h \
|
||||
udp/udpbitdht.h \
|
||||
|
||||
SOURCES += \
|
||||
bitdht/bencode.c \
|
||||
bitdht/bdobj.cc \
|
||||
bitdht/bdmsgs.cc \
|
||||
bitdht/bdpeer.cc \
|
||||
bitdht/bdquery.cc \
|
||||
bitdht/bdhash.cc \
|
||||
bitdht/bdstore.cc \
|
||||
bitdht/bdnode.cc \
|
||||
bitdht/bdmanager.cc \
|
||||
bitdht/bdstddht.cc \
|
||||
util/bdthreads.cc \
|
||||
udp/udplayer.cc \
|
||||
udp/udpstack.cc \
|
||||
udp/udpbitdht.cc \
|
||||
|
||||
|
80
libbitdht/src/tests/Makefile
Normal file
80
libbitdht/src/tests/Makefile
Normal file
@ -0,0 +1,80 @@
|
||||
|
||||
LIB_TOP_DIR = ..
|
||||
TEST_TOP_DIR = $(LIB_TOP_DIR)/tests
|
||||
|
||||
##### Define any flags that are needed for this section #######
|
||||
###############################################################
|
||||
|
||||
###############################################################
|
||||
include $(TEST_TOP_DIR)/scripts/config.mk
|
||||
###############################################################
|
||||
|
||||
# Generic Test Harnesses.
|
||||
TESTOBJ = bdmetric_test.o bdmsgs_test.o bdnode_test.o bdspace_test.o
|
||||
TESTOBJ += bdmgr_multitest.o bdnode_multitest1.o bdquery_test.o bdstore_test.o
|
||||
TESTOBJ += bdmidids_test.o bdnode_test2.o bdspace_test2.o
|
||||
#TESTOBJ += bencode_test.o bdudp_test.o
|
||||
|
||||
TESTS = bdmetric_test bdmsgs_test bdnode_test bdspace_test
|
||||
TESTS += bdmgr_multitest bdnode_multitest1 bdquery_test bdstore_test
|
||||
TESTS += bdmidids_test bdnode_test2 bdspace_test2
|
||||
#TESTS += bencode_test bdudp_test
|
||||
|
||||
MANUAL_TESTS =
|
||||
|
||||
all: tests $(MANUAL_TESTS)
|
||||
|
||||
bdmsgs_test: bdmsgs_test.o
|
||||
$(CC) $(CFLAGS) -o bdmsgs_test bdmsgs_test.o $(LIBS)
|
||||
|
||||
bdmetric_test: bdmetric_test.o
|
||||
$(CC) $(CFLAGS) -o bdmetric_test bdmetric_test.o $(LIBS)
|
||||
|
||||
bdquery_test: bdquery_test.o
|
||||
$(CC) $(CFLAGS) -o bdquery_test bdquery_test.o $(LIBS)
|
||||
|
||||
bdspace_test: bdspace_test.o
|
||||
$(CC) $(CFLAGS) -o bdspace_test bdspace_test.o $(LIBS)
|
||||
|
||||
bdspace_test2: bdspace_test2.o
|
||||
$(CC) $(CFLAGS) -o bdspace_test2 bdspace_test2.o $(LIBS)
|
||||
|
||||
bdnode_test: bdnode_test.o
|
||||
$(CC) $(CFLAGS) -o bdnode_test bdnode_test.o $(LIBS)
|
||||
|
||||
bdnode_test2: bdnode_test2.o
|
||||
$(CC) $(CFLAGS) -o bdnode_test2 bdnode_test2.o $(LIBS)
|
||||
|
||||
bdmidids_test: bdmidids_test.o
|
||||
$(CC) $(CFLAGS) -o bdmidids_test bdmidids_test.o $(LIBS)
|
||||
|
||||
|
||||
bdnode_multitest1: bdnode_multitest1.o
|
||||
$(CC) $(CFLAGS) -o bdnode_multitest1 bdnode_multitest1.o $(LIBS)
|
||||
|
||||
bdmgr_multitest: bdmgr_multitest.o
|
||||
$(CC) $(CFLAGS) -o bdmgr_multitest bdmgr_multitest.o $(LIBS)
|
||||
|
||||
|
||||
bdstore_test: bdstore_test.o
|
||||
$(CC) $(CFLAGS) -o bdstore_test bdstore_test.o $(LIBS)
|
||||
|
||||
bdudp_test: bdudp_test.o
|
||||
$(CC) $(CFLAGS) -o bdudp_test bdudp_test.o $(LIBS)
|
||||
|
||||
udpbitdht_nettest: udpbitdht_nettest.o
|
||||
$(CC) $(CFLAGS) -o udpbitdht_test udpbitdht_test.o $(LIBS)
|
||||
|
||||
bencode_test: bencode_test.o
|
||||
$(CC) $(CFLAGS) -o bencode_test bencode_test.o $(LIBS)
|
||||
|
||||
|
||||
clobber: remove_extra_files
|
||||
|
||||
remove_extra_files:
|
||||
-$(RM) $(MANUAL_TESTS)
|
||||
|
||||
###############################################################
|
||||
include $(TEST_TOP_DIR)/scripts/rules.mk
|
||||
###############################################################
|
||||
|
166
libbitdht/src/tests/bdmetric_test.cc
Normal file
166
libbitdht/src/tests/bdmetric_test.cc
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* bitdht/bdmetric_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/* create some ids */
|
||||
bdId id1;
|
||||
bdId id2;
|
||||
bdId id3;
|
||||
bdId id4;
|
||||
bdId id5;
|
||||
bdId id6;
|
||||
|
||||
bdStdRandomId(&id1);
|
||||
bdStdRandomId(&id2);
|
||||
bdStdRandomId(&id3);
|
||||
bdStdRandomId(&id4);
|
||||
bdStdRandomId(&id5);
|
||||
bdStdRandomId(&id6);
|
||||
|
||||
fprintf(stderr, "id1:");
|
||||
bdStdPrintId(std::cerr,&id1);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id2:");
|
||||
bdStdPrintId(std::cerr,&id2);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id3:");
|
||||
bdStdPrintId(std::cerr,&id3);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id4:");
|
||||
bdStdPrintId(std::cerr,&id4);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id5:");
|
||||
bdStdPrintId(std::cerr,&id5);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id6:");
|
||||
bdStdPrintId(std::cerr,&id6);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* now do the sums */
|
||||
bdMetric met;
|
||||
bdMetric met2;
|
||||
int bdist = 0;
|
||||
bdStdDistance(&(id1.id), &(id2.id), &met);
|
||||
|
||||
fprintf(stderr, "1^2:");
|
||||
bdStdPrintNodeId(std::cerr,&met);
|
||||
fprintf(stderr, "\n");
|
||||
bdist = bdStdBucketDistance(&met);
|
||||
fprintf(stderr, " bucket: %d\n", bdist);
|
||||
|
||||
bdStdDistance(&(id1.id), &(id3.id), &met2);
|
||||
bdist = bdStdBucketDistance(&met2);
|
||||
|
||||
fprintf(stderr, "1^3:");
|
||||
bdStdPrintNodeId(std::cerr,&met2);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " bucket: %d\n", bdist);
|
||||
|
||||
int c1 = met < met2;
|
||||
int c2 = met2 < met;
|
||||
|
||||
fprintf(stderr, "1^2<1^3? : %d 1^3<1^2?: %d\n", c1, c2);
|
||||
|
||||
|
||||
bdStdDistance(&(id1.id), &(id4.id), &met2);
|
||||
bdist = bdStdBucketDistance(&met2);
|
||||
|
||||
fprintf(stderr, "1^4:");
|
||||
bdStdPrintNodeId(std::cerr,&met2);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " bucket: %d\n", bdist);
|
||||
|
||||
c1 = met < met2;
|
||||
c2 = met2 < met;
|
||||
|
||||
fprintf(stderr, "1^2<1^4? : %d 1^4<1^2?: %d\n", c1, c2);
|
||||
|
||||
bdStdDistance(&(id1.id), &(id5.id), &met);
|
||||
bdist = bdStdBucketDistance(&met);
|
||||
|
||||
fprintf(stderr, "1^5:");
|
||||
bdStdPrintNodeId(std::cerr,&met);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " bucket: %d\n", bdist);
|
||||
|
||||
bdStdDistance(&(id1.id), &(id6.id), &met);
|
||||
bdist = bdStdBucketDistance(&met);
|
||||
|
||||
fprintf(stderr, "1^6:");
|
||||
bdStdPrintNodeId(std::cerr,&met);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " bucket: %d\n", bdist);
|
||||
|
||||
bdStdDistance(&(id2.id), &(id3.id), &met);
|
||||
bdist = bdStdBucketDistance(&met);
|
||||
|
||||
fprintf(stderr, "2^3:");
|
||||
bdStdPrintNodeId(std::cerr,&met);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " bucket: %d\n", bdist);
|
||||
|
||||
|
||||
fprintf(stderr, "id1:");
|
||||
bdStdPrintId(std::cerr,&id1);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id2:");
|
||||
bdStdPrintId(std::cerr,&id2);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id3:");
|
||||
bdStdPrintId(std::cerr,&id3);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id4:");
|
||||
bdStdPrintId(std::cerr,&id4);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id5:");
|
||||
bdStdPrintId(std::cerr,&id5);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "id6:");
|
||||
bdStdPrintId(std::cerr,&id6);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
185
libbitdht/src/tests/bdmgr_multitest.cc
Normal file
185
libbitdht/src/tests/bdmgr_multitest.cc
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* bitdht/bdmgr_multitest.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdmanager.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
#include "udp/udplayer.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**********************************************************************************
|
||||
* tests of multi bdnodes all connected together.
|
||||
* in these cases, the networking step is shortcut and the ip addresses ignored.
|
||||
* instead the port number is used as an index to peers.
|
||||
*
|
||||
* test1()
|
||||
* Small cross seeding, and static list of peers.
|
||||
* Set it going - and see what happens.
|
||||
*/
|
||||
|
||||
std::map<bdId, bdNodeManager *> nodes;
|
||||
std::map<struct sockaddr_in, bdId> addrIdx;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
time_t sim_time = 600;
|
||||
time_t starttime = time(NULL);
|
||||
int n_nodes = 1000;
|
||||
std::map<bdId, bdNodeManager *>::iterator it;
|
||||
std::map<bdId, bdNodeManager *>::iterator nit;
|
||||
std::map<struct sockaddr_in, bdId>::iterator ait;
|
||||
|
||||
int i, j;
|
||||
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
|
||||
std::cerr << "bdmgr_multitest() Setting up Nodes" << std::endl;
|
||||
/* setup nodes */
|
||||
for(i = 0; i < n_nodes; i++)
|
||||
{
|
||||
bdId id;
|
||||
|
||||
bdStdRandomId(&id);
|
||||
|
||||
//id.addr.sin_port = htons(i);
|
||||
//((uint32_t *) (id.id.data))[0] = i * 16 * 16; /* force this so the sort order is maintained! */
|
||||
std::cerr << "bdmgr_multitest() Id: ";
|
||||
fns->bdPrintId(std::cerr, &id);
|
||||
std::cerr << std::endl;
|
||||
|
||||
bdNodeManager *mgr = new bdNodeManager(&(id.id), "bdTEST", "", fns);
|
||||
|
||||
/* Store in nodes */
|
||||
nodes[id] = mgr;
|
||||
/* Store in indices */
|
||||
addrIdx[id.addr] = id;
|
||||
|
||||
}
|
||||
|
||||
std::cerr << "bdmgr_multitest() Cross Seeding" << std::endl;
|
||||
/* do a little cross seeding */
|
||||
for(nit = nodes.begin(); nit != nodes.end(); nit++)
|
||||
{
|
||||
for(j = 0; j < 2; j++)
|
||||
{
|
||||
int peeridx = rand() % n_nodes;
|
||||
for(i = 0, it = nodes.begin();
|
||||
(i < peeridx) && (it != nodes.end()); i++, it++)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
if (it != nodes.end())
|
||||
{
|
||||
nit->second->addPotentialPeer((bdId *) &(it->first));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ready to run */
|
||||
|
||||
std::cerr << "bdmgr_multitest() Simulation Time....." << std::endl;
|
||||
i = 0;
|
||||
while(time(NULL) < starttime + sim_time)
|
||||
{
|
||||
i++;
|
||||
std::cerr << "bdmgr_multitest() Iteration: " << i << std::endl;
|
||||
|
||||
for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++)
|
||||
{
|
||||
/* extract messages to go -> and deliver */
|
||||
#define MAX_MSG_SIZE 10240
|
||||
struct sockaddr_in addr;
|
||||
char data[MAX_MSG_SIZE];
|
||||
int len = MAX_MSG_SIZE;
|
||||
|
||||
while(it->second->outgoingMsg(&addr, data, &len))
|
||||
{
|
||||
std::cerr << "bdmgr_multitest() Msg from Peer: " << j;
|
||||
|
||||
/* find the peer */
|
||||
ait = addrIdx.find(addr);
|
||||
nit = nodes.end();
|
||||
if (ait != addrIdx.end())
|
||||
{
|
||||
nit = nodes.find(ait->second);
|
||||
std::cerr << " For: ";
|
||||
fns->bdPrintId(std::cerr, &(nit->first));
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << " For Unknown Destination";
|
||||
std::cerr << std::endl;
|
||||
|
||||
}
|
||||
|
||||
if (nit != nodes.end())
|
||||
{
|
||||
/* set from address */
|
||||
nit->second->incomingMsg( (sockaddr_in *) &(it->first.addr), data, len);
|
||||
}
|
||||
/* reset message size */
|
||||
len = MAX_MSG_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++)
|
||||
{
|
||||
/* tick */
|
||||
std::cerr << "bdmgr_multitest() Ticking peer: " << j << std::endl;
|
||||
it->second->iteration();
|
||||
}
|
||||
|
||||
|
||||
/* have a rest */
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
std::cerr << "bdmgr_multitest() Displying States"<< std::endl;
|
||||
for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++)
|
||||
{
|
||||
/* tick */
|
||||
std::cerr << "bdmgr_multitest() Peer State: " << j << std::endl;
|
||||
it->second->printState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
96
libbitdht/src/tests/bdmidids_test.cc
Normal file
96
libbitdht/src/tests/bdmidids_test.cc
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* bitdht/bdmidids_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/* Do this multiple times */
|
||||
int i, j;
|
||||
|
||||
std::cerr << "Test Mid Peer Intersection....." << std::endl;
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
bdNodeId targetId;
|
||||
bdNodeId peerId;
|
||||
|
||||
bdStdRandomNodeId(&targetId);
|
||||
bdStdRandomNodeId(&peerId);
|
||||
|
||||
std::cerr << "-------------------------------------------------" << std::endl;
|
||||
|
||||
for(j = 0; j < 10; j++)
|
||||
{
|
||||
|
||||
bdNodeId midId;
|
||||
|
||||
bdStdRandomMidId(&targetId, &peerId, &midId);
|
||||
|
||||
bdMetric TPmetric;
|
||||
bdMetric TMmetric;
|
||||
bdMetric PMmetric;
|
||||
|
||||
bdStdDistance(&targetId, &peerId, &TPmetric);
|
||||
bdStdDistance(&targetId, &midId, &TMmetric);
|
||||
bdStdDistance(&peerId, &midId, &PMmetric);
|
||||
|
||||
int TPdist = bdStdBucketDistance(&TPmetric);
|
||||
int TMdist = bdStdBucketDistance(&TMmetric);
|
||||
int PMdist = bdStdBucketDistance(&PMmetric);
|
||||
|
||||
std::cerr << "Target: ";
|
||||
bdStdPrintNodeId(std::cerr,&targetId);
|
||||
std::cerr << " Peer: ";
|
||||
bdStdPrintNodeId(std::cerr,&peerId);
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << "\tTarget ^ Peer: ";
|
||||
bdStdPrintNodeId(std::cerr,&TPmetric);
|
||||
std::cerr << " Bucket: " << TPdist;
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << "\tTarget ^ Mid: ";
|
||||
bdStdPrintNodeId(std::cerr,&TMmetric);
|
||||
std::cerr << " Bucket: " << TMdist;
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr << "\tPeer ^ Mid: ";
|
||||
bdStdPrintNodeId(std::cerr,&PMmetric);
|
||||
std::cerr << " Bucket: " << PMdist;
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* now save mid to peer... and repeat */
|
||||
peerId = midId;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
102
libbitdht/src/tests/bdmsgs_test.cc
Normal file
102
libbitdht/src/tests/bdmsgs_test.cc
Normal file
@ -0,0 +1,102 @@
|
||||
|
||||
/*
|
||||
* bitdht/bdmsgs_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdmsgs.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
#include <string.h>
|
||||
|
||||
/*******************************************************************
|
||||
* Test of bencode message creation functions in bdmsgs.cc
|
||||
*
|
||||
* Create a couple of each type.
|
||||
*/
|
||||
|
||||
#define MAX_MESSAGE_LEN 10240
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/***** create messages *****/
|
||||
char msg[MAX_MESSAGE_LEN];
|
||||
int avail = MAX_MESSAGE_LEN -1;
|
||||
|
||||
bdToken tid;
|
||||
bdToken vid;
|
||||
bdToken token;
|
||||
|
||||
|
||||
bdNodeId ownId;
|
||||
bdNodeId peerId;
|
||||
bdNodeId target;
|
||||
bdNodeId info_hash;
|
||||
|
||||
bdStdRandomNodeId(&ownId);
|
||||
bdStdRandomNodeId(&peerId);
|
||||
bdStdRandomNodeId(&target);
|
||||
bdStdRandomNodeId(&info_hash);
|
||||
|
||||
std::list<bdId> nodes;
|
||||
std::list<std::string> values;
|
||||
|
||||
/* setup tokens */
|
||||
strncpy((char*)tid.data, "tid", 4);
|
||||
strncpy((char*)vid.data, "RS50", 5);
|
||||
strncpy((char*)token.data, "ToKEn", 6);
|
||||
|
||||
tid.len = 3;
|
||||
vid.len = 4;
|
||||
token.len = 5;
|
||||
|
||||
/* setup lists */
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
bdId rndId;
|
||||
bdStdRandomId(&rndId);
|
||||
|
||||
nodes.push_back(rndId);
|
||||
values.push_back("values");
|
||||
}
|
||||
|
||||
uint32_t port = 1234;
|
||||
|
||||
bitdht_create_ping_msg(&tid, &ownId, msg, avail);
|
||||
bitdht_response_ping_msg(&tid, &ownId, &vid, msg, avail);
|
||||
|
||||
bitdht_find_node_msg(&tid, &ownId, &target, msg, avail);
|
||||
bitdht_resp_node_msg(&tid, &ownId, nodes, msg, avail);
|
||||
|
||||
bitdht_get_peers_msg(&tid, &ownId, &info_hash, msg, avail);
|
||||
bitdht_peers_reply_hash_msg(&tid, &ownId, &token, values, msg, avail);
|
||||
bitdht_peers_reply_closest_msg(&tid, &ownId, &token, nodes, msg, avail);
|
||||
|
||||
bitdht_announce_peers_msg(&tid, &ownId, &info_hash, port, &token, msg, avail);
|
||||
bitdht_reply_announce_msg(&tid, &ownId, msg, avail);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
184
libbitdht/src/tests/bdnode_multitest1.cc
Normal file
184
libbitdht/src/tests/bdnode_multitest1.cc
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* bitdht/bdnode_multitest1.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdnode.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**********************************************************************************
|
||||
* tests of multi bdnodes all connected together.
|
||||
* in these cases, the networking step is shortcut and the ip addresses ignored.
|
||||
* instead the port number is used as an index to peers.
|
||||
*
|
||||
* test1()
|
||||
* Small cross seeding, and static list of peers.
|
||||
* Set it going - and see what happens.
|
||||
*/
|
||||
|
||||
std::map<bdId, bdNode *> nodes;
|
||||
std::map<uint16_t, bdId> portIdx;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
time_t sim_time = 60;
|
||||
time_t starttime = time(NULL);
|
||||
int n_nodes = 10;
|
||||
std::map<bdId, bdNode *>::iterator it;
|
||||
std::map<bdId, bdNode *>::iterator nit;
|
||||
std::map<uint16_t, bdId>::iterator pit;
|
||||
|
||||
int i, j;
|
||||
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
|
||||
std::cerr << "bdnode_multitest1() Setting up Nodes" << std::endl;
|
||||
/* setup nodes */
|
||||
for(i = 0; i < n_nodes; i++)
|
||||
{
|
||||
bdId id;
|
||||
|
||||
bdStdRandomId(&id);
|
||||
|
||||
id.addr.sin_port = htons(i);
|
||||
((uint32_t *) (id.id.data))[0] = i * 16 * 16; /* force this so the sort order is maintained! */
|
||||
std::cerr << "bdnode_multitest1() Id: ";
|
||||
fns->bdPrintId(std::cerr, &id);
|
||||
std::cerr << std::endl;
|
||||
|
||||
bdNode *node = new bdNode(&(id.id), "bdTEST", "", fns);
|
||||
|
||||
/* Store in nodes */
|
||||
nodes[id] = node;
|
||||
/* Store in indices */
|
||||
portIdx[i] = id;
|
||||
|
||||
}
|
||||
|
||||
std::cerr << "bdnode_multitest1() Cross Seeding" << std::endl;
|
||||
/* do a little cross seeding */
|
||||
for(i = 0; i < n_nodes; i++)
|
||||
{
|
||||
bdId nid = portIdx[i];
|
||||
bdNode *node = nodes[nid];
|
||||
|
||||
for(j = 0; j < 5; j++)
|
||||
{
|
||||
int peeridx = rand() % n_nodes;
|
||||
|
||||
bdId pid = portIdx[peeridx];
|
||||
node->addPotentialPeer(&pid);
|
||||
}
|
||||
}
|
||||
|
||||
/* ready to run */
|
||||
|
||||
std::cerr << "bdnode_multitest1() Simulation Time....." << std::endl;
|
||||
i = 0;
|
||||
while(time(NULL) < starttime + sim_time)
|
||||
{
|
||||
i++;
|
||||
std::cerr << "bdnode_multitest1() Iteration: " << i << std::endl;
|
||||
|
||||
for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++)
|
||||
{
|
||||
/* extract messages to go -> and deliver */
|
||||
#define MAX_MSG_SIZE 10240
|
||||
struct sockaddr_in addr;
|
||||
char data[MAX_MSG_SIZE];
|
||||
int len = MAX_MSG_SIZE;
|
||||
|
||||
while(it->second->outgoingMsg(&addr, data, &len))
|
||||
{
|
||||
std::cerr << "bdnode_multitest1() Msg from Peer: " << j;
|
||||
|
||||
/* find the peer */
|
||||
int peeridx = htons(addr.sin_port);
|
||||
pit = portIdx.find(peeridx);
|
||||
nit = nodes.end();
|
||||
if (pit != portIdx.end())
|
||||
{
|
||||
nit = nodes.find(pit->second);
|
||||
std::cerr << " For: ";
|
||||
fns->bdPrintId(std::cerr, &(nit->first));
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << " For Unknown Destination";
|
||||
std::cerr << std::endl;
|
||||
|
||||
}
|
||||
|
||||
if (nit != nodes.end())
|
||||
{
|
||||
/* set from address */
|
||||
nit->second->incomingMsg( (sockaddr_in *) &(it->first.addr), data, len);
|
||||
}
|
||||
/* reset message size */
|
||||
len = MAX_MSG_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++)
|
||||
{
|
||||
/* tick */
|
||||
std::cerr << "bdnode_multitest1() Ticking peer: " << j << std::endl;
|
||||
it->second->iteration();
|
||||
}
|
||||
|
||||
if (i % 5 == 0)
|
||||
{
|
||||
std::cerr << "bdnode_multitest1() Displying States"<< std::endl;
|
||||
for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++)
|
||||
{
|
||||
/* tick */
|
||||
std::cerr << "bdnode_multitest1() Peer State: " << j << std::endl;
|
||||
it->second->printState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* have a rest */
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
89
libbitdht/src/tests/bdnode_test.cc
Normal file
89
libbitdht/src/tests/bdnode_test.cc
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* bitdht/bdnode_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
#include "bitdht/bdquery.h"
|
||||
#include "bitdht/bdnode.h"
|
||||
|
||||
#define N_PEERS_TO_ADD_INIT 10
|
||||
#define N_PEERS_TO_ADD 11
|
||||
#define N_PEERS_TO_START 10
|
||||
#define N_PEERS_TO_PRINT 1
|
||||
#define N_QUERIES 2
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/* create some ids */
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
|
||||
bdNodeId ownId;
|
||||
bdStdRandomNodeId(&ownId);
|
||||
|
||||
bdNode node(&ownId, "bdTEST","./dht.log", fns);
|
||||
|
||||
int i = 0;
|
||||
for (i = 0; i < N_PEERS_TO_ADD_INIT; i++)
|
||||
{
|
||||
bdId tmpId;
|
||||
bdStdRandomId(&tmpId);
|
||||
|
||||
node.addPeer(&tmpId, 0);
|
||||
}
|
||||
|
||||
node.printState();
|
||||
|
||||
|
||||
for(i = 0; i < N_QUERIES; i++)
|
||||
{
|
||||
/* create a query */
|
||||
bdNodeId queryId;
|
||||
bdStdRandomNodeId(&queryId);
|
||||
|
||||
node.addQuery(&queryId, 0);
|
||||
}
|
||||
|
||||
node.printState();
|
||||
|
||||
for (i = 0; i < N_PEERS_TO_ADD; i++)
|
||||
{
|
||||
bdId tmpId;
|
||||
bdStdRandomId(&tmpId);
|
||||
|
||||
node.addPeer(&tmpId, 0);
|
||||
|
||||
if (i % N_PEERS_TO_PRINT == 0)
|
||||
{
|
||||
node.printState();
|
||||
node.iteration();
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
56
libbitdht/src/tests/bdnode_test2.cc
Normal file
56
libbitdht/src/tests/bdnode_test2.cc
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* bitdht/bdnode_test2.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
#include "bitdht/bdquery.h"
|
||||
#include "bitdht/bdnode.h"
|
||||
|
||||
#define N_PEERS_TO_ADD_INIT 10
|
||||
#define N_PEERS_TO_ADD 11
|
||||
#define N_PEERS_TO_START 10
|
||||
#define N_PEERS_TO_PRINT 1
|
||||
#define N_QUERIES 2
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/* create some ids */
|
||||
bdNodeId ownId;
|
||||
bdStdRandomNodeId(&ownId);
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
|
||||
bdNode node(&ownId, "bdTEST", "./dht.log", fns);
|
||||
|
||||
while(1)
|
||||
{
|
||||
node.iteration();
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
83
libbitdht/src/tests/bdquery_test.cc
Normal file
83
libbitdht/src/tests/bdquery_test.cc
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* bitdht/bdquery_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
#include "bitdht/bdquery.h"
|
||||
|
||||
#define N_PEERS_TO_ADD 10000
|
||||
#define N_PEERS_TO_PRINT 1000
|
||||
#define N_PEERS_TO_START 10
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/* create some ids */
|
||||
bdNodeId ownId;
|
||||
bdStdRandomNodeId(&ownId);
|
||||
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
|
||||
bdSpace space(&ownId, fns);
|
||||
int i = 0;
|
||||
for (i = 0; i < N_PEERS_TO_ADD; i++)
|
||||
{
|
||||
bdId tmpId;
|
||||
bdStdRandomId(&tmpId);
|
||||
|
||||
space.add_peer(&tmpId, 0);
|
||||
}
|
||||
|
||||
space.printDHT();
|
||||
|
||||
/* create a query */
|
||||
bdId queryId;
|
||||
bdStdRandomId(&queryId);
|
||||
|
||||
|
||||
|
||||
std::list<bdId> startList;
|
||||
std::multimap<bdMetric, bdId> nearest;
|
||||
std::multimap<bdMetric, bdId>::iterator it;
|
||||
|
||||
space.find_nearest_nodes(&(queryId.id), N_PEERS_TO_START, startList, nearest);
|
||||
|
||||
for(it = nearest.begin(); it != nearest.end(); it++)
|
||||
{
|
||||
startList.push_back(it->second);
|
||||
}
|
||||
|
||||
bdQuery query(&(queryId.id), startList, BITDHT_QFLAGS_DISGUISE, fns);
|
||||
|
||||
/* */
|
||||
|
||||
query.printQuery();
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
60
libbitdht/src/tests/bdspace_test.cc
Normal file
60
libbitdht/src/tests/bdspace_test.cc
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* bitdht/bdspace_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
|
||||
#define N_PEERS_TO_ADD 10000
|
||||
#define N_PEERS_TO_PRINT 1000
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/* create some ids */
|
||||
bdNodeId ownId;
|
||||
bdStdRandomNodeId(&ownId);
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
|
||||
bdSpace space(&ownId, fns);
|
||||
int i = 0;
|
||||
for (i = 0; i < N_PEERS_TO_ADD; i++)
|
||||
{
|
||||
bdId tmpId;
|
||||
bdStdRandomId(&tmpId);
|
||||
|
||||
space.add_peer(&tmpId, 0);
|
||||
|
||||
if (i % N_PEERS_TO_PRINT == 0)
|
||||
{
|
||||
space.printDHT();
|
||||
}
|
||||
}
|
||||
space.printDHT();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
68
libbitdht/src/tests/bdspace_test2.cc
Normal file
68
libbitdht/src/tests/bdspace_test2.cc
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* bitdht/bdspace_test2.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
|
||||
#define N_PEERS_TO_ADD 10000
|
||||
#define N_PEERS_TO_TEST 100
|
||||
#define N_PEERS_TO_FIND 10
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/* create some ids */
|
||||
bdNodeId ownId;
|
||||
bdStdRandomNodeId(&ownId);
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
|
||||
bdSpace space(&ownId, fns);
|
||||
int i = 0;
|
||||
for (i = 0; i < N_PEERS_TO_ADD; i++)
|
||||
{
|
||||
bdId tmpId;
|
||||
bdStdRandomId(&tmpId);
|
||||
space.add_peer(&tmpId, 0);
|
||||
}
|
||||
|
||||
space.printDHT();
|
||||
|
||||
|
||||
/* now generate random id's and test closeness */
|
||||
for(i = 0; i < N_PEERS_TO_TEST; i++)
|
||||
{
|
||||
bdId tmpId;
|
||||
bdStdRandomId(&tmpId);
|
||||
std::list<bdId> list1;
|
||||
std::multimap<bdMetric, bdId> list2;
|
||||
|
||||
space.find_nearest_nodes(&(tmpId.id), N_PEERS_TO_FIND, list1, list2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
47
libbitdht/src/tests/bdstore_test.cc
Normal file
47
libbitdht/src/tests/bdstore_test.cc
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* bitdht/bdstore_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdstore.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* load store */
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Missing Store File\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
bdStore store(argv[1], fns);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
66
libbitdht/src/tests/bdudp_test.cc
Normal file
66
libbitdht/src/tests/bdudp_test.cc
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* bitdht/bdudp_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdquery.h"
|
||||
#include "udp/udpbitdht.h"
|
||||
|
||||
#define N_PEERS_TO_ADD 10000
|
||||
#define N_PEERS_TO_PRINT 1000
|
||||
#define N_PEERS_TO_START 10
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
/* create some ids */
|
||||
bdId ownId;
|
||||
bdRandomId(&ownId);
|
||||
|
||||
|
||||
struct sockaddr_in local;
|
||||
local.sin_addr.s_addr = 0;
|
||||
local.sin_port = htons(7812);
|
||||
std::string bootstrapfile = "dht.log";
|
||||
|
||||
bdId bid;
|
||||
|
||||
bid.addr = local;
|
||||
bid.id = ownId.id;
|
||||
|
||||
UdpBitDht ubd(local, 0, &bid, bootstrapfile);
|
||||
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
ubd.tick();
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
182
libbitdht/src/tests/bencode_test.cc
Normal file
182
libbitdht/src/tests/bencode_test.cc
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* bitdht/bencode_test.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bencode.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
char msg[100];
|
||||
|
||||
msg[0] = 'd';
|
||||
msg[1] = '1';
|
||||
msg[2] = ':';
|
||||
msg[3] = 't';
|
||||
msg[4] = 'L';
|
||||
msg[5] = 'b';
|
||||
msg[6] = 'U';
|
||||
msg[7] = 0xd9;
|
||||
msg[8] = 0xfa;
|
||||
msg[9] = 0xff;
|
||||
msg[10] = 0xff;
|
||||
msg[11] = 0xff;
|
||||
msg[12] = 0xff;
|
||||
msg[13] = '\n';
|
||||
msg[14] = 'H';
|
||||
msg[15] = '#';
|
||||
msg[16] = '#';
|
||||
msg[17] = '#';
|
||||
msg[18] = '#';
|
||||
msg[19] = '#';
|
||||
msg[20] = '#';
|
||||
msg[21] = '#';
|
||||
|
||||
be_node *n = be_decoden(msg, 16);
|
||||
|
||||
if (n)
|
||||
{
|
||||
be_dump(n);
|
||||
be_free(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "didn't crash!\n");
|
||||
}
|
||||
|
||||
msg[0] = 'd';
|
||||
msg[1] = '1';
|
||||
msg[2] = ':';
|
||||
msg[3] = 'a';
|
||||
msg[4] = 'L';
|
||||
msg[5] = 0x8d;
|
||||
msg[6] = 0xd6;
|
||||
msg[7] = '\r';
|
||||
msg[8] = 0x9d;
|
||||
msg[9] = ';';
|
||||
msg[10] = 0xff;
|
||||
msg[11] = 0xff;
|
||||
msg[12] = 0xff;
|
||||
msg[13] = 0xff;
|
||||
msg[14] = 'H';
|
||||
msg[15] = '#';
|
||||
msg[16] = '#';
|
||||
msg[17] = '#';
|
||||
msg[18] = '#';
|
||||
msg[19] = '#';
|
||||
msg[20] = '#';
|
||||
msg[21] = '#';
|
||||
|
||||
n = be_decoden(msg, 14);
|
||||
|
||||
if (n)
|
||||
{
|
||||
be_dump(n);
|
||||
be_free(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "didn't crash!\n");
|
||||
}
|
||||
|
||||
msg[0] = 'd';
|
||||
msg[1] = '1';
|
||||
msg[2] = ':';
|
||||
msg[3] = 't';
|
||||
msg[4] = '4';
|
||||
msg[5] = ':';
|
||||
msg[6] = 'a';
|
||||
msg[7] = 'b';
|
||||
msg[8] = 'c';
|
||||
msg[9] = 'd';
|
||||
msg[10] = '1';
|
||||
msg[11] = ':';
|
||||
msg[12] = 'y';
|
||||
msg[13] = '1';
|
||||
msg[14] = ':';
|
||||
msg[15] = 'r';
|
||||
msg[16] = '1';
|
||||
msg[17] = ':';
|
||||
msg[18] = 'r';
|
||||
msg[19] = 'd';
|
||||
msg[20] = '2';
|
||||
msg[21] = ':';
|
||||
msg[22] = 'i';
|
||||
msg[23] = 'd';
|
||||
msg[24] = '2';
|
||||
msg[25] = '0';
|
||||
msg[26] = ':';
|
||||
msg[27] = '1';
|
||||
msg[28] = '2';
|
||||
msg[29] = '3';
|
||||
msg[30] = '4';
|
||||
msg[31] = '5';
|
||||
msg[32] = '6';
|
||||
msg[33] = '7';
|
||||
msg[34] = '8';
|
||||
msg[35] = '9';
|
||||
msg[36] = '0';
|
||||
msg[37] = 'a';
|
||||
msg[38] = 'b';
|
||||
msg[39] = 'c';
|
||||
msg[40] = 'd';
|
||||
msg[41] = 'e';
|
||||
msg[42] = 'f';
|
||||
msg[43] = 'g';
|
||||
msg[44] = 'h';
|
||||
msg[45] = 'i';
|
||||
msg[46] = '.';
|
||||
msg[47] = '5';
|
||||
msg[48] = ':';
|
||||
msg[49] = 'n';
|
||||
msg[50] = 'o';
|
||||
msg[51] = 'd';
|
||||
msg[52] = 'e';
|
||||
msg[53] = 's';
|
||||
msg[54] = '2';
|
||||
msg[55] = '0';
|
||||
msg[56] = '8';
|
||||
msg[57] = ':';
|
||||
msg[58] = '\0';
|
||||
msg[59] = '\0';
|
||||
msg[60] = '\0';
|
||||
|
||||
n = be_decoden(msg, 58);
|
||||
|
||||
if (n)
|
||||
{
|
||||
be_dump(n);
|
||||
be_free(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "didn't crash!\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
19
libbitdht/src/tests/scripts/checks.mk
Normal file
19
libbitdht/src/tests/scripts/checks.mk
Normal file
@ -0,0 +1,19 @@
|
||||
#Basic checks
|
||||
|
||||
ifndef TEST_TOP_DIR
|
||||
dummy:
|
||||
echo "TEST_TOP_DIR is not defined in your makefile"
|
||||
endif
|
||||
|
||||
ifneq ($(OS),Linux)
|
||||
ifneq ($(OS),MacOSX)
|
||||
ifndef PTHREADS_DIR
|
||||
dummy:
|
||||
echo "you must define PTHREADS_DIR before you can compile"
|
||||
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
|
118
libbitdht/src/tests/scripts/config-cygwin.mk
Normal file
118
libbitdht/src/tests/scripts/config-cygwin.mk
Normal file
@ -0,0 +1,118 @@
|
||||
ifneq ($(OS),Cygwin)
|
||||
dummy:
|
||||
echo "ERROR Cygwin configuration file included, but (OS != Cygwin)
|
||||
|
||||
endif
|
||||
|
||||
############ LINUX CONFIGURATION ########################
|
||||
|
||||
# flags for components....
|
||||
PQI_USE_XPGP = 1
|
||||
#PQI_USE_PROXY = 1
|
||||
#PQI_USE_CHANNELS = 1
|
||||
#USE_FILELOOK = 1
|
||||
|
||||
###########################################################################
|
||||
|
||||
#### DrBobs Versions.... Please Don't Delete.
|
||||
### Comment out if needed.
|
||||
ALT_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW
|
||||
SRC_ROOT=../../../..
|
||||
|
||||
PTHREADS_DIR=$(ALT_SRC_ROOT)/pthreads/pthreads.2
|
||||
|
||||
###################
|
||||
|
||||
#ALT_SRC_ROOT=/cygdrive/c/RetroShareBuild/src
|
||||
#SRC_ROOT=/cygdrive/c/RetroShareBuild/src
|
||||
|
||||
#PTHREADS_DIR=$(ALT_SRC_ROOT)/pthreads-w32-2-8-0-release
|
||||
|
||||
###################
|
||||
|
||||
ZLIB_DIR=$(ALT_SRC_ROOT)/zlib-1.2.3
|
||||
|
||||
SSL_DIR=$(SRC_ROOT)/openssl-0.9.7g-xpgp-0.1c
|
||||
UPNPC_DIR=$(SRC_ROOT)/miniupnpc-1.0
|
||||
|
||||
include $(RS_TOP_DIR)/scripts/checks.mk
|
||||
|
||||
############ ENFORCE DIRECTORY NAMING ########################
|
||||
|
||||
CC = g++
|
||||
RM = /bin/rm
|
||||
RANLIB = ranlib
|
||||
LIBDIR = $(RS_TOP_DIR)/lib
|
||||
LIBRS = $(LIBDIR)/libretroshare.a
|
||||
|
||||
# Unix: Linux/Cygwin
|
||||
INCLUDE = -I $(RS_TOP_DIR)
|
||||
|
||||
ifdef PQI_DEBUG
|
||||
CFLAGS = -Wall -g $(INCLUDE)
|
||||
else
|
||||
CFLAGS = -Wall -O2 $(INCLUDE)
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_XPGP
|
||||
INCLUDE += -I $(SSL_DIR)/include
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_XPGP
|
||||
CFLAGS += -DPQI_USE_XPGP
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_PROXY
|
||||
CFLAGS += -DPQI_USE_PROXY
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_CHANNELS
|
||||
CFLAGS += -DPQI_USE_CHANNELS
|
||||
endif
|
||||
|
||||
ifdef USE_FILELOOK
|
||||
CFLAGS += -DUSE_FILELOOK
|
||||
endif
|
||||
|
||||
|
||||
RSCFLAGS = -Wall -g $(INCLUDE)
|
||||
|
||||
#########################################################################
|
||||
# OS Compile Options
|
||||
#########################################################################
|
||||
|
||||
# For the SSL BIO compilation. (Copied from OpenSSL compilation flags)
|
||||
BIOCC = gcc
|
||||
|
||||
# Cygwin - ?same? as Linux flags
|
||||
BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
|
||||
|
||||
#########################################################################
|
||||
# OS specific Linking.
|
||||
#########################################################################
|
||||
|
||||
# for static pthread libs....
|
||||
WININC += -DPTW32_STATIC_LIB
|
||||
WININC += -mno-cygwin -mwindows -fno-exceptions
|
||||
WININC += -DWINDOWS_SYS
|
||||
|
||||
WINLIB = -lws2_32 -luuid -lole32 -liphlpapi
|
||||
WINLIB += -lcrypt32 -lwinmm
|
||||
|
||||
CFLAGS += -I$(PTHREADS_DIR) $(WININC)
|
||||
CFLAGS += -I$(ZLIB_DIR)
|
||||
|
||||
LIBS = -L$(LIBDIR) -lretroshare
|
||||
ifdef PQI_USE_XPGP
|
||||
LIBS += -L$(SSL_DIR)
|
||||
endif
|
||||
|
||||
LIBS += -lssl -lcrypto
|
||||
LIBS += -L$(UPNPC_DIR) -lminiupnpc
|
||||
LIBS += -L$(ZLIB_DIR) -lz
|
||||
LIBS += -L$(PTHREADS_DIR) -lpthreadGC2d
|
||||
LIBS += $(WINLIB)
|
||||
|
||||
RSCFLAGS += $(WININC)
|
||||
|
||||
|
41
libbitdht/src/tests/scripts/config-linux.mk
Normal file
41
libbitdht/src/tests/scripts/config-linux.mk
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
ifneq ($(OS),Linux)
|
||||
dummy:
|
||||
echo "ERROR Linux configuration file included, but (OS != Linux)
|
||||
|
||||
endif
|
||||
|
||||
############ LINUX CONFIGURATION ########################
|
||||
|
||||
include $(TEST_TOP_DIR)/scripts/checks.mk
|
||||
|
||||
############ ENFORCE DIRECTORY NAMING ########################
|
||||
|
||||
CC = g++
|
||||
RM = /bin/rm
|
||||
RANLIB = ranlib
|
||||
LIBDIR = $(LIB_TOP_DIR)/lib
|
||||
LIBRS = $(LIBDIR)/libretroshare.a
|
||||
|
||||
# Unix: Linux/Cygwin
|
||||
INCLUDE = -I $(LIB_TOP_DIR)
|
||||
CFLAGS = -Wall -g $(INCLUDE)
|
||||
CFLAGS += ${DEFINES} -D BE_DEBUG
|
||||
|
||||
#########################################################################
|
||||
# OS Compile Options
|
||||
#########################################################################
|
||||
|
||||
#########################################################################
|
||||
# OS specific Linking.
|
||||
#########################################################################
|
||||
|
||||
LIBS = -L$(LIBDIR) -lbitdht
|
||||
LIBS += -lpthread
|
||||
#LIBS += $(XLIB) -ldl -lz
|
||||
#LIBS += -lupnp
|
||||
#LIBS += -lgpgme
|
||||
#
|
||||
#RSLIBS = $(LIBS)
|
||||
|
||||
|
152
libbitdht/src/tests/scripts/config-macosx.mk
Normal file
152
libbitdht/src/tests/scripts/config-macosx.mk
Normal file
@ -0,0 +1,152 @@
|
||||
|
||||
ifneq ($(OS),MacOSX)
|
||||
dummy:
|
||||
echo "ERROR MacOSX configuration file included, but (OS != MacOSX)
|
||||
|
||||
endif
|
||||
|
||||
############ LINUX CONFIGURATION ########################
|
||||
|
||||
|
||||
# FLAGS to decide if we want i386 Build or ppc Build
|
||||
#
|
||||
#
|
||||
|
||||
# PPC is default
|
||||
# Could define both for combined compilation...
|
||||
# except might not work for bio_tou.c file!
|
||||
#
|
||||
# MAC_I386_BUILD = 1
|
||||
# MAC_PPC_BUILD = 1
|
||||
|
||||
#MAC_I386_BUILD = 1
|
||||
#MAC_PPC_BUILD = 1
|
||||
|
||||
ifndef MAC_I386_BUILD
|
||||
MAC_PPC_BUILD = 1
|
||||
endif
|
||||
|
||||
# flags for components....
|
||||
#PQI_USE_SSLONLY = 1
|
||||
#PQI_USE_XPGP = 1
|
||||
|
||||
#PQI_USE_PROXY = 1
|
||||
#PQI_USE_CHANNELS = 1
|
||||
#USE_FILELOOK = 1
|
||||
|
||||
SSL_DIR=../../../../../src/openssl-0.9.7g-xpgp-0.1c
|
||||
UPNPC_DIR=../../../../../src/miniupnpc-1.0
|
||||
|
||||
include $(RS_TOP_DIR)/scripts/checks.mk
|
||||
|
||||
############ ENFORCE DIRECTORY NAMING ########################
|
||||
|
||||
CC = g++
|
||||
RM = /bin/rm
|
||||
|
||||
RANLIB = ranlib
|
||||
|
||||
# Dummy ranlib -> can't do it until afterwards with universal binaries.
|
||||
# RANLIB = ls -l
|
||||
|
||||
LIBDIR = $(RS_TOP_DIR)/lib
|
||||
LIBRS = $(LIBDIR)/libretroshare.a
|
||||
|
||||
OPT_DIR = /opt/local
|
||||
OPT_INCLUDE = $(OPT_DIR)/include
|
||||
OPT_LIBS = $(OPT_DIR)/lib
|
||||
|
||||
INCLUDE = -I $(RS_TOP_DIR) -I $(OPT_INCLUDE)
|
||||
#CFLAGS = -Wall -O3
|
||||
CFLAGS = -Wall -g
|
||||
|
||||
# Flags for architecture builds.
|
||||
ifdef MAC_I386_BUILD
|
||||
CFLAGS += -arch i386
|
||||
endif
|
||||
|
||||
ifdef MAC_PPC_BUILD
|
||||
CFLAGS += -arch ppc
|
||||
endif
|
||||
|
||||
CFLAGS += $(INCLUDE)
|
||||
|
||||
# This Line is for Universal BUILD for 10.4 + 10.5
|
||||
# (but unlikely to work unless Qt Libraries are build properly)
|
||||
# CFLAGS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk
|
||||
|
||||
ifdef PQI_USE_XPGP
|
||||
INCLUDE += -I $(SSL_DIR)/include
|
||||
CFLAGS += -DPQI_USE_XPGP
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_SSLONLY
|
||||
CFLAGS += -DPQI_USE_SSLONLY
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_PROXY
|
||||
CFLAGS += -DPQI_USE_PROXY
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_CHANNELS
|
||||
CFLAGS += -DPQI_USE_CHANNELS
|
||||
endif
|
||||
|
||||
ifdef USE_FILELOOK
|
||||
CFLAGS += -DUSE_FILELOOK
|
||||
endif
|
||||
|
||||
|
||||
# RSCFLAGS = -Wall -O3 $(INCLUDE)
|
||||
|
||||
#########################################################################
|
||||
# OS Compile Options
|
||||
#########################################################################
|
||||
|
||||
# For the SSL BIO compilation. (Copied from OpenSSL compilation flags)
|
||||
BIOCC = gcc
|
||||
|
||||
|
||||
# Flags for architecture builds.
|
||||
ifdef MAC_I386_BUILD
|
||||
BIOCFLAGS = -arch i386 -I $(SSL_DIR)/include -DOPENSSL_SYSNAME_MACOSX -DOPENSSL_THREADS -D_REENTRANT -DOPENSSL_NO_KRB5 -O3 -fomit-frame-pointer -fno-common
|
||||
endif
|
||||
|
||||
ifdef MAC_PPC_BUILD
|
||||
BIOCFLAGS = -arch ppc -I $(SSL_DIR)/include -DOPENSSL_SYSNAME_MACOSX -DOPENSSL_THREADS -D_REENTRANT -DOPENSSL_NO_KRB5 -O3 -fomit-frame-pointer -fno-common -DB_ENDIAN
|
||||
endif
|
||||
|
||||
|
||||
|
||||
# MacOSX flags
|
||||
# BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_SYSNAME_MACOSX -DOPENSSL_THREADS -D_REENTRANT -DOPENSSL_NO_KRB5 -O3 -fomit-frame-pointer -fno-common -DB_ENDIAN
|
||||
|
||||
# This is for the Universal Build...
|
||||
# but is unlikely to work... as options are PPC specific....
|
||||
#
|
||||
# BIOCFLAGS = -arch ppc -arch i386 -I $(SSL_DIR)/include -DOPENSSL_SYSNAME_MACOSX -DOPENSSL_THREADS -D_REENTRANT -DOPENSSL_NO_KRB5 -O3 -fomit-frame-pointer -fno-common -DB_ENDIAN
|
||||
|
||||
|
||||
#########################################################################
|
||||
# OS specific Linking.
|
||||
#########################################################################
|
||||
|
||||
LIBS = -Wl,-search_paths_first
|
||||
|
||||
# for Univeral BUILD
|
||||
# LIBS += -arch ppc -arch i386
|
||||
# LIBS += -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386
|
||||
|
||||
LIBS += -L$(LIBDIR) -lretroshare
|
||||
ifdef PQI_USE_XPGP
|
||||
LIBS += -L$(SSL_DIR)
|
||||
endif
|
||||
LIBS += -lssl -lcrypto -lpthread
|
||||
LIBS += -L$(OPT_LIBS)
|
||||
LIBS += -lgpgme -lgpg-error
|
||||
LIBS += -L$(UPNPC_DIR) -lminiupnpc
|
||||
LIBS += $(XLIB) -ldl -lz
|
||||
|
||||
RSLIBS = $(LIBS)
|
||||
|
||||
|
138
libbitdht/src/tests/scripts/config-mingw.mk
Normal file
138
libbitdht/src/tests/scripts/config-mingw.mk
Normal file
@ -0,0 +1,138 @@
|
||||
#ifneq ($(OS),"Win ")
|
||||
#dummy:
|
||||
# echo "ERROR OS = $(OS)"
|
||||
# echo "ERROR MinGW configuration file included, but (OS != Win)
|
||||
#
|
||||
#endif
|
||||
|
||||
############ LINUX CONFIGURATION ########################
|
||||
|
||||
# flags for components....
|
||||
#PQI_USE_XPGP = 1
|
||||
#PQI_USE_PROXY = 1
|
||||
#PQI_USE_CHANNELS = 1
|
||||
#USE_FILELOOK = 1
|
||||
|
||||
###########################################################################
|
||||
|
||||
#### DrBobs Versions.... Please Don't Delete.
|
||||
### Comment out if needed.
|
||||
SRC_ROOT_PKG=/home/Mark/prog/retroshare/package/rs-win-v0.5.0/src
|
||||
SRC_ROOT_GPG=/local
|
||||
|
||||
#ALT_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW
|
||||
#SRC_ROOT=../../../..
|
||||
|
||||
PTHREADS_DIR=$(SRC_ROOT_PKG)/pthreads-w32-2-8-0/Pre-built.2
|
||||
ZLIB_DIR=$(SRC_ROOT_PKG)/zlib-1.2.3
|
||||
SSL_DIR=$(SRC_ROOT_PKG)/openssl-tmp
|
||||
UPNPC_DIR=$(SRC_ROOT_PKG)/miniupnpc-1.3
|
||||
|
||||
###########################################################################
|
||||
|
||||
#### Enable this section for compiling with MSYS/MINGW compile
|
||||
#SRC_ROOT=/home/linux
|
||||
|
||||
#SSL_DIR=$(SRC_ROOT)/OpenSSL
|
||||
#GPGME_DIR=$(SRC_ROOT)/gpgme-1.1.8
|
||||
#GPG_ERROR_DIR=$(SRC_ROOT)/libgpg-error-1.7
|
||||
|
||||
#ZLIB_DIR=$(SRC_ROOT)/zlib-1.2.3
|
||||
#UPNPC_DIR=$(SRC_ROOT)/miniupnpc-1.0
|
||||
#PTHREADS_DIR=$(SRC_ROOT)/pthreads-w32-2-8-0-release
|
||||
|
||||
include $(RS_TOP_DIR)/scripts/checks.mk
|
||||
|
||||
############ ENFORCE DIRECTORY NAMING #######################################
|
||||
|
||||
CC = g++
|
||||
RM = /bin/rm
|
||||
RANLIB = ranlib
|
||||
LIBDIR = $(RS_TOP_DIR)/lib
|
||||
LIBRS = $(LIBDIR)/libretroshare.a
|
||||
|
||||
# Unix: Linux/Cygwin
|
||||
INCLUDE = -I $(RS_TOP_DIR)
|
||||
|
||||
ifdef PQI_DEBUG
|
||||
CFLAGS = -Wall -g $(INCLUDE)
|
||||
else
|
||||
CFLAGS = -Wall -O2 $(INCLUDE)
|
||||
endif
|
||||
|
||||
# These aren't used anymore.... really.
|
||||
ifdef PQI_USE_XPGP
|
||||
CFLAGS += -DPQI_USE_XPGP
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_PROXY
|
||||
CFLAGS += -DPQI_USE_PROXY
|
||||
endif
|
||||
|
||||
ifdef PQI_USE_CHANNELS
|
||||
CFLAGS += -DPQI_USE_CHANNELS
|
||||
endif
|
||||
|
||||
ifdef USE_FILELOOK
|
||||
CFLAGS += -DUSE_FILELOOK
|
||||
endif
|
||||
|
||||
|
||||
# SSL / pthreads / Zlib
|
||||
# included by default for Windows compilation.
|
||||
INCLUDE += -I $(SSL_DIR)/include
|
||||
INCLUDE += -I$(PTHREADS_DIR)
|
||||
INCLUDE += -I$(ZLIB_DIR)
|
||||
|
||||
|
||||
#########################################################################
|
||||
# OS Compile Options
|
||||
#########################################################################
|
||||
|
||||
# For the SSL BIO compilation. (Copied from OpenSSL compilation flags)
|
||||
BIOCC = gcc
|
||||
|
||||
# Cygwin - ?same? as Linux flags
|
||||
BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
|
||||
BIOCFLAGS += -DWINDOWS_SYS
|
||||
|
||||
#########################################################################
|
||||
# OS specific Linking.
|
||||
#########################################################################
|
||||
|
||||
# for static pthread libs....
|
||||
#WININC += -DPTW32_STATIC_LIB
|
||||
#WININC += -mno-cygwin -mwindows -fno-exceptions
|
||||
|
||||
WININC += -DWINDOWS_SYS
|
||||
|
||||
WINLIB = -lws2_32 -luuid -lole32 -liphlpapi
|
||||
WINLIB += -lcrypt32 -lwinmm
|
||||
|
||||
CFLAGS += -I$(SSL_DIR)/include
|
||||
CFLAGS += -I$(PTHREADS_DIR)/include
|
||||
CFLAGS += -I$(ZLIB_DIR)
|
||||
CFLAGS += -I$(SRC_ROOT_GPG)/include
|
||||
|
||||
### Enable this for GPGME and GPG ERROR dirs
|
||||
#CFLAGS += -I$(GPGME_DIR)/src
|
||||
#CFLAGS += -I$(GPG_ERROR_DIR)/src
|
||||
|
||||
CFLAGS += $(WININC)
|
||||
|
||||
|
||||
|
||||
LIBS = -L$(LIBDIR) -lretroshare
|
||||
|
||||
LIBS += -L$(SSL_DIR)
|
||||
|
||||
LIBS += -lssl -lcrypto
|
||||
LIBS += -L$(UPNPC_DIR) -lminiupnpc
|
||||
LIBS += -L$(ZLIB_DIR) -lz
|
||||
LIBS += -L$(PTHREADS_DIR) -lpthreadGC2d
|
||||
LIBS += $(WINLIB)
|
||||
|
||||
#RSCFLAGS = -Wall -g $(INCLUDE)
|
||||
#RSCFLAGS += $(WININC)
|
||||
|
||||
|
27
libbitdht/src/tests/scripts/config.mk
Normal file
27
libbitdht/src/tests/scripts/config.mk
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
# determine which operating system
|
||||
#
|
||||
###########################################################################
|
||||
#Define OS.
|
||||
#
|
||||
OS = Linux
|
||||
#OS = MacOSX
|
||||
#OS = Cygwin
|
||||
#OS = Win # MinGw.
|
||||
###########################################################################
|
||||
|
||||
ifeq ($(OS),Linux)
|
||||
include $(TEST_TOP_DIR)/scripts/config-linux.mk
|
||||
else
|
||||
ifeq ($(OS),MacOSX)
|
||||
include $(TEST_TOP_DIR)/scripts/config-macosx.mk
|
||||
else
|
||||
ifeq ($(OS),Cygwin)
|
||||
include $(TEST_TOP_DIR)/scripts/config-cygwin.mk
|
||||
else
|
||||
include $(TEST_TOP_DIR)/scripts/config-mingw.mk
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
###########################################################################
|
25
libbitdht/src/tests/scripts/regress.mk
Normal file
25
libbitdht/src/tests/scripts/regress.mk
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
testoutputfiles = $(foreach tt,$(1),$(tt).tstout)
|
||||
|
||||
%.tstout : %.sh
|
||||
-sh ./$< > $@ 2>&1
|
||||
|
||||
%.tstout : %
|
||||
-./$< > $@ 2>&1
|
||||
|
||||
TESTOUT = $(call testoutputfiles,$(TESTS))
|
||||
|
||||
.phony : tests regress retest clobber
|
||||
|
||||
tests: $(TESTS)
|
||||
|
||||
regress: $(TESTOUT)
|
||||
@-echo "--------------- SUCCESS (count):"
|
||||
@-grep -c SUCCESS $(TESTOUT)
|
||||
@-echo "--------------- FAILURE REPORTS:"
|
||||
@-grep FAILURE $(TESTOUT) || echo no failures
|
||||
@-echo "--------------- end"
|
||||
|
||||
retest:
|
||||
-/bin/rm $(TESTOUT)
|
||||
|
19
libbitdht/src/tests/scripts/rules.mk
Normal file
19
libbitdht/src/tests/scripts/rules.mk
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
# defines required / used.
|
||||
#
|
||||
# CFLAGS
|
||||
#
|
||||
#
|
||||
|
||||
.cc.o:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
clean:
|
||||
-/bin/rm $(EXECOBJ) $(TESTOBJ)
|
||||
|
||||
clobber: clean retest
|
||||
-/bin/rm $(EXEC) $(TESTS)
|
||||
|
||||
|
||||
include $(TEST_TOP_DIR)/scripts/regress.mk
|
||||
|
188
libbitdht/src/udp/udpbitdht.cc
Normal file
188
libbitdht/src/udp/udpbitdht.cc
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* bitdht/udpbitdht.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "udp/udpbitdht.h"
|
||||
#include "bitdht/bdpeer.h"
|
||||
#include "bitdht/bdstore.h"
|
||||
#include "bitdht/bdmsgs.h"
|
||||
#include "bitdht/bencode.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*
|
||||
* #define DEBUG_UDP_BITDHT 1
|
||||
*/
|
||||
//#define DEBUG_UDP_BITDHT 1
|
||||
|
||||
/*************************************/
|
||||
|
||||
UdpBitDht::UdpBitDht(UdpPublisher *pub, bdNodeId *id, std::string dhtVersion, std::string bootstrapfile, bdDhtFunctions *fns)
|
||||
:UdpSubReceiver(pub), mFns(fns)
|
||||
{
|
||||
/* setup nodeManager */
|
||||
mBitDhtManager = new bdNodeManager(id, dhtVersion, bootstrapfile, fns);
|
||||
|
||||
}
|
||||
|
||||
|
||||
UdpBitDht::~UdpBitDht()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*********** External Interface to the World ************/
|
||||
|
||||
/***** Functions to Call down to bdNodeManager ****/
|
||||
/* Request DHT Peer Lookup */
|
||||
/* Request Keyword Lookup */
|
||||
void UdpBitDht::addFindNode(bdNodeId *id, uint32_t mode)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
mBitDhtManager->addFindNode(id, mode);
|
||||
}
|
||||
|
||||
void UdpBitDht::removeFindNode(bdNodeId *id)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
mBitDhtManager->removeFindNode(id);
|
||||
}
|
||||
|
||||
void UdpBitDht::findDhtValue(bdNodeId *id, std::string key, uint32_t mode)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
mBitDhtManager->findDhtValue(id, key, mode);
|
||||
}
|
||||
|
||||
/***** Add / Remove Callback Clients *****/
|
||||
void UdpBitDht::addCallback(BitDhtCallback *cb)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
mBitDhtManager->addCallback(cb);
|
||||
}
|
||||
|
||||
void UdpBitDht::removeCallback(BitDhtCallback *cb)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
mBitDhtManager->removeCallback(cb);
|
||||
}
|
||||
|
||||
int UdpBitDht::getDhtPeerAddress(bdNodeId *id, struct sockaddr_in &from)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
return mBitDhtManager->getDhtPeerAddress(id, from);
|
||||
}
|
||||
|
||||
int UdpBitDht::getDhtValue(bdNodeId *id, std::string key, std::string &value)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
return mBitDhtManager->getDhtValue(id, key, value);
|
||||
}
|
||||
|
||||
/******************* Internals *************************/
|
||||
|
||||
/***** Iteration / Loop Management *****/
|
||||
|
||||
/*** Overloaded from UdpSubReceiver ***/
|
||||
int UdpBitDht::recvPkt(void *data, int size, struct sockaddr_in &from)
|
||||
{
|
||||
/* pass onto bitdht */
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
/* check packet suitability */
|
||||
if (mBitDhtManager->isBitDhtPacket((char *) data, size, from))
|
||||
{
|
||||
|
||||
mBitDhtManager->incomingMsg(&from, (char *) data, size);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UdpBitDht::status(std::ostream &out)
|
||||
{
|
||||
out << "UdpBitDht::status()" << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*** Overloaded from iThread ***/
|
||||
void UdpBitDht::run()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
tick();
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
int UdpBitDht::tick()
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
/* pass on messages from the node */
|
||||
int i = 0;
|
||||
char data[BITDHT_MAX_PKTSIZE];
|
||||
struct sockaddr_in toAddr;
|
||||
int size = BITDHT_MAX_PKTSIZE;
|
||||
|
||||
/* accept up to 10 msgs / tick() */
|
||||
while((i < 10) && (mBitDhtManager->outgoingMsg(&toAddr, data, &size)))
|
||||
{
|
||||
#ifdef DEBUG_UDP_BITDHT
|
||||
std::cerr << "UdpBitDht::tick() outgoing msg(" << size << ") to " << toAddr;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
sendPkt(data, size, toAddr, BITDHT_TTL);
|
||||
|
||||
// iterate
|
||||
i++;
|
||||
size = BITDHT_MAX_PKTSIZE; // reset msg size!
|
||||
}
|
||||
|
||||
mBitDhtManager->iteration();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
96
libbitdht/src/udp/udpbitdht.h
Normal file
96
libbitdht/src/udp/udpbitdht.h
Normal file
@ -0,0 +1,96 @@
|
||||
#ifndef UDP_BIT_DHT_CLASS_H
|
||||
#define UDP_BIT_DHT_CLASS_H
|
||||
|
||||
/*
|
||||
* bitdht/udpbitdht.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "udp/udpstack.h"
|
||||
#include "bitdht/bdiface.h"
|
||||
#include "bitdht/bdmanager.h"
|
||||
|
||||
/*
|
||||
* This implements a UdpSubReceiver class to allow the DHT to talk to the network.
|
||||
* The parser is very strict - and will try to not pick up anyone else's messages.
|
||||
*
|
||||
* Mutexes are implemented at this level protecting the whole of the DHT code.
|
||||
* This class is also a thread - enabling it to do callback etc.
|
||||
*/
|
||||
|
||||
// class BitDhtCallback defined in bdiface.h
|
||||
|
||||
|
||||
class UdpBitDht: public UdpSubReceiver, public bdThread, public BitDhtInterface
|
||||
{
|
||||
public:
|
||||
|
||||
UdpBitDht(UdpPublisher *pub, bdNodeId *id, std::string dhtVersion, std::string bootstrapfile, bdDhtFunctions *fns);
|
||||
virtual ~UdpBitDht();
|
||||
|
||||
|
||||
/*********** External Interface to the World (BitDhtInterface) ************/
|
||||
|
||||
/***** Functions to Call down to bdNodeManager ****/
|
||||
/* Request DHT Peer Lookup */
|
||||
/* Request Keyword Lookup */
|
||||
virtual void addFindNode(bdNodeId *id, uint32_t mode);
|
||||
virtual void removeFindNode(bdNodeId *id);
|
||||
virtual void findDhtValue(bdNodeId *id, std::string key, uint32_t mode);
|
||||
|
||||
/***** Add / Remove Callback Clients *****/
|
||||
virtual void addCallback(BitDhtCallback *cb);
|
||||
virtual void removeCallback(BitDhtCallback *cb);
|
||||
|
||||
/***** Get Results Details *****/
|
||||
virtual int getDhtPeerAddress(bdNodeId *id, struct sockaddr_in &from);
|
||||
virtual int getDhtValue(bdNodeId *id, std::string key, std::string &value);
|
||||
|
||||
/******************* Internals *************************/
|
||||
/***** Iteration / Loop Management *****/
|
||||
|
||||
/*** Overloaded from UdpSubReceiver ***/
|
||||
virtual int recvPkt(void *data, int size, struct sockaddr_in &from);
|
||||
virtual int status(std::ostream &out);
|
||||
|
||||
|
||||
/*** Overloaded from iThread ***/
|
||||
virtual void run();
|
||||
|
||||
/**** do whats to be done ***/
|
||||
int tick();
|
||||
|
||||
private:
|
||||
|
||||
bdMutex dhtMtx; /* for all class data (below) */
|
||||
bdNodeManager *mBitDhtManager;
|
||||
bdDhtFunctions *mFns;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
124
libbitdht/src/udp/udpbitdht_nettest.cc
Normal file
124
libbitdht/src/udp/udpbitdht_nettest.cc
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* bitdht/udpbitdht_nettest.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "udpbitdht.h"
|
||||
#include "udpstack.h"
|
||||
#include "bdstddht.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*******************************************************************
|
||||
* Test of bencode message creation functions in bdmsgs.cc
|
||||
*
|
||||
* Create a couple of each type.
|
||||
*/
|
||||
|
||||
#define MAX_MESSAGE_LEN 10240
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* setup id, and bootstrap file */
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cerr << " Missing port number " << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int delta = 0;
|
||||
if (argc < 3)
|
||||
{
|
||||
std::cerr << "No Id Delta" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = atoi(argv[2]);
|
||||
}
|
||||
|
||||
int port = atoi(argv[1]);
|
||||
std::cerr << "Using Port: " << port << std::endl;
|
||||
std::cerr << "Using Delta: " << delta << std::endl;
|
||||
|
||||
bdDhtFunctions *fns = new bdStdDht();
|
||||
|
||||
bdNodeId id;
|
||||
memcpy(((char *) id.data), "1234567890abcdefghi", 20);
|
||||
uint32_t *deltaptr = (uint32_t *) (id.data);
|
||||
(*deltaptr) += htonl(delta);
|
||||
|
||||
std::cerr << "Using NodeId: ";
|
||||
fns->bdPrintNodeId(std::cerr, &id);
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::string bootstrapfile = "bdboot.txt";
|
||||
|
||||
/* setup the udp port */
|
||||
struct sockaddr_in local;
|
||||
local.sin_port = htons(port);
|
||||
UdpStack *udpstack = new UdpStack(local);
|
||||
|
||||
/* create bitdht component */
|
||||
std::string dhtVersion = "dbTEST";
|
||||
UdpBitDht *bitdht = new UdpBitDht(udpstack, &id, dhtVersion, bootstrapfile, fns);
|
||||
|
||||
/* add in the stack */
|
||||
udpstack->addReceiver(bitdht);
|
||||
|
||||
/* register callback display */
|
||||
bdDebugCallback *cb = new bdDebugCallback();
|
||||
bitdht->addCallback(cb);
|
||||
|
||||
/* startup threads */
|
||||
//udpstack->start();
|
||||
bitdht->start();
|
||||
|
||||
|
||||
|
||||
|
||||
/* do a couple of random continuous searchs. */
|
||||
|
||||
uint32_t mode = BITDHT_QFLAGS_DO_IDLE;
|
||||
|
||||
|
||||
int count = 0;
|
||||
while(1)
|
||||
{
|
||||
sleep(120);
|
||||
if (++count == 2)
|
||||
{
|
||||
/* switch to one-shot searchs */
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
bdNodeId rndId;
|
||||
bdStdRandomNodeId(&rndId);
|
||||
bitdht->addFindNode(&rndId, mode);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
497
libbitdht/src/udp/udplayer.cc
Normal file
497
libbitdht/src/udp/udplayer.cc
Normal file
@ -0,0 +1,497 @@
|
||||
/*
|
||||
* bitdht/udplayer.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "udplayer.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
*/
|
||||
|
||||
/***
|
||||
* #define DEBUG_UDP_LAYER 1
|
||||
***/
|
||||
|
||||
#define OPEN_UNIVERSAL_PORT 1
|
||||
|
||||
static const int UDP_DEF_TTL = 64;
|
||||
|
||||
|
||||
class udpPacket
|
||||
{
|
||||
public:
|
||||
udpPacket(struct sockaddr_in *addr, void *dta, int dlen)
|
||||
:raddr(*addr), len(dlen)
|
||||
{
|
||||
data = malloc(len);
|
||||
memcpy(data, dta, len);
|
||||
}
|
||||
|
||||
~udpPacket()
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
free(data);
|
||||
data = NULL;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct sockaddr_in raddr;
|
||||
void *data;
|
||||
int len;
|
||||
};
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const struct sockaddr_in &addr)
|
||||
{
|
||||
out << "[" << inet_ntoa(addr.sin_addr) << ":";
|
||||
out << htons(addr.sin_port) << "]";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const struct sockaddr_in &addr, const struct sockaddr_in &addr2)
|
||||
{
|
||||
if (addr.sin_family != addr2.sin_family)
|
||||
return false;
|
||||
if (addr.sin_addr.s_addr != addr2.sin_addr.s_addr)
|
||||
return false;
|
||||
if (addr.sin_port != addr2.sin_port)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool operator<(const struct sockaddr_in &addr, const struct sockaddr_in &addr2)
|
||||
{
|
||||
if (addr.sin_family != addr2.sin_family)
|
||||
return (addr.sin_family < addr2.sin_family);
|
||||
if (addr.sin_addr.s_addr != addr2.sin_addr.s_addr)
|
||||
return (addr.sin_addr.s_addr < addr2.sin_addr.s_addr);
|
||||
if (addr.sin_port != addr2.sin_port)
|
||||
return (addr.sin_port < addr2.sin_port);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string printPkt(void *d, int size)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "Packet:" << "**********************";
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
if (i % 16 == 0)
|
||||
out << std::endl;
|
||||
out << std::hex << std::setw(2) << (unsigned int) ((unsigned char *) d)[i] << " ";
|
||||
}
|
||||
out << std::endl << "**********************";
|
||||
out << std::endl;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
||||
std::string printPktOffset(unsigned int offset, void *d, unsigned int size)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "Packet:" << "**********************";
|
||||
out << std::endl;
|
||||
out << "Offset: " << std::hex << offset << " -> " << offset + size;
|
||||
out << std::endl;
|
||||
out << "Packet:" << "**********************";
|
||||
|
||||
unsigned int j = offset % 16;
|
||||
if (j != 0)
|
||||
{
|
||||
out << std::endl;
|
||||
out << std::hex << std::setw(6) << (unsigned int) offset - j;
|
||||
out << ": ";
|
||||
for(unsigned int i = 0; i < j; i++)
|
||||
{
|
||||
out << "xx ";
|
||||
}
|
||||
}
|
||||
for(unsigned int i = offset; i < offset + size; i++)
|
||||
{
|
||||
if (i % 16 == 0)
|
||||
{
|
||||
out << std::endl;
|
||||
out << std::hex << std::setw(6) << (unsigned int) i;
|
||||
out << ": ";
|
||||
}
|
||||
out << std::hex << std::setw(2) << (unsigned int) ((unsigned char *) d)[i-offset] << " ";
|
||||
}
|
||||
out << std::endl << "**********************";
|
||||
out << std::endl;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
UdpLayer::UdpLayer(UdpReceiver *udpr, struct sockaddr_in &local)
|
||||
:recv(udpr), laddr(local), errorState(0), ttl(UDP_DEF_TTL)
|
||||
{
|
||||
openSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
int UdpLayer::status(std::ostream &out)
|
||||
{
|
||||
out << "UdpLayer::status()" << std::endl;
|
||||
out << "localaddr: " << laddr << std::endl;
|
||||
out << "sockfd: " << sockfd << std::endl;
|
||||
out << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UdpLayer::reset(struct sockaddr_in &local)
|
||||
{
|
||||
std::cerr << "UdpLayer::reset()" << std::endl;
|
||||
|
||||
/* stop the old thread */
|
||||
{
|
||||
bdStackMutex stack(sockMtx); /********** LOCK MUTEX *********/
|
||||
std::cerr << "UdpLayer::reset() setting stopThread flag" << std::endl;
|
||||
stopThread = true;
|
||||
}
|
||||
|
||||
std::cerr << "UdpLayer::reset() joining" << std::endl;
|
||||
join();
|
||||
|
||||
std::cerr << "UdpLayer::reset() closing socket" << std::endl;
|
||||
closeSocket();
|
||||
|
||||
std::cerr << "UdpLayer::reset() resetting variables" << std::endl;
|
||||
laddr = local;
|
||||
errorState = 0;
|
||||
ttl = UDP_DEF_TTL;
|
||||
|
||||
std::cerr << "UdpLayer::reset() opening socket" << std::endl;
|
||||
openSocket();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int UdpLayer::closeSocket()
|
||||
{
|
||||
/* close socket if open */
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
if (sockfd > 0)
|
||||
{
|
||||
close(sockfd);
|
||||
}
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
return 1;
|
||||
}
|
||||
|
||||
void UdpLayer::run()
|
||||
{
|
||||
return recv_loop();
|
||||
}
|
||||
|
||||
/* higher level interface */
|
||||
void UdpLayer::recv_loop()
|
||||
{
|
||||
int maxsize = 16000;
|
||||
void *inbuf = malloc(maxsize);
|
||||
|
||||
int status;
|
||||
struct timeval timeout;
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* select on the socket TODO */
|
||||
fd_set rset;
|
||||
for(;;)
|
||||
{
|
||||
/* check if we need to stop */
|
||||
bool toStop = false;
|
||||
{
|
||||
bdStackMutex stack(sockMtx); /********** LOCK MUTEX *********/
|
||||
toStop = stopThread;
|
||||
}
|
||||
|
||||
if (toStop)
|
||||
{
|
||||
std::cerr << "UdpLayer::recv_loop() stopping thread" << std::endl;
|
||||
stop();
|
||||
}
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(sockfd, &rset);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000; /* 500 ms timeout */
|
||||
status = select(sockfd+1, &rset, NULL, NULL, &timeout);
|
||||
if (status > 0)
|
||||
{
|
||||
break; /* data available, go read it */
|
||||
}
|
||||
else if (status < 0)
|
||||
{
|
||||
std::cerr << "UdpLayer::recv_loop() ";
|
||||
std::cerr << "Error: " << errno << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int nsize = maxsize;
|
||||
struct sockaddr_in from;
|
||||
if (0 < receiveUdpPacket(inbuf, &nsize, from))
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::readPkt() from : " << from << std::endl;
|
||||
std::cerr << printPkt(inbuf, nsize);
|
||||
#endif
|
||||
// send to reciever.
|
||||
recv -> recvPkt(inbuf, nsize, from);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::readPkt() not ready" << from;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int UdpLayer::sendPkt(const void *data, int size, sockaddr_in &to, int ttl)
|
||||
{
|
||||
/* if ttl is different -> set it */
|
||||
if (ttl != getTTL())
|
||||
{
|
||||
setTTL(ttl);
|
||||
}
|
||||
|
||||
/* and send! */
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::sendPkt() to: " << to << std::endl;
|
||||
std::cerr << printPkt((void *) data, size);
|
||||
#endif
|
||||
sendUdpPacket(data, size, to);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* setup connections */
|
||||
int UdpLayer::openSocket()
|
||||
{
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
/* make a socket */
|
||||
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UpdStreamer::openSocket()" << std::endl;
|
||||
#endif
|
||||
/* bind to address */
|
||||
|
||||
|
||||
#ifdef UDP_LOOPBACK_TESTING
|
||||
inet_aton("127.0.0.1", &(laddr.sin_addr));
|
||||
#endif
|
||||
|
||||
#ifdef OPEN_UNIVERSAL_PORT
|
||||
struct sockaddr_in tmpaddr = laddr;
|
||||
tmpaddr.sin_addr.s_addr = 0;
|
||||
if (0 != bind(sockfd, (struct sockaddr *) (&tmpaddr), sizeof(tmpaddr)))
|
||||
#else
|
||||
if (0 != bind(sockfd, (struct sockaddr *) (&laddr), sizeof(laddr)))
|
||||
#endif
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Socket Failed to Bind to : " << laddr << std::endl;
|
||||
std::cerr << "Error: " << errno << std::endl;
|
||||
#endif
|
||||
errorState = EADDRINUSE;
|
||||
//exit(1);
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (-1 == fcntl(sockfd, F_SETFL, O_NONBLOCK))
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Failed to Make Non-Blocking" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Setup socket for broadcast. */
|
||||
int val = 1;
|
||||
if (-1 == setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(int)))
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Failed to Make Socket Broadcast" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
errorState = 0;
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Socket Bound to : " << laddr << std::endl;
|
||||
#endif
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Setting TTL to " << UDP_DEF_TTL << std::endl;
|
||||
#endif
|
||||
setTTL(UDP_DEF_TTL);
|
||||
|
||||
// start up our thread.
|
||||
{
|
||||
bdStackMutex stack(sockMtx); /********** LOCK MUTEX *********/
|
||||
stopThread = false;
|
||||
}
|
||||
start();
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int UdpLayer::setTTL(int t)
|
||||
{
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
int err = setsockopt(sockfd, IPPROTO_IP, IP_TTL, &t, sizeof(int));
|
||||
ttl = t;
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::setTTL(" << t << ") returned: " << err;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int UdpLayer::getTTL()
|
||||
{
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
int t = ttl;
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* monitoring / updates */
|
||||
int UdpLayer::okay()
|
||||
{
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
bool nonFatalError = ((errorState == 0) ||
|
||||
(errorState == EAGAIN) ||
|
||||
(errorState == EINPROGRESS));
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
if (!nonFatalError)
|
||||
{
|
||||
std::cerr << "UdpLayer::NOT okay(): Error: " << errorState << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return nonFatalError;
|
||||
}
|
||||
|
||||
int UdpLayer::tick()
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::tick()" << std::endl;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************* Internals *************************************/
|
||||
|
||||
int UdpLayer::receiveUdpPacket(void *data, int *size, struct sockaddr_in &from)
|
||||
{
|
||||
struct sockaddr_in fromaddr;
|
||||
socklen_t fromsize = sizeof(fromaddr);
|
||||
int insize = *size;
|
||||
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
insize = recvfrom(sockfd,data,insize,0,
|
||||
(struct sockaddr*)&fromaddr,&fromsize);
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
if (0 < insize)
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "receiveUdpPacket() from: " << fromaddr;
|
||||
std::cerr << " Size: " << insize;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
*size = insize;
|
||||
from = fromaddr;
|
||||
return insize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int UdpLayer::sendUdpPacket(const void *data, int size, struct sockaddr_in &to)
|
||||
{
|
||||
/* send out */
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::sendUdpPacket(): size: " << size;
|
||||
std::cerr << " To: " << to << std::endl;
|
||||
#endif
|
||||
struct sockaddr_in toaddr = to;
|
||||
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
sendto(sockfd, data, size, 0,
|
||||
(struct sockaddr *) &(toaddr),
|
||||
sizeof(toaddr));
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
128
libbitdht/src/udp/udplayer.h
Normal file
128
libbitdht/src/udp/udplayer.h
Normal file
@ -0,0 +1,128 @@
|
||||
#ifndef BITDHT_UDP_LAYER_H
|
||||
#define BITDHT_UDP_LAYER_H
|
||||
|
||||
/*
|
||||
* bitdht/udplayer.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "util/bdthreads.h"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
/****
|
||||
* #define UDP_LOOPBACK_TESTING 1
|
||||
***/
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const struct sockaddr_in &addr);
|
||||
bool operator==(const struct sockaddr_in &addr, const struct sockaddr_in &addr2);
|
||||
bool operator<(const struct sockaddr_in &addr, const struct sockaddr_in &addr2);
|
||||
|
||||
std::string printPkt(void *d, int size);
|
||||
std::string printPktOffset(unsigned int offset, void *d, unsigned int size);
|
||||
|
||||
|
||||
/* UdpLayer ..... is the bottom layer which
|
||||
* just sends and receives Udp packets.
|
||||
*/
|
||||
|
||||
class UdpReceiver
|
||||
{
|
||||
public:
|
||||
virtual ~UdpReceiver() {}
|
||||
virtual int recvPkt(void *data, int size, struct sockaddr_in &from) = 0;
|
||||
virtual int status(std::ostream &out) = 0;
|
||||
};
|
||||
|
||||
class UdpPublisher
|
||||
{
|
||||
public:
|
||||
virtual ~UdpPublisher() {}
|
||||
virtual int sendPkt(const void *data, int size, struct sockaddr_in &to, int ttl) = 0;
|
||||
};
|
||||
|
||||
|
||||
class UdpLayer: public bdThread
|
||||
{
|
||||
public:
|
||||
|
||||
UdpLayer(UdpReceiver *recv, struct sockaddr_in &local);
|
||||
virtual ~UdpLayer() { return; }
|
||||
|
||||
int reset(struct sockaddr_in &local); /* calls join, close, openSocket */
|
||||
|
||||
int status(std::ostream &out);
|
||||
|
||||
/* setup connections */
|
||||
int closeSocket();
|
||||
int openSocket();
|
||||
|
||||
/* RsThread functions */
|
||||
virtual void run(); /* called once the thread is started */
|
||||
|
||||
void recv_loop(); /* uses callback to UdpReceiver */
|
||||
|
||||
/* Higher Level Interface */
|
||||
//int readPkt(void *data, int *size, struct sockaddr_in &from);
|
||||
int sendPkt(const void *data, int size, struct sockaddr_in &to, int ttl);
|
||||
|
||||
/* monitoring / updates */
|
||||
int okay();
|
||||
int tick();
|
||||
|
||||
|
||||
/* data */
|
||||
/* internals */
|
||||
protected:
|
||||
|
||||
virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from);
|
||||
virtual int sendUdpPacket(const void *data, int size, struct sockaddr_in &to);
|
||||
|
||||
int setTTL(int t);
|
||||
int getTTL();
|
||||
|
||||
/* low level */
|
||||
private:
|
||||
|
||||
UdpReceiver *recv;
|
||||
|
||||
struct sockaddr_in laddr; /* local addr */
|
||||
|
||||
int errorState;
|
||||
int sockfd;
|
||||
int ttl;
|
||||
bool stopThread;
|
||||
|
||||
bdMutex sockMtx;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
215
libbitdht/src/udp/udpstack.cc
Normal file
215
libbitdht/src/udp/udpstack.cc
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* bitdht/udpstack.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "udpstack.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
/***
|
||||
* #define DEBUG_UDP_RECV 1
|
||||
***/
|
||||
|
||||
//#define DEBUG_UDP_RECV 1
|
||||
|
||||
|
||||
UdpStack::UdpStack(struct sockaddr_in &local)
|
||||
:udpLayer(NULL), laddr(local)
|
||||
{
|
||||
openSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
bool UdpStack::resetAddress(struct sockaddr_in &local)
|
||||
{
|
||||
return udpLayer->reset(local);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* higher level interface */
|
||||
int UdpStack::recvPkt(void *data, int size, struct sockaddr_in &from)
|
||||
{
|
||||
/* print packet information */
|
||||
#ifdef DEBUG_UDP_RECV
|
||||
std::cerr << "UdpStack::recvPkt(" << size << ") from: " << from;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
bdStackMutex stack(stackMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
std::list<UdpReceiver *>::iterator it;
|
||||
for(it = mReceivers.begin(); it != mReceivers.end(); it++)
|
||||
{
|
||||
// See if they want the packet.
|
||||
if ((*it)->recvPkt(data, size, from))
|
||||
{
|
||||
#ifdef DEBUG_UDP_RECV
|
||||
std::cerr << "UdpStack::recvPkt(" << size << ") from: " << from;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UdpStack::sendPkt(const void *data, int size, struct sockaddr_in &to, int ttl)
|
||||
{
|
||||
/* print packet information */
|
||||
#ifdef DEBUG_UDP_RECV
|
||||
std::cerr << "UdpStack::sendPkt(" << size << ") ttl: " << ttl;
|
||||
std::cerr << " to: " << to;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* send to udpLayer */
|
||||
return udpLayer->sendPkt(data, size, to, ttl);
|
||||
}
|
||||
|
||||
int UdpStack::status(std::ostream &out)
|
||||
{
|
||||
{
|
||||
bdStackMutex stack(stackMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
out << "UdpStack::status()" << std::endl;
|
||||
out << "localaddr: " << laddr << std::endl;
|
||||
out << "UdpStack::SubReceivers:" << std::endl;
|
||||
std::list<UdpReceiver *>::iterator it;
|
||||
int i = 0;
|
||||
for(it = mReceivers.begin(); it != mReceivers.end(); it++, i++)
|
||||
{
|
||||
out << "\tReceiver " << i << " --------------------" << std::endl;
|
||||
(*it)->status(out);
|
||||
}
|
||||
out << "--------------------" << std::endl;
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
udpLayer->status(out);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* setup connections */
|
||||
int UdpStack::openSocket()
|
||||
{
|
||||
udpLayer = new UdpLayer(this, laddr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* monitoring / updates */
|
||||
int UdpStack::okay()
|
||||
{
|
||||
return udpLayer->okay();
|
||||
}
|
||||
|
||||
int UdpStack::close()
|
||||
{
|
||||
/* TODO */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* add a TCPonUDP stream */
|
||||
int UdpStack::addReceiver(UdpReceiver *recv)
|
||||
{
|
||||
bdStackMutex stack(stackMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
/* check for duplicate */
|
||||
std::list<UdpReceiver *>::iterator it;
|
||||
it = std::find(mReceivers.begin(), mReceivers.end(), recv);
|
||||
if (it == mReceivers.end())
|
||||
{
|
||||
mReceivers.push_back(recv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* otherwise its already there! */
|
||||
|
||||
#ifdef DEBUG_UDP_RECV
|
||||
std::cerr << "UdpStack::addReceiver() Recv already exists!" << std::endl;
|
||||
std::cerr << "UdpStack::addReceiver() ERROR" << std::endl;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UdpStack::removeReceiver(UdpReceiver *recv)
|
||||
{
|
||||
bdStackMutex stack(stackMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
/* check for duplicate */
|
||||
std::list<UdpReceiver *>::iterator it;
|
||||
it = std::find(mReceivers.begin(), mReceivers.end(), recv);
|
||||
if (it != mReceivers.end())
|
||||
{
|
||||
mReceivers.erase(it);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* otherwise its not there! */
|
||||
|
||||
#ifdef DEBUG_UDP_RECV
|
||||
std::cerr << "UdpStack::removeReceiver() Recv dont exist!" << std::endl;
|
||||
std::cerr << "UdpStack::removeReceiver() ERROR" << std::endl;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************************/
|
||||
|
||||
UdpSubReceiver::UdpSubReceiver(UdpPublisher *pub)
|
||||
:mPublisher(pub)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int UdpSubReceiver::sendPkt(const void *data, int size, struct sockaddr_in &to, int ttl)
|
||||
{
|
||||
/* print packet information */
|
||||
#ifdef DEBUG_UDP_RECV
|
||||
std::cerr << "UdpSubReceiver::sendPkt(" << size << ") ttl: " << ttl;
|
||||
std::cerr << " to: " << to;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* send to udpLayer */
|
||||
return mPublisher->sendPkt(data, size, to, ttl);
|
||||
}
|
||||
|
||||
|
110
libbitdht/src/udp/udpstack.h
Normal file
110
libbitdht/src/udp/udpstack.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifndef BITDHT_UDP_STACK_RECEIVER_H
|
||||
#define BITDHT_UDP_STACK_RECEIVER_H
|
||||
|
||||
/*
|
||||
* bitdht/udpstack.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "util/bdthreads.h"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
|
||||
#include "udplayer.h"
|
||||
|
||||
/* UdpStackReceiver is a Generic Receiver of info from a UdpLayer class.
|
||||
* it provides a UdpReceiver class, and accepts a stack of UdpReceivers,
|
||||
* which will be iterated through (in-order) until someone accepts the packet.
|
||||
*
|
||||
* It is important to order these Receivers correctly!
|
||||
*
|
||||
* This infact becomes the holder of the UdpLayer, and all controls
|
||||
* go through the StackReceiver.
|
||||
*/
|
||||
|
||||
class UdpSubReceiver: public UdpReceiver
|
||||
{
|
||||
public:
|
||||
UdpSubReceiver(UdpPublisher *pub);
|
||||
|
||||
/* calls mPublisher->sendPkt */
|
||||
virtual int sendPkt(const void *data, int size, struct sockaddr_in &to, int ttl);
|
||||
/* callback for recved data (overloaded from UdpReceiver) */
|
||||
//virtual int recvPkt(void *data, int size, struct sockaddr_in &from) = 0;
|
||||
|
||||
UdpPublisher *mPublisher;
|
||||
};
|
||||
|
||||
|
||||
class UdpStack: public UdpReceiver, public UdpPublisher
|
||||
{
|
||||
public:
|
||||
|
||||
UdpStack(struct sockaddr_in &local);
|
||||
virtual ~UdpStack() { return; }
|
||||
|
||||
bool resetAddress(struct sockaddr_in &local);
|
||||
|
||||
|
||||
/* add in a receiver */
|
||||
int addReceiver(UdpReceiver *recv);
|
||||
int removeReceiver(UdpReceiver *recv);
|
||||
|
||||
/* Packet IO */
|
||||
/* pass-through send packets */
|
||||
virtual int sendPkt(const void *data, int size, struct sockaddr_in &to, int ttl);
|
||||
/* callback for recved data (overloaded from UdpReceiver) */
|
||||
|
||||
virtual int recvPkt(void *data, int size, struct sockaddr_in &from);
|
||||
|
||||
int status(std::ostream &out);
|
||||
|
||||
/* setup connections */
|
||||
int openSocket();
|
||||
|
||||
/* monitoring / updates */
|
||||
int okay();
|
||||
// int tick();
|
||||
|
||||
int close();
|
||||
|
||||
private:
|
||||
|
||||
UdpLayer *udpLayer;
|
||||
|
||||
bdMutex stackMtx; /* for all class data (below) */
|
||||
|
||||
struct sockaddr_in laddr; /* local addr */
|
||||
|
||||
std::list<UdpReceiver *> mReceivers;
|
||||
};
|
||||
|
||||
#endif
|
79
libbitdht/src/util/bdthreads.cc
Normal file
79
libbitdht/src/util/bdthreads.cc
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* bitdht/bdthreads.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "bdthreads.h"
|
||||
#include <unistd.h> /* for usleep() */
|
||||
|
||||
/*******
|
||||
* #define DEBUG_THREADS 1
|
||||
*******/
|
||||
|
||||
#ifdef DEBUG_THREADS
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
extern "C" void* bdthread_init(void* p)
|
||||
{
|
||||
bdThread *thread = (bdThread *) p;
|
||||
if (!thread)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
thread -> run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
pthread_t createThread(bdThread &thread)
|
||||
{
|
||||
pthread_t tid;
|
||||
void *data = (void *) (&thread);
|
||||
|
||||
thread.mMutex.lock();
|
||||
{
|
||||
pthread_create(&tid, 0, &bdthread_init, data);
|
||||
thread.mTid = tid;
|
||||
}
|
||||
thread.mMutex.unlock();
|
||||
|
||||
return tid;
|
||||
|
||||
}
|
||||
|
||||
void bdThread::join() /* waits for the the mTid thread to stop */
|
||||
{
|
||||
void *ptr;
|
||||
pthread_join(mTid, &ptr);
|
||||
}
|
||||
|
||||
void bdThread::stop()
|
||||
{
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
81
libbitdht/src/util/bdthreads.h
Normal file
81
libbitdht/src/util/bdthreads.h
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef BITDHT_THREADS_H
|
||||
#define BITDHT_THREADS_H
|
||||
|
||||
/*
|
||||
* bitdht/bdthreads.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2010 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/* Thread Wrappers */
|
||||
|
||||
class bdMutex
|
||||
{
|
||||
public:
|
||||
|
||||
bdMutex() { pthread_mutex_init(&realMutex, NULL); }
|
||||
~bdMutex() { pthread_mutex_destroy(&realMutex); }
|
||||
void lock() { pthread_mutex_lock(&realMutex); }
|
||||
void unlock() { pthread_mutex_unlock(&realMutex); }
|
||||
bool trylock() { return (0 == pthread_mutex_trylock(&realMutex)); }
|
||||
|
||||
private:
|
||||
pthread_mutex_t realMutex;
|
||||
};
|
||||
|
||||
class bdStackMutex
|
||||
{
|
||||
public:
|
||||
|
||||
bdStackMutex(bdMutex &mtx): mMtx(mtx) { mMtx.lock(); }
|
||||
~bdStackMutex() { mMtx.unlock(); }
|
||||
|
||||
private:
|
||||
bdMutex &mMtx;
|
||||
};
|
||||
|
||||
class bdThread;
|
||||
|
||||
/* to create a thread! */
|
||||
pthread_t createThread(bdThread &thread);
|
||||
|
||||
class bdThread
|
||||
{
|
||||
public:
|
||||
bdThread() { return; }
|
||||
virtual ~bdThread() { return; }
|
||||
|
||||
virtual void start() { createThread(*this); }
|
||||
virtual void run() = 0; /* called once the thread is started */
|
||||
virtual void join(); /* waits for the mTid thread to stop */
|
||||
virtual void stop(); /* calls pthread_exit() */
|
||||
|
||||
pthread_t mTid;
|
||||
bdMutex mMutex;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user