ffi-tox 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/ProjectTox-Core/AUTHORS +0 -0
  3. data/ProjectTox-Core/ChangeLog +0 -0
  4. data/ProjectTox-Core/INSTALL +370 -0
  5. data/ProjectTox-Core/INSTALL.md +455 -56
  6. data/ProjectTox-Core/Makefile.am +35 -0
  7. data/ProjectTox-Core/NEWS +0 -0
  8. data/ProjectTox-Core/README +43 -0
  9. data/ProjectTox-Core/README.md +34 -44
  10. data/ProjectTox-Core/auto_tests/Makefile.inc +110 -0
  11. data/ProjectTox-Core/auto_tests/TCP_test.c +519 -0
  12. data/ProjectTox-Core/auto_tests/assoc_test.c +160 -0
  13. data/ProjectTox-Core/auto_tests/crypto_test.c +302 -0
  14. data/ProjectTox-Core/auto_tests/dht_test.c +362 -0
  15. data/ProjectTox-Core/auto_tests/encryptsave_test.c +104 -0
  16. data/ProjectTox-Core/auto_tests/friends_test.c +238 -0
  17. data/ProjectTox-Core/auto_tests/helpers.h +15 -0
  18. data/ProjectTox-Core/auto_tests/messenger_test.c +365 -0
  19. data/ProjectTox-Core/auto_tests/network_test.c +171 -0
  20. data/ProjectTox-Core/auto_tests/onion_test.c +363 -0
  21. data/ProjectTox-Core/auto_tests/skeleton_test.c +49 -0
  22. data/ProjectTox-Core/auto_tests/tox_test.c +454 -0
  23. data/ProjectTox-Core/auto_tests/toxav_basic_test.c +597 -0
  24. data/ProjectTox-Core/auto_tests/toxav_many_test.c +402 -0
  25. data/ProjectTox-Core/autogen.sh +6 -0
  26. data/ProjectTox-Core/build/Makefile.am +14 -0
  27. data/ProjectTox-Core/configure.ac +694 -0
  28. data/ProjectTox-Core/dist-build/android-arm.sh +3 -0
  29. data/ProjectTox-Core/dist-build/android-armv7.sh +3 -0
  30. data/ProjectTox-Core/dist-build/android-build.sh +59 -0
  31. data/ProjectTox-Core/dist-build/android-mips.sh +3 -0
  32. data/ProjectTox-Core/dist-build/android-x86.sh +3 -0
  33. data/ProjectTox-Core/docs/Group-Chats.md +71 -0
  34. data/ProjectTox-Core/docs/Hardening.txt +60 -0
  35. data/ProjectTox-Core/docs/Hardening_docs.txt +30 -0
  36. data/ProjectTox-Core/docs/Prevent_Tracking.txt +160 -0
  37. data/ProjectTox-Core/docs/TCP_Network.txt +154 -0
  38. data/ProjectTox-Core/docs/TODO +62 -0
  39. data/ProjectTox-Core/docs/Tox_middle_level_network_protocol.txt +120 -0
  40. data/ProjectTox-Core/docs/av_api.md +194 -0
  41. data/ProjectTox-Core/libtoxav.pc.in +11 -0
  42. data/ProjectTox-Core/libtoxcore.pc.in +11 -0
  43. data/ProjectTox-Core/m4/ax_have_epoll.m4 +104 -0
  44. data/ProjectTox-Core/m4/ax_pthread.m4 +317 -0
  45. data/ProjectTox-Core/m4/pkg.m4 +199 -0
  46. data/ProjectTox-Core/other/DHT_bootstrap.c +121 -58
  47. data/ProjectTox-Core/other/DHTnodes +3 -0
  48. data/ProjectTox-Core/other/Makefile.inc +20 -0
  49. data/ProjectTox-Core/other/bootstrap_node_packets.c +65 -0
  50. data/ProjectTox-Core/other/tox.png +0 -0
  51. data/ProjectTox-Core/testing/DHT_test.c +170 -98
  52. data/ProjectTox-Core/testing/Makefile.inc +112 -0
  53. data/ProjectTox-Core/testing/Messenger_test.c +133 -69
  54. data/ProjectTox-Core/testing/dns3_test.c +115 -0
  55. data/ProjectTox-Core/testing/misc_tools.c +59 -13
  56. data/ProjectTox-Core/testing/nTox.c +1127 -264
  57. data/ProjectTox-Core/testing/nTox.h +10 -19
  58. data/ProjectTox-Core/testing/tox_shell.c +159 -0
  59. data/ProjectTox-Core/testing/tox_sync.c +299 -0
  60. data/ProjectTox-Core/tools/README +11 -0
  61. data/ProjectTox-Core/tools/astylerc +11 -0
  62. data/ProjectTox-Core/tools/pre-commit +17 -0
  63. data/ProjectTox-Core/toxav/Makefile.inc +36 -0
  64. data/ProjectTox-Core/toxav/codec.c +357 -0
  65. data/ProjectTox-Core/toxav/codec.h +116 -0
  66. data/ProjectTox-Core/toxav/msi.c +1949 -0
  67. data/ProjectTox-Core/toxav/msi.h +267 -0
  68. data/ProjectTox-Core/toxav/rtp.c +600 -0
  69. data/ProjectTox-Core/toxav/rtp.h +196 -0
  70. data/ProjectTox-Core/toxav/toxav.c +1148 -0
  71. data/ProjectTox-Core/toxav/toxav.h +389 -0
  72. data/ProjectTox-Core/toxcore/DHT.c +2521 -0
  73. data/ProjectTox-Core/toxcore/DHT.h +412 -0
  74. data/ProjectTox-Core/toxcore/LAN_discovery.c +322 -0
  75. data/ProjectTox-Core/{core → toxcore}/LAN_discovery.h +17 -12
  76. data/ProjectTox-Core/toxcore/Makefile.inc +67 -0
  77. data/ProjectTox-Core/toxcore/Messenger.c +3006 -0
  78. data/ProjectTox-Core/toxcore/Messenger.h +818 -0
  79. data/ProjectTox-Core/toxcore/TCP_client.c +858 -0
  80. data/ProjectTox-Core/toxcore/TCP_client.h +156 -0
  81. data/ProjectTox-Core/toxcore/TCP_server.c +1332 -0
  82. data/ProjectTox-Core/toxcore/TCP_server.h +181 -0
  83. data/ProjectTox-Core/toxcore/assoc.c +1033 -0
  84. data/ProjectTox-Core/toxcore/assoc.h +104 -0
  85. data/ProjectTox-Core/toxcore/crypto_core.c +278 -0
  86. data/ProjectTox-Core/toxcore/crypto_core.h +151 -0
  87. data/ProjectTox-Core/toxcore/friend_requests.c +175 -0
  88. data/ProjectTox-Core/toxcore/friend_requests.h +83 -0
  89. data/ProjectTox-Core/toxcore/group_chats.c +837 -0
  90. data/ProjectTox-Core/toxcore/group_chats.h +199 -0
  91. data/ProjectTox-Core/toxcore/list.c +256 -0
  92. data/ProjectTox-Core/toxcore/list.h +85 -0
  93. data/ProjectTox-Core/toxcore/logger.c +153 -0
  94. data/ProjectTox-Core/toxcore/logger.h +84 -0
  95. data/ProjectTox-Core/toxcore/misc_tools.h +70 -0
  96. data/ProjectTox-Core/toxcore/net_crypto.c +2753 -0
  97. data/ProjectTox-Core/toxcore/net_crypto.h +410 -0
  98. data/ProjectTox-Core/toxcore/network.c +979 -0
  99. data/ProjectTox-Core/toxcore/network.h +367 -0
  100. data/ProjectTox-Core/toxcore/onion.c +540 -0
  101. data/ProjectTox-Core/toxcore/onion.h +150 -0
  102. data/ProjectTox-Core/toxcore/onion_announce.c +433 -0
  103. data/ProjectTox-Core/toxcore/onion_announce.h +139 -0
  104. data/ProjectTox-Core/toxcore/onion_client.c +1347 -0
  105. data/ProjectTox-Core/toxcore/onion_client.h +253 -0
  106. data/ProjectTox-Core/toxcore/ping.c +346 -0
  107. data/ProjectTox-Core/toxcore/ping.h +47 -0
  108. data/ProjectTox-Core/toxcore/ping_array.c +162 -0
  109. data/ProjectTox-Core/toxcore/ping_array.h +75 -0
  110. data/ProjectTox-Core/toxcore/tox.c +940 -0
  111. data/ProjectTox-Core/toxcore/tox.h +734 -0
  112. data/ProjectTox-Core/toxcore/util.c +193 -0
  113. data/ProjectTox-Core/toxcore/util.h +63 -0
  114. data/ProjectTox-Core/toxdns/Makefile.inc +29 -0
  115. data/ProjectTox-Core/toxdns/toxdns.c +238 -0
  116. data/ProjectTox-Core/toxdns/toxdns.h +88 -0
  117. data/ProjectTox-Core/toxencryptsave/Makefile.inc +45 -0
  118. data/ProjectTox-Core/toxencryptsave/toxencryptsave.c +179 -0
  119. data/ProjectTox-Core/toxencryptsave/toxencryptsave.h +74 -0
  120. data/interfaces/libtox.i +2 -6
  121. data/lib/ffi-tox/libtox.rb +406 -28
  122. metadata +124 -46
  123. data/ProjectTox-Core/CMakeLists.txt +0 -50
  124. data/ProjectTox-Core/cmake/FindLIBCONFIG.cmake +0 -15
  125. data/ProjectTox-Core/cmake/FindNaCl.cmake +0 -17
  126. data/ProjectTox-Core/cmake/FindSODIUM.cmake +0 -15
  127. data/ProjectTox-Core/core/CMakeLists.txt +0 -19
  128. data/ProjectTox-Core/core/DHT.c +0 -1104
  129. data/ProjectTox-Core/core/DHT.h +0 -111
  130. data/ProjectTox-Core/core/LAN_discovery.c +0 -79
  131. data/ProjectTox-Core/core/Lossless_UDP.c +0 -755
  132. data/ProjectTox-Core/core/Lossless_UDP.h +0 -106
  133. data/ProjectTox-Core/core/Messenger.c +0 -596
  134. data/ProjectTox-Core/core/Messenger.h +0 -165
  135. data/ProjectTox-Core/core/friend_requests.c +0 -131
  136. data/ProjectTox-Core/core/friend_requests.h +0 -51
  137. data/ProjectTox-Core/core/net_crypto.c +0 -575
  138. data/ProjectTox-Core/core/net_crypto.h +0 -134
  139. data/ProjectTox-Core/core/network.c +0 -205
  140. data/ProjectTox-Core/core/network.h +0 -134
  141. data/ProjectTox-Core/docs/commands.md +0 -25
  142. data/ProjectTox-Core/docs/start_guide.de.md +0 -40
  143. data/ProjectTox-Core/docs/start_guide.md +0 -38
  144. data/ProjectTox-Core/other/CMakeLists.txt +0 -9
  145. data/ProjectTox-Core/testing/CMakeLists.txt +0 -18
  146. data/ProjectTox-Core/testing/DHT_cryptosendfiletest.c +0 -228
  147. data/ProjectTox-Core/testing/DHT_sendfiletest.c +0 -176
  148. data/ProjectTox-Core/testing/Lossless_UDP_testclient.c +0 -214
  149. data/ProjectTox-Core/testing/Lossless_UDP_testserver.c +0 -201
  150. data/ProjectTox-Core/testing/misc_tools.h +0 -29
  151. data/ProjectTox-Core/testing/nTox_win32.c +0 -387
  152. data/ProjectTox-Core/testing/nTox_win32.h +0 -40
  153. data/ProjectTox-Core/testing/rect.py +0 -45
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-tox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tristan Rice
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-30 00:00:00.000000000 Z
11
+ date: 2014-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.9.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.9.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ffi-swig-generator
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.3.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.3.2
41
41
  description: Ruby FFI bindings to Tox
@@ -45,54 +45,132 @@ extensions:
45
45
  - ext/ffi-tox/extconf.rb
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - lib/ffi-tox.rb
49
- - lib/ffi-tox/libtox.rb
50
- - interfaces/libtox.i
48
+ - ProjectTox-Core/AUTHORS
51
49
  - ProjectTox-Core/COPYING
52
- - ProjectTox-Core/CMakeLists.txt
50
+ - ProjectTox-Core/ChangeLog
51
+ - ProjectTox-Core/INSTALL
53
52
  - ProjectTox-Core/INSTALL.md
53
+ - ProjectTox-Core/Makefile.am
54
+ - ProjectTox-Core/NEWS
55
+ - ProjectTox-Core/README
54
56
  - ProjectTox-Core/README.md
55
- - ProjectTox-Core/core/DHT.c
56
- - ProjectTox-Core/core/DHT.h
57
- - ProjectTox-Core/core/LAN_discovery.c
58
- - ProjectTox-Core/core/LAN_discovery.h
59
- - ProjectTox-Core/core/Lossless_UDP.h
60
- - ProjectTox-Core/core/friend_requests.c
61
- - ProjectTox-Core/core/net_crypto.h
62
- - ProjectTox-Core/core/CMakeLists.txt
63
- - ProjectTox-Core/core/Lossless_UDP.c
64
- - ProjectTox-Core/core/Messenger.c
65
- - ProjectTox-Core/core/Messenger.h
66
- - ProjectTox-Core/core/friend_requests.h
67
- - ProjectTox-Core/core/net_crypto.c
68
- - ProjectTox-Core/core/network.c
69
- - ProjectTox-Core/core/network.h
70
- - ProjectTox-Core/other/CMakeLists.txt
57
+ - ProjectTox-Core/auto_tests/Makefile.inc
58
+ - ProjectTox-Core/auto_tests/TCP_test.c
59
+ - ProjectTox-Core/auto_tests/assoc_test.c
60
+ - ProjectTox-Core/auto_tests/crypto_test.c
61
+ - ProjectTox-Core/auto_tests/dht_test.c
62
+ - ProjectTox-Core/auto_tests/encryptsave_test.c
63
+ - ProjectTox-Core/auto_tests/friends_test.c
64
+ - ProjectTox-Core/auto_tests/helpers.h
65
+ - ProjectTox-Core/auto_tests/messenger_test.c
66
+ - ProjectTox-Core/auto_tests/network_test.c
67
+ - ProjectTox-Core/auto_tests/onion_test.c
68
+ - ProjectTox-Core/auto_tests/skeleton_test.c
69
+ - ProjectTox-Core/auto_tests/tox_test.c
70
+ - ProjectTox-Core/auto_tests/toxav_basic_test.c
71
+ - ProjectTox-Core/auto_tests/toxav_many_test.c
72
+ - ProjectTox-Core/autogen.sh
73
+ - ProjectTox-Core/build/Makefile.am
74
+ - ProjectTox-Core/configure.ac
75
+ - ProjectTox-Core/dist-build/android-arm.sh
76
+ - ProjectTox-Core/dist-build/android-armv7.sh
77
+ - ProjectTox-Core/dist-build/android-build.sh
78
+ - ProjectTox-Core/dist-build/android-mips.sh
79
+ - ProjectTox-Core/dist-build/android-x86.sh
80
+ - ProjectTox-Core/docs/Group-Chats.md
81
+ - ProjectTox-Core/docs/Hardening.txt
82
+ - ProjectTox-Core/docs/Hardening_docs.txt
83
+ - ProjectTox-Core/docs/Prevent_Tracking.txt
84
+ - ProjectTox-Core/docs/TCP_Network.txt
85
+ - ProjectTox-Core/docs/TODO
86
+ - ProjectTox-Core/docs/Tox_middle_level_network_protocol.txt
87
+ - ProjectTox-Core/docs/av_api.md
88
+ - ProjectTox-Core/libtoxav.pc.in
89
+ - ProjectTox-Core/libtoxcore.pc.in
90
+ - ProjectTox-Core/m4/ax_have_epoll.m4
91
+ - ProjectTox-Core/m4/ax_pthread.m4
92
+ - ProjectTox-Core/m4/pkg.m4
71
93
  - ProjectTox-Core/other/DHT_bootstrap.c
72
- - ProjectTox-Core/testing/DHT_sendfiletest.c
94
+ - ProjectTox-Core/other/DHTnodes
95
+ - ProjectTox-Core/other/Makefile.inc
96
+ - ProjectTox-Core/other/bootstrap_node_packets.c
97
+ - ProjectTox-Core/other/tox.png
98
+ - ProjectTox-Core/testing/DHT_test.c
99
+ - ProjectTox-Core/testing/Makefile.inc
73
100
  - ProjectTox-Core/testing/Messenger_test.c
101
+ - ProjectTox-Core/testing/dns3_test.c
74
102
  - ProjectTox-Core/testing/misc_tools.c
75
- - ProjectTox-Core/testing/rect.py
76
- - ProjectTox-Core/testing/CMakeLists.txt
77
- - ProjectTox-Core/testing/DHT_cryptosendfiletest.c
78
- - ProjectTox-Core/testing/DHT_test.c
79
- - ProjectTox-Core/testing/Lossless_UDP_testclient.c
80
- - ProjectTox-Core/testing/Lossless_UDP_testserver.c
81
- - ProjectTox-Core/testing/misc_tools.h
82
103
  - ProjectTox-Core/testing/nTox.c
83
104
  - ProjectTox-Core/testing/nTox.h
84
- - ProjectTox-Core/testing/nTox_win32.c
85
- - ProjectTox-Core/testing/nTox_win32.h
86
- - ProjectTox-Core/cmake/FindLIBCONFIG.cmake
87
- - ProjectTox-Core/cmake/FindNaCl.cmake
88
- - ProjectTox-Core/cmake/FindSODIUM.cmake
89
- - ProjectTox-Core/docs/commands.md
90
- - ProjectTox-Core/docs/start_guide.de.md
91
- - ProjectTox-Core/docs/start_guide.md
105
+ - ProjectTox-Core/testing/tox_shell.c
106
+ - ProjectTox-Core/testing/tox_sync.c
107
+ - ProjectTox-Core/tools/README
108
+ - ProjectTox-Core/tools/astylerc
109
+ - ProjectTox-Core/tools/pre-commit
110
+ - ProjectTox-Core/toxav/Makefile.inc
111
+ - ProjectTox-Core/toxav/codec.c
112
+ - ProjectTox-Core/toxav/codec.h
113
+ - ProjectTox-Core/toxav/msi.c
114
+ - ProjectTox-Core/toxav/msi.h
115
+ - ProjectTox-Core/toxav/rtp.c
116
+ - ProjectTox-Core/toxav/rtp.h
117
+ - ProjectTox-Core/toxav/toxav.c
118
+ - ProjectTox-Core/toxav/toxav.h
119
+ - ProjectTox-Core/toxcore/DHT.c
120
+ - ProjectTox-Core/toxcore/DHT.h
121
+ - ProjectTox-Core/toxcore/LAN_discovery.c
122
+ - ProjectTox-Core/toxcore/LAN_discovery.h
123
+ - ProjectTox-Core/toxcore/Makefile.inc
124
+ - ProjectTox-Core/toxcore/Messenger.c
125
+ - ProjectTox-Core/toxcore/Messenger.h
126
+ - ProjectTox-Core/toxcore/TCP_client.c
127
+ - ProjectTox-Core/toxcore/TCP_client.h
128
+ - ProjectTox-Core/toxcore/TCP_server.c
129
+ - ProjectTox-Core/toxcore/TCP_server.h
130
+ - ProjectTox-Core/toxcore/assoc.c
131
+ - ProjectTox-Core/toxcore/assoc.h
132
+ - ProjectTox-Core/toxcore/crypto_core.c
133
+ - ProjectTox-Core/toxcore/crypto_core.h
134
+ - ProjectTox-Core/toxcore/friend_requests.c
135
+ - ProjectTox-Core/toxcore/friend_requests.h
136
+ - ProjectTox-Core/toxcore/group_chats.c
137
+ - ProjectTox-Core/toxcore/group_chats.h
138
+ - ProjectTox-Core/toxcore/list.c
139
+ - ProjectTox-Core/toxcore/list.h
140
+ - ProjectTox-Core/toxcore/logger.c
141
+ - ProjectTox-Core/toxcore/logger.h
142
+ - ProjectTox-Core/toxcore/misc_tools.h
143
+ - ProjectTox-Core/toxcore/net_crypto.c
144
+ - ProjectTox-Core/toxcore/net_crypto.h
145
+ - ProjectTox-Core/toxcore/network.c
146
+ - ProjectTox-Core/toxcore/network.h
147
+ - ProjectTox-Core/toxcore/onion.c
148
+ - ProjectTox-Core/toxcore/onion.h
149
+ - ProjectTox-Core/toxcore/onion_announce.c
150
+ - ProjectTox-Core/toxcore/onion_announce.h
151
+ - ProjectTox-Core/toxcore/onion_client.c
152
+ - ProjectTox-Core/toxcore/onion_client.h
153
+ - ProjectTox-Core/toxcore/ping.c
154
+ - ProjectTox-Core/toxcore/ping.h
155
+ - ProjectTox-Core/toxcore/ping_array.c
156
+ - ProjectTox-Core/toxcore/ping_array.h
157
+ - ProjectTox-Core/toxcore/tox.c
158
+ - ProjectTox-Core/toxcore/tox.h
159
+ - ProjectTox-Core/toxcore/util.c
160
+ - ProjectTox-Core/toxcore/util.h
161
+ - ProjectTox-Core/toxdns/Makefile.inc
162
+ - ProjectTox-Core/toxdns/toxdns.c
163
+ - ProjectTox-Core/toxdns/toxdns.h
164
+ - ProjectTox-Core/toxencryptsave/Makefile.inc
165
+ - ProjectTox-Core/toxencryptsave/toxencryptsave.c
166
+ - ProjectTox-Core/toxencryptsave/toxencryptsave.h
92
167
  - ext/ffi-tox/extconf.rb
168
+ - interfaces/libtox.i
169
+ - lib/ffi-tox.rb
170
+ - lib/ffi-tox/libtox.rb
93
171
  homepage: http://github.com/d4l3k/ffi-tox
94
172
  licenses:
95
- - Simplified BSD
173
+ - MIT
96
174
  metadata: {}
97
175
  post_install_message:
98
176
  rdoc_options: []
@@ -100,17 +178,17 @@ require_paths:
100
178
  - lib
101
179
  required_ruby_version: !ruby/object:Gem::Requirement
102
180
  requirements:
103
- - - '>='
181
+ - - ">="
104
182
  - !ruby/object:Gem::Version
105
183
  version: '0'
106
184
  required_rubygems_version: !ruby/object:Gem::Requirement
107
185
  requirements:
108
- - - '>='
186
+ - - ">="
109
187
  - !ruby/object:Gem::Version
110
188
  version: '0'
111
189
  requirements: []
112
190
  rubyforge_project:
113
- rubygems_version: 2.0.3
191
+ rubygems_version: 2.2.2
114
192
  signing_key:
115
193
  specification_version: 4
116
194
  summary: Tox bindings
@@ -1,50 +0,0 @@
1
- cmake_minimum_required(VERSION 2.6.0)
2
-
3
- set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
4
-
5
- if(NOT WIN32)
6
- option(USE_NACL "Use NaCl library instead of libsodium")
7
- endif()
8
-
9
- if(USE_NACL)
10
- find_package(NaCl REQUIRED)
11
-
12
- include_directories(${NACL_INCLUDE_DIR})
13
- add_definitions(-DVANILLA_NACL)
14
-
15
- set(LINK_CRYPTO_LIBRARY ${NACL_LIBRARIES})
16
- endif()
17
-
18
- #MinGW prints more warnings for -Wall than gcc does, thus causing build to fail
19
- if(NOT WIN32)
20
- if(("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang"))
21
- message(STATUS "==== ${CMAKE_C_COMPILER_ID} detected - Adding compiler flags ====")
22
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror")
23
- endif()
24
- find_package(SODIUM REQUIRED)
25
- endif()
26
-
27
- if(NOT USE_NACL)
28
- set(LINK_CRYPTO_LIBRARY ${SODIUM_LIBRARY})
29
- endif()
30
-
31
- macro(linkCoreLibraries exe_name)
32
- add_dependencies(${exe_name} core)
33
- if(WIN32)
34
- include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/)
35
- target_link_libraries(${exe_name} core
36
- ${CMAKE_SOURCE_DIR}/sodium/lib/libsodium.a
37
- ws2_32)
38
- else()
39
- include_directories(${SODIUM_INCLUDE_DIR})
40
- target_link_libraries(${exe_name} core
41
- ${LINK_CRYPTO_LIBRARY})
42
-
43
- endif()
44
- endmacro()
45
-
46
- cmake_policy(SET CMP0011 NEW)
47
-
48
- add_subdirectory(core)
49
- add_subdirectory(testing)
50
- add_subdirectory(other)
@@ -1,15 +0,0 @@
1
- # Find LIBCONFIG
2
- #
3
- # LIBCONFIG_INCLUDE_DIR
4
- # LIBCONFIG_LIBRARY
5
- # LIBCONFIG_FOUND
6
- #
7
-
8
- FIND_PATH(LIBCONFIG_INCLUDE_DIR NAMES libconfig.h)
9
-
10
- FIND_LIBRARY(LIBCONFIG_LIBRARY NAMES config)
11
-
12
- INCLUDE(FindPackageHandleStandardArgs)
13
- FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBCONFIG DEFAULT_MSG LIBCONFIG_LIBRARY LIBCONFIG_INCLUDE_DIR)
14
-
15
- MARK_AS_ADVANCED(LIBCONFIG_INCLUDE_DIR LIBCONFIG_LIBRARY)
@@ -1,17 +0,0 @@
1
- find_path(NACL_INCLUDE_DIR crypto_box.h
2
- $ENV{NACL_INCLUDE_DIR} /usr/include/nacl/
3
- DOC "Directory which contain NaCl headers")
4
-
5
- find_path(NACL_LIBRARY_DIR libnacl.a
6
- $ENV{NACL_LIBRARY_DIR} /usr/lib/nacl
7
- DOC "Directory which contain libnacl.a, cpucycles.o, and randombytes.o")
8
-
9
- if(NACL_LIBRARY_DIR)
10
- set(NACL_LIBRARIES
11
- "${NACL_LIBRARY_DIR}/cpucycles.o"
12
- "${NACL_LIBRARY_DIR}/libnacl.a"
13
- "${NACL_LIBRARY_DIR}/randombytes.o")
14
- endif()
15
-
16
- include(FindPackageHandleStandardArgs)
17
- find_package_handle_standard_args(NaCl DEFAULT_MSG NACL_INCLUDE_DIR NACL_LIBRARY_DIR NACL_LIBRARIES)
@@ -1,15 +0,0 @@
1
- # Find SODIUM
2
- #
3
- # SODIUM_INCLUDE_DIR
4
- # SODIUM_LIBRARY
5
- # SODIUM_FOUND
6
- #
7
-
8
- FIND_PATH(SODIUM_INCLUDE_DIR NAMES sodium.h)
9
-
10
- FIND_LIBRARY(SODIUM_LIBRARY NAMES sodium)
11
-
12
- INCLUDE(FindPackageHandleStandardArgs)
13
- FIND_PACKAGE_HANDLE_STANDARD_ARGS(SODIUM DEFAULT_MSG SODIUM_LIBRARY SODIUM_INCLUDE_DIR)
14
-
15
- MARK_AS_ADVANCED(SODIUM_INCLUDE_DIR SODIUM_LIBRARY)
@@ -1,19 +0,0 @@
1
- cmake_minimum_required(VERSION 2.6.0)
2
- project(core C)
3
-
4
- if(WIN32)
5
- include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/)
6
- else(WIN32)
7
- include_directories(${SODIUM_INCLUDE_DIR})
8
- endif()
9
-
10
- set(core_sources
11
- DHT.c
12
- network.c
13
- Lossless_UDP.c
14
- net_crypto.c
15
- friend_requests.c
16
- LAN_discovery.c
17
- Messenger.c)
18
-
19
- add_library(core ${core_sources})
@@ -1,1104 +0,0 @@
1
- /* DHT.c
2
- *
3
- * An implementation of the DHT as seen in docs/DHT.txt
4
- *
5
- * Copyright (C) 2013 Tox project All Rights Reserved.
6
- *
7
- * This file is part of Tox.
8
- *
9
- * Tox is free software: you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation, either version 3 of the License, or
12
- * (at your option) any later version.
13
- *
14
- * Tox is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- * GNU General Public License for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License
20
- * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21
- *
22
- */
23
-
24
- #include "DHT.h"
25
-
26
- typedef struct {
27
- uint8_t client_id[CLIENT_ID_SIZE];
28
- IP_Port ip_port;
29
- uint32_t timestamp;
30
- uint32_t last_pinged;
31
- IP_Port ret_ip_port;/* The ip_port returned by this node for the friend
32
- (for nodes in friends_list) or us (for nodes in close_clientlist) */
33
- uint32_t ret_timestamp;
34
- } Client_data;
35
-
36
- /* maximum number of clients stored per friend. */
37
- #define MAX_FRIEND_CLIENTS 8
38
-
39
- typedef struct {
40
- uint8_t client_id[CLIENT_ID_SIZE];
41
- Client_data client_list[MAX_FRIEND_CLIENTS];
42
- uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */
43
-
44
- /*Symetric NAT hole punching stuff*/
45
- uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */
46
- uint32_t punching_index;
47
- uint32_t punching_timestamp;
48
- uint32_t recvNATping_timestamp;
49
- uint64_t NATping_id;
50
- uint32_t NATping_timestamp;
51
- } Friend;
52
-
53
- typedef struct {
54
- uint8_t client_id[CLIENT_ID_SIZE];
55
- IP_Port ip_port;
56
- } Node_format;
57
-
58
- typedef struct {
59
- IP_Port ip_port;
60
- uint64_t ping_id;
61
- uint32_t timestamp;
62
-
63
- } Pinged;
64
-
65
- /* Our client id/public key */
66
- uint8_t self_public_key[CLIENT_ID_SIZE];
67
- uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
68
-
69
- /* TODO: Move these out of here and put them into the .c file.
70
- A list of the clients mathematically closest to ours. */
71
- #define LCLIENT_LIST 32
72
- static Client_data close_clientlist[LCLIENT_LIST];
73
-
74
- static Friend * friends_list;
75
- static uint16_t num_friends;
76
-
77
- /* The list of ip ports along with the ping_id of what we sent them and a timestamp */
78
- #define LPING_ARRAY 256
79
-
80
- static Pinged pings[LPING_ARRAY];
81
-
82
- #define LSEND_NODES_ARRAY LPING_ARRAY/2
83
-
84
- static Pinged send_nodes[LSEND_NODES_ARRAY];
85
-
86
- /* Compares client_id1 and client_id2 with client_id
87
- return 0 if both are same distance
88
- return 1 if client_id1 is closer
89
- return 2 if client_id2 is closer */
90
- int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */
91
- {
92
- uint32_t i;
93
- for(i = 0; i < CLIENT_ID_SIZE; ++i) {
94
- if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i]))
95
- return 1;
96
- else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i]))
97
- return 2;
98
- }
99
- return 0;
100
- }
101
-
102
- /* check if client with client_id is already in list of length length.
103
- if it is set it's corresponding timestamp to current time.
104
- if the id is already in the list with a different ip_port, update it.
105
- return True(1) or False(0)
106
- TODO: maybe optimize this. */
107
- int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port)
108
- {
109
- uint32_t i;
110
- uint32_t temp_time = unix_time();
111
-
112
- for(i = 0; i < length; ++i) {
113
- /*If ip_port is assigned to a different client_id replace it*/
114
- if(list[i].ip_port.ip.i == ip_port.ip.i &&
115
- list[i].ip_port.port == ip_port.port) {
116
- memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
117
- }
118
-
119
- if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
120
- /* Refresh the client timestamp. */
121
- list[i].timestamp = temp_time;
122
- list[i].ip_port.ip.i = ip_port.ip.i;
123
- list[i].ip_port.port = ip_port.port;
124
- return 1;
125
- }
126
- }
127
- return 0;
128
-
129
- }
130
-
131
- /* check if client with client_id is already in node format list of length length.
132
- return True(1) or False(0) */
133
- int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
134
- {
135
- uint32_t i;
136
- for(i = 0; i < length; ++i)
137
- if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
138
- return 1;
139
- return 0;
140
- }
141
-
142
- /*Return the friend number from the client_id
143
- Return -1 if failure, number of friend if success*/
144
- static int friend_number(uint8_t * client_id)
145
- {
146
- uint32_t i;
147
- for(i = 0; i < num_friends; ++i)
148
- if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */
149
- return i;
150
- return -1;
151
- }
152
-
153
- /* the number of seconds for a non responsive node to become bad. */
154
- #define BAD_NODE_TIMEOUT 70
155
- /* the max number of nodes to send with send nodes. */
156
- #define MAX_SENT_NODES 8
157
-
158
- /* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request:
159
- put them in the nodes_list and return how many were found.
160
- TODO: Make this function much more efficient. */
161
- int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
162
- {
163
- uint32_t i, j, k;
164
- int num_nodes=0;
165
- uint32_t temp_time = unix_time();
166
- for(i = 0; i < LCLIENT_LIST; ++i)
167
- if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time &&
168
- !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) {
169
- /* if node is good and not already in list. */
170
- if(num_nodes < MAX_SENT_NODES) {
171
- memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
172
- nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
173
- num_nodes++;
174
- } else for(j = 0; j < MAX_SENT_NODES; ++j)
175
- if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) {
176
- memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
177
- nodes_list[j].ip_port = close_clientlist[i].ip_port;
178
- break;
179
- }
180
- }
181
-
182
- for(i = 0; i < num_friends; ++i)
183
- for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
184
- if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
185
- !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
186
- /* if node is good and not already in list. */
187
- if(num_nodes < MAX_SENT_NODES) {
188
- memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
189
- nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
190
- num_nodes++;
191
- } else for(k = 0; k < MAX_SENT_NODES; ++k)
192
- if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
193
- memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
194
- nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
195
- break;
196
- }
197
- }
198
- return num_nodes;
199
- }
200
-
201
- /* replace first bad (or empty) node with this one
202
- return 0 if successful
203
- return 1 if not (list contains no bad nodes) */
204
- int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) /* tested */
205
- {
206
- uint32_t i;
207
- uint32_t temp_time = unix_time();
208
- for(i = 0; i < length; ++i)
209
- if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { /* if node is bad. */
210
- memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
211
- list[i].ip_port = ip_port;
212
- list[i].timestamp = temp_time;
213
- list[i].ret_ip_port.ip.i = 0;
214
- list[i].ret_ip_port.port = 0;
215
- list[i].ret_timestamp = 0;
216
- return 0;
217
- }
218
-
219
- return 1;
220
- }
221
-
222
- /* replace the first good node that is further to the comp_client_id than that of the client_id in the list */
223
- int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port, uint8_t * comp_client_id)
224
- {
225
- uint32_t i;
226
- uint32_t temp_time = unix_time();
227
-
228
- for(i = 0; i < length; ++i)
229
- if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
230
- memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
231
- list[i].ip_port = ip_port;
232
- list[i].timestamp = temp_time;
233
- list[i].ret_ip_port.ip.i = 0;
234
- list[i].ret_ip_port.port = 0;
235
- list[i].ret_timestamp = 0;
236
- return 0;
237
- }
238
-
239
- return 1;
240
- }
241
-
242
- /* Attempt to add client with ip_port and client_id to the friends client list and close_clientlist */
243
- void addto_lists(IP_Port ip_port, uint8_t * client_id)
244
- {
245
- uint32_t i;
246
-
247
- /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */
248
- if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port))
249
- if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port))
250
- /* if we can't replace bad nodes we try replacing good ones */
251
- replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key);
252
-
253
- for(i = 0; i < num_friends; ++i)
254
- if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
255
- if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
256
- /* if we can't replace bad nodes we try replacing good ones. */
257
- replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id);
258
- }
259
-
260
- /* If client_id is a friend or us, update ret_ip_port
261
- nodeclient_id is the id of the node that sent us this info */
262
- void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id)
263
- {
264
- uint32_t i, j;
265
- uint32_t temp_time = unix_time();
266
- if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) {
267
- for(i = 0; i < LCLIENT_LIST; ++i)
268
- if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) {
269
- close_clientlist[i].ret_ip_port = ip_port;
270
- close_clientlist[i].ret_timestamp = temp_time;
271
- return;
272
- }
273
- } else
274
- for(i = 0; i < num_friends; ++i)
275
- if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0)
276
- for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
277
- if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) {
278
- friends_list[i].client_list[j].ret_ip_port = ip_port;
279
- friends_list[i].client_list[j].ret_timestamp = temp_time;
280
- return;
281
- }
282
- }
283
-
284
- /* ping timeout in seconds */
285
- #define PING_TIMEOUT 5
286
-
287
- /* check if we are currently pinging an ip_port and/or a ping_id
288
- variables with values of zero will not be checked.
289
- if we are already, return 1
290
- else return 0
291
- TODO: optimize this */
292
- int is_pinging(IP_Port ip_port, uint64_t ping_id)
293
- {
294
- uint32_t i;
295
- uint8_t pinging;
296
- uint32_t temp_time = unix_time();
297
-
298
- for(i = 0; i < LPING_ARRAY; ++i )
299
- if((pings[i].timestamp + PING_TIMEOUT) > temp_time) {
300
- pinging = 0;
301
- if(ip_port.ip.i != 0)
302
- if(pings[i].ip_port.ip.i == ip_port.ip.i &&
303
- pings[i].ip_port.port == ip_port.port)
304
- ++pinging;
305
- if(ping_id != 0)
306
- if(pings[i].ping_id == ping_id)
307
- ++pinging;
308
- if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
309
- return 1;
310
- }
311
-
312
- return 0;
313
- }
314
-
315
- /* Same as last function but for get_node requests. */
316
- int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
317
- {
318
- uint32_t i;
319
- uint8_t pinging;
320
- uint32_t temp_time = unix_time();
321
-
322
- for(i = 0; i < LSEND_NODES_ARRAY; ++i )
323
- if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) {
324
- pinging = 0;
325
- if(ip_port.ip.i != 0)
326
- if(send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
327
- send_nodes[i].ip_port.port == ip_port.port)
328
- ++pinging;
329
- if(ping_id != 0)
330
- if(send_nodes[i].ping_id == ping_id)
331
- ++pinging;
332
- if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
333
- return 1;
334
-
335
- }
336
-
337
- return 0;
338
- }
339
-
340
- /* Add a new ping request to the list of ping requests
341
- returns the ping_id to put in the ping request
342
- returns 0 if problem.
343
- TODO: optimize this */
344
- uint64_t add_pinging(IP_Port ip_port)
345
- {
346
- uint32_t i, j;
347
- uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
348
- uint32_t temp_time = unix_time();
349
-
350
- for(i = 0; i < PING_TIMEOUT; ++i )
351
- for(j = 0; j < LPING_ARRAY; ++j )
352
- if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) {
353
- pings[j].timestamp = temp_time;
354
- pings[j].ip_port = ip_port;
355
- pings[j].ping_id = ping_id;
356
- return ping_id;
357
- }
358
-
359
- return 0;
360
- }
361
-
362
- /* Same but for get node requests */
363
- uint64_t add_gettingnodes(IP_Port ip_port)
364
- {
365
- uint32_t i, j;
366
- uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
367
- uint32_t temp_time = unix_time();
368
-
369
- for(i = 0; i < PING_TIMEOUT; ++i )
370
- for(j = 0; j < LSEND_NODES_ARRAY; ++j )
371
- if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) {
372
- send_nodes[j].timestamp = temp_time;
373
- send_nodes[j].ip_port = ip_port;
374
- send_nodes[j].ping_id = ping_id;
375
- return ping_id;
376
- }
377
-
378
- return 0;
379
- }
380
-
381
- /* send a ping request
382
- Ping request only works if none has been sent to that ip/port in the last 5 seconds. */
383
- static int pingreq(IP_Port ip_port, uint8_t * public_key)
384
- {
385
- if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */
386
- return 1;
387
-
388
- if(is_pinging(ip_port, 0))
389
- return 1;
390
-
391
- uint64_t ping_id = add_pinging(ip_port);
392
- if(ping_id == 0)
393
- return 1;
394
-
395
- uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
396
- uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING];
397
- uint8_t nonce[crypto_box_NONCEBYTES];
398
- random_nonce(nonce);
399
-
400
- int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
401
- if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
402
- return -1;
403
- data[0] = 0;
404
- memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
405
- memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
406
- memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
407
-
408
- return sendpacket(ip_port, data, sizeof(data));
409
- }
410
-
411
- /* send a ping response */
412
- static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
413
- {
414
- /* check if packet is gonna be sent to ourself */
415
- if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)
416
- return 1;
417
-
418
- uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
419
- uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING];
420
- uint8_t nonce[crypto_box_NONCEBYTES];
421
- random_nonce(nonce);
422
-
423
- int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
424
- if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
425
- return -1;
426
- data[0] = 1;
427
- memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
428
- memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
429
- memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
430
-
431
- return sendpacket(ip_port, data, sizeof(data));
432
- }
433
-
434
- /* send a getnodes request */
435
- static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
436
- {
437
- /* check if packet is gonna be sent to ourself */
438
- if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)
439
- return 1;
440
-
441
- if(is_gettingnodes(ip_port, 0))
442
- return 1;
443
-
444
- uint64_t ping_id = add_gettingnodes(ip_port);
445
-
446
- if(ping_id == 0)
447
- return 1;
448
-
449
- uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
450
- uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
451
- uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
452
- uint8_t nonce[crypto_box_NONCEBYTES];
453
- random_nonce(nonce);
454
-
455
- memcpy(plain, &ping_id, sizeof(ping_id));
456
- memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
457
-
458
- int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt);
459
-
460
- if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
461
- return -1;
462
- data[0] = 2;
463
- memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
464
- memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
465
- memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
466
- return sendpacket(ip_port, data, sizeof(data));
467
- }
468
-
469
- /* send a send nodes response */
470
- static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
471
- {
472
- if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */
473
- return 1;
474
-
475
- uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
476
- + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
477
-
478
- Node_format nodes_list[MAX_SENT_NODES];
479
- int num_nodes = get_close_nodes(client_id, nodes_list);
480
-
481
- if(num_nodes == 0)
482
- return 0;
483
-
484
- uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
485
- uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
486
- uint8_t nonce[crypto_box_NONCEBYTES];
487
- random_nonce(nonce);
488
-
489
- memcpy(plain, &ping_id, sizeof(ping_id));
490
- memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
491
-
492
- int len = encrypt_data(public_key, self_secret_key, nonce, plain,
493
- sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
494
-
495
- if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
496
- return -1;
497
-
498
- data[0] = 3;
499
- memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
500
- memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
501
- memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
502
-
503
- return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
504
- }
505
-
506
- /* Packet handling functions
507
- One to handle each types of packets we receive
508
- return 0 if handled correctly, 1 if packet is bad. */
509
- int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
510
- {
511
- uint64_t ping_id;
512
- if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
513
- return 1;
514
- /* check if packet is from ourself. */
515
- if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
516
- return 1;
517
-
518
- int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
519
- packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
520
- sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
521
- if(len != sizeof(ping_id))
522
- return 1;
523
-
524
- pingres(source, packet + 1, ping_id);
525
-
526
- pingreq(source, packet + 1); /* TODO: make this smarter? */
527
-
528
- return 0;
529
- }
530
-
531
- int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
532
- {
533
- uint64_t ping_id;
534
- if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
535
- return 1;
536
- if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */
537
- return 1;
538
-
539
- int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
540
- packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
541
- sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
542
- if(len != sizeof(ping_id))
543
- return 1;
544
-
545
- if(is_pinging(source, ping_id)) {
546
- addto_lists(source, packet + 1);
547
- return 0;
548
- }
549
- return 1;
550
-
551
- }
552
-
553
- int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
554
- {
555
- uint64_t ping_id;
556
- if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
557
- return 1;
558
- /* check if packet is from ourself. */
559
- if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
560
- return 1;
561
-
562
- uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
563
-
564
- int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
565
- packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
566
- sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain);
567
-
568
- if(len != sizeof(ping_id) + CLIENT_ID_SIZE)
569
- return 1;
570
-
571
- memcpy(&ping_id, plain, sizeof(ping_id));
572
- sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id);
573
-
574
- pingreq(source, packet + 1); /* TODO: make this smarter? */
575
-
576
- return 0;
577
-
578
- }
579
-
580
- int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
581
- {
582
- uint64_t ping_id;
583
- /* TODO: make this more readable */
584
- if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
585
- + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) ||
586
- (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
587
- + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 ||
588
- length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
589
- + sizeof(Node_format) + ENCRYPTION_PADDING) {
590
- return 1;
591
- }
592
- uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
593
- + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format);
594
-
595
- uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
596
-
597
- int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
598
- packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
599
- sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain);
600
-
601
- if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format))
602
- return 1;
603
-
604
- memcpy(&ping_id, plain, sizeof(ping_id));
605
- if(!is_gettingnodes(source, ping_id))
606
- return 1;
607
-
608
- Node_format nodes_list[MAX_SENT_NODES];
609
- memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
610
-
611
- addto_lists(source, packet + 1);
612
-
613
- uint32_t i;
614
- for(i = 0; i < num_nodes; ++i) {
615
- pingreq(nodes_list[i].ip_port, nodes_list[i].client_id);
616
- returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
617
- }
618
-
619
- return 0;
620
- }
621
-
622
- /* END of packet handling functions */
623
-
624
- int DHT_addfriend(uint8_t * client_id)
625
- {
626
- Friend * temp;
627
- temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1));
628
- if(temp == NULL)
629
- return 1;
630
-
631
- friends_list = temp;
632
- memset(&friends_list[num_friends], 0, sizeof(Friend));
633
- memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE);
634
- friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int();
635
- ++num_friends;
636
- return 0;
637
- }
638
-
639
- int DHT_delfriend(uint8_t * client_id)
640
- {
641
- uint32_t i;
642
- Friend * temp;
643
- for(i = 0; i < num_friends; ++i)
644
- /* Equal */
645
- if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
646
- --num_friends;
647
- if(num_friends != i)
648
- memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE);
649
- temp = realloc(friends_list, sizeof(Friend) * (num_friends));
650
- if(temp != NULL)
651
- friends_list = temp;
652
- return 0;
653
- }
654
-
655
- return 1;
656
- }
657
-
658
- /* TODO: Optimize this. */
659
- IP_Port DHT_getfriendip(uint8_t * client_id)
660
- {
661
- uint32_t i, j;
662
- IP_Port empty = {{{0}}, 0};
663
- uint32_t temp_time = unix_time();
664
- for(i = 0; i < num_friends; ++i)
665
- /* Equal */
666
- if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
667
- for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
668
- if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 &&
669
- friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)
670
- return friends_list[i].client_list[j].ip_port;
671
-
672
- return empty;
673
- }
674
- empty.ip.i = 1;
675
- return empty;
676
-
677
- }
678
-
679
- /* The timeout after which a node is discarded completely. */
680
- #define Kill_NODE_TIMEOUT 300
681
-
682
- /* ping interval in seconds for each node in our lists. */
683
- #define PING_INTERVAL 60
684
-
685
- /* ping interval in seconds for each random sending of a get nodes request. */
686
- #define GET_NODE_INTERVAL 10
687
-
688
- /* Ping each client in the "friends" list every 60 seconds.
689
- Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */
690
- void doDHTFriends()
691
- {
692
- uint32_t i, j;
693
- uint32_t temp_time = unix_time();
694
- uint32_t rand_node;
695
- uint32_t index[MAX_FRIEND_CLIENTS];
696
-
697
- for(i = 0; i < num_friends; ++i) {
698
- uint32_t num_nodes = 0;
699
- for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
700
- if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) { /* if node is not dead. */
701
- if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
702
- pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id);
703
- friends_list[i].client_list[j].last_pinged = temp_time;
704
- }
705
- if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) { /* if node is good. */
706
- index[num_nodes] = j;
707
- ++num_nodes;
708
- }
709
- }
710
- if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
711
- rand_node = rand() % num_nodes;
712
- getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
713
- friends_list[i].client_list[index[rand_node]].client_id,
714
- friends_list[i].client_id);
715
- friends_list[i].lastgetnode = temp_time;
716
- }
717
- }
718
- }
719
-
720
- static uint32_t close_lastgetnodes;
721
-
722
- /* Ping each client in the close nodes list every 60 seconds.
723
- Send a get nodes request every 20 seconds to a random good node in the list. */
724
- void doClose() /* tested */
725
- {
726
- uint32_t i;
727
- uint32_t temp_time = unix_time();
728
- uint32_t num_nodes = 0;
729
- uint32_t rand_node;
730
- uint32_t index[LCLIENT_LIST];
731
-
732
- for(i = 0; i < LCLIENT_LIST; ++i)
733
- /* if node is not dead. */
734
- if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) {
735
- if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
736
- pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id);
737
- close_clientlist[i].last_pinged = temp_time;
738
- }
739
- /* if node is good. */
740
- if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
741
- index[num_nodes] = i;
742
- ++num_nodes;
743
- }
744
- }
745
-
746
- if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
747
- rand_node = rand() % num_nodes;
748
- getnodes(close_clientlist[index[rand_node]].ip_port,
749
- close_clientlist[index[rand_node]].client_id,
750
- self_public_key);
751
- close_lastgetnodes = temp_time;
752
- }
753
- }
754
-
755
- void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
756
- {
757
- getnodes(ip_port, public_key, self_public_key);
758
- }
759
-
760
- /* send the given packet to node with client_id
761
- returns -1 if failure */
762
- int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
763
- {
764
- uint32_t i;
765
- for(i = 0; i < LCLIENT_LIST; ++i)
766
- if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
767
- return sendpacket(close_clientlist[i].ip_port, packet, length);
768
- return -1;
769
- }
770
-
771
- /* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
772
- ip_portlist must be at least MAX_FRIEND_CLIENTS big
773
- returns the number of ips returned
774
- return 0 if we are connected to friend or if no ips were found.
775
- returns -1 if no such friend*/
776
- static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
777
- {
778
- int num_ips = 0;
779
- uint32_t i;
780
- uint32_t temp_time = unix_time();
781
- if(friend_num >= num_friends)
782
- return -1;
783
- for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
784
- /*If ip is not zero and node is good */
785
- if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 &&
786
- friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
787
- if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 )
788
- return 0;
789
- ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port;
790
- ++num_ips;
791
- }
792
- return num_ips;
793
- }
794
-
795
- /* Send the following packet to everyone who tells us they are connected to friend_id
796
- returns the number of nodes it sent the packet to */
797
- int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
798
- {
799
- uint32_t i, j;
800
- uint32_t sent = 0;
801
- uint32_t temp_time = unix_time();
802
- for(i = 0; i < num_friends; ++i)
803
- /* Equal */
804
- if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
805
- for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
806
- /*If ip is not zero and node is good */
807
- if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 &&
808
- friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time)
809
- if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length)
810
- ++sent;
811
- return sent;
812
- }
813
- return 0;
814
- }
815
-
816
- /* Send the following packet to one random person who tells us they are connected to friend_id
817
- returns the number of nodes it sent the packet to */
818
- int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
819
- {
820
- int num = friend_number(friend_id);
821
- if(num == -1)
822
- return 0;
823
-
824
- IP_Port ip_list[MAX_FRIEND_CLIENTS];
825
- int n = 0;
826
- uint32_t i;
827
- uint32_t temp_time = unix_time();
828
- for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
829
- /*If ip is not zero and node is good */
830
- if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 &&
831
- friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
832
- ip_list[n] = friends_list[num].client_list[i].ip_port;
833
- ++n;
834
- }
835
- if(n < 1)
836
- return 0;
837
- if(sendpacket(ip_list[rand() % n], packet, length) == length)
838
- return 1;
839
- return 0;
840
- }
841
-
842
- /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
843
- ip_portlist must be at least MAX_FRIEND_CLIENTS big
844
- returns the number of ips returned
845
- return 0 if we are connected to friend or if no ips were found.
846
- returns -1 if no such friend*/
847
- int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
848
- {
849
-
850
- uint32_t i;
851
- for(i = 0; i < num_friends; ++i)
852
- /* Equal */
853
- if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0)
854
- return friend_iplist(ip_portlist, i);
855
- return -1;
856
- }
857
-
858
- /*BEGINNING OF NAT PUNCHING FUNCTIONS*/
859
-
860
- int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
861
- {
862
- uint8_t data[sizeof(uint64_t) + 1];
863
- data[0] = type;
864
- memcpy(data + 1, &ping_id, sizeof(uint64_t));
865
-
866
- uint8_t packet[MAX_DATA_SIZE];
867
- int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */
868
- if(len == -1)
869
- return -1;
870
-
871
- int num = 0;
872
-
873
- if(type == 0)
874
- num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/
875
- else if(type == 1)
876
- num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/
877
- if(num == 0)
878
- return -1;
879
- return num;
880
- }
881
-
882
- /* Handle a recieved ping request for */
883
- int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
884
- {
885
- if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
886
- length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
887
- return 1;
888
- /* check if request is for us. */
889
- if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
890
- uint8_t public_key[crypto_box_PUBLICKEYBYTES];
891
- uint8_t data[MAX_DATA_SIZE];
892
- int len = handle_request(public_key, data, packet, length);
893
- if(len != sizeof(uint64_t) + 1)
894
- return 1;
895
- uint64_t ping_id;
896
- memcpy(&ping_id, data + 1, sizeof(uint64_t));
897
-
898
- int friendnumber = friend_number(public_key);
899
- if(friendnumber == -1)
900
- return 1;
901
-
902
- if(data[0] == 0) {
903
- send_NATping(public_key, ping_id, 1); /*1 is reply*/
904
- friends_list[friendnumber].recvNATping_timestamp = unix_time();
905
- return 0;
906
- } else if (data[0] == 1)
907
- if(friends_list[friendnumber].NATping_id == ping_id) {
908
- friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int();
909
- friends_list[friendnumber].hole_punching = 1;
910
- return 0;
911
- }
912
- return 1;
913
- }
914
- /* if request is not for us, try routing it. */
915
- else if(route_packet(packet + 1, packet, length) == length)
916
- return 0;
917
- return 0;
918
- }
919
-
920
- /*Get the most common ip in the ip_portlist
921
- Only return ip if it appears in list min_num or more
922
- len must not be bigger than MAX_FRIEND_CLIENTS
923
- return ip of 0 if failure */
924
- static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
925
- {
926
- IP zero = {{0}};
927
- if(len > MAX_FRIEND_CLIENTS)
928
- return zero;
929
-
930
- uint32_t i, j;
931
- uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
932
- for(i = 0; i < len; ++i) {
933
- for(j = 0; j < len; ++j)
934
- if(ip_portlist[i].ip.i == ip_portlist[j].ip.i)
935
- ++numbers[i];
936
- if(numbers[i] >= min_num)
937
- return ip_portlist[i].ip;
938
- }
939
- return zero;
940
- }
941
-
942
- /*Return all the ports for one ip in a list
943
- portlist must be at least len long
944
- where len is the length of ip_portlist
945
- returns the number of ports and puts the list of ports in portlist*/
946
- static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip)
947
- {
948
- uint32_t i;
949
- uint16_t num = 0;
950
- for(i = 0; i < len; ++i)
951
- if(ip_portlist[i].ip.i == ip.i) {
952
- portlist[num] = ntohs(ip_portlist[i].port);
953
- ++num;
954
- }
955
- return num;
956
- }
957
-
958
- #define MAX_PUNCHING_PORTS 32
959
-
960
- static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num)
961
- {
962
- if(numports > MAX_FRIEND_CLIENTS || numports == 0)
963
- return;
964
- uint32_t i;
965
- uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
966
- for(i = friends_list[friend_num].punching_index; i != top; i++) {
967
- /*TODO: improve port guessing algorithm*/
968
- uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
969
- IP_Port pinging = {ip, htons(port)};
970
- pingreq(pinging, friends_list[friend_num].client_id);
971
- }
972
- friends_list[friend_num].punching_index = i;
973
- }
974
-
975
- /*Interval in seconds between punching attempts*/
976
- #define PUNCH_INTERVAL 10
977
-
978
- static void doNAT()
979
- {
980
- uint32_t i;
981
- uint32_t temp_time = unix_time();
982
- for(i = 0; i < num_friends; ++i) {
983
- IP_Port ip_list[MAX_FRIEND_CLIENTS];
984
- int num = friend_iplist(ip_list, i);
985
- /*If we are connected to friend or if friend is not online don't try to hole punch with him*/
986
- if(num < MAX_FRIEND_CLIENTS/2)
987
- continue;
988
-
989
-
990
- if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
991
- send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
992
- friends_list[i].NATping_timestamp = temp_time;
993
- }
994
- if(friends_list[i].hole_punching == 1 &&
995
- friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time &&
996
- friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL*2 >= temp_time) {
997
- IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
998
- if(ip.i == 0)
999
- continue;
1000
-
1001
- uint16_t port_list[MAX_FRIEND_CLIENTS];
1002
- uint16_t numports = NAT_getports(port_list, ip_list, num, ip);
1003
- punch_holes(ip, port_list, numports, i);
1004
-
1005
- friends_list[i].punching_timestamp = temp_time;
1006
- friends_list[i].hole_punching = 0;
1007
- }
1008
- }
1009
- }
1010
-
1011
- /*END OF NAT PUNCHING FUNCTIONS*/
1012
-
1013
- int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
1014
- {
1015
- switch (packet[0]) {
1016
- case 0:
1017
- return handle_pingreq(packet, length, source);
1018
-
1019
- case 1:
1020
- return handle_pingres(packet, length, source);
1021
-
1022
- case 2:
1023
- return handle_getnodes(packet, length, source);
1024
-
1025
- case 3:
1026
- return handle_sendnodes(packet, length, source);
1027
-
1028
- case 254:
1029
- return handle_NATping(packet, length, source);
1030
-
1031
- default:
1032
- return 1;
1033
-
1034
- }
1035
-
1036
- return 0;
1037
- }
1038
-
1039
- void doDHT()
1040
- {
1041
- doClose();
1042
- doDHTFriends();
1043
- doNAT();
1044
- }
1045
-
1046
- /* get the size of the DHT (for saving) */
1047
- uint32_t DHT_size()
1048
- {
1049
- return sizeof(close_clientlist) + sizeof(Friend) * num_friends;
1050
- }
1051
-
1052
- /* save the DHT in data where data is an array of size DHT_size() */
1053
- void DHT_save(uint8_t * data)
1054
- {
1055
- memcpy(data, close_clientlist, sizeof(close_clientlist));
1056
- memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends);
1057
- }
1058
-
1059
- /* load the DHT from data of size size;
1060
- return -1 if failure
1061
- return 0 if success */
1062
- int DHT_load(uint8_t * data, uint32_t size)
1063
- {
1064
- if(size < sizeof(close_clientlist))
1065
- return -1;
1066
- if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0)
1067
- return -1;
1068
- uint32_t i, j;
1069
- /* uint32_t temp_time = unix_time(); */
1070
- uint16_t temp;
1071
-
1072
- temp = (size - sizeof(close_clientlist))/sizeof(Friend);
1073
-
1074
- if(temp != 0) {
1075
- Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist));
1076
-
1077
- for(i = 0; i < temp; ++i) {
1078
- DHT_addfriend(tempfriends_list[i].client_id);
1079
- for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
1080
- if(tempfriends_list[i].client_list[j].timestamp != 0) {
1081
- getnodes(tempfriends_list[i].client_list[j].ip_port,
1082
- tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id);
1083
- }
1084
- }
1085
- }
1086
- Client_data * tempclose_clientlist = (Client_data *)data;
1087
-
1088
- for(i = 0; i < LCLIENT_LIST; ++i)
1089
- if(tempclose_clientlist[i].timestamp != 0)
1090
- DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id);
1091
- return 0;
1092
- }
1093
-
1094
- /* returns 0 if we are not connected to the DHT
1095
- returns 1 if we are */
1096
- int DHT_isconnected()
1097
- {
1098
- uint32_t i;
1099
- uint32_t temp_time = unix_time();
1100
- for(i = 0; i < LCLIENT_LIST; ++i)
1101
- if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)
1102
- return 1;
1103
- return 0;
1104
- }