ooxml_crypt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +58 -0
  5. data/Rakefile +12 -0
  6. data/bin/console +15 -0
  7. data/bin/setup +8 -0
  8. data/ext/ooxml_crypt/extconf.rb +18 -0
  9. data/ext/ooxml_crypt/ooxml_crypt.c +27 -0
  10. data/ext/ooxml_crypt/ooxml_crypt.h +7 -0
  11. data/lib/ooxml_crypt/version.rb +5 -0
  12. data/lib/ooxml_crypt.rb +75 -0
  13. data/vendor/cybozulib/.github/workflows/main.yml +12 -0
  14. data/vendor/cybozulib/.gitignore +5 -0
  15. data/vendor/cybozulib/CMakeLists.txt +6 -0
  16. data/vendor/cybozulib/COPYRIGHT +27 -0
  17. data/vendor/cybozulib/Makefile +26 -0
  18. data/vendor/cybozulib/bin/libeay32.dll +0 -0
  19. data/vendor/cybozulib/bin/libmecab.dll +0 -0
  20. data/vendor/cybozulib/bin/ssleay32.dll +0 -0
  21. data/vendor/cybozulib/common.mk +116 -0
  22. data/vendor/cybozulib/common.props +25 -0
  23. data/vendor/cybozulib/cybozulib.sln +286 -0
  24. data/vendor/cybozulib/debug.props +14 -0
  25. data/vendor/cybozulib/include/cybozu/array.hpp +197 -0
  26. data/vendor/cybozulib/include/cybozu/atoi.hpp +238 -0
  27. data/vendor/cybozulib/include/cybozu/atomic.hpp +146 -0
  28. data/vendor/cybozulib/include/cybozu/base64.hpp +210 -0
  29. data/vendor/cybozulib/include/cybozu/benchmark.hpp +212 -0
  30. data/vendor/cybozulib/include/cybozu/bfd.hpp +105 -0
  31. data/vendor/cybozulib/include/cybozu/bit_operation.hpp +139 -0
  32. data/vendor/cybozulib/include/cybozu/bitvector.hpp +358 -0
  33. data/vendor/cybozulib/include/cybozu/condition_variable.hpp +113 -0
  34. data/vendor/cybozulib/include/cybozu/condition_variable_cs.hpp +74 -0
  35. data/vendor/cybozulib/include/cybozu/config.hpp +392 -0
  36. data/vendor/cybozulib/include/cybozu/critical_section.hpp +60 -0
  37. data/vendor/cybozulib/include/cybozu/crypto.hpp +321 -0
  38. data/vendor/cybozulib/include/cybozu/csucvector.hpp +624 -0
  39. data/vendor/cybozulib/include/cybozu/csv.hpp +294 -0
  40. data/vendor/cybozulib/include/cybozu/data_type.hpp +27 -0
  41. data/vendor/cybozulib/include/cybozu/endian.hpp +224 -0
  42. data/vendor/cybozulib/include/cybozu/env.hpp +63 -0
  43. data/vendor/cybozulib/include/cybozu/event.hpp +122 -0
  44. data/vendor/cybozulib/include/cybozu/exception.hpp +253 -0
  45. data/vendor/cybozulib/include/cybozu/file.hpp +626 -0
  46. data/vendor/cybozulib/include/cybozu/fmindex.hpp +291 -0
  47. data/vendor/cybozulib/include/cybozu/format.hpp +93 -0
  48. data/vendor/cybozulib/include/cybozu/frequency.hpp +264 -0
  49. data/vendor/cybozulib/include/cybozu/hash.hpp +67 -0
  50. data/vendor/cybozulib/include/cybozu/inttype.hpp +174 -0
  51. data/vendor/cybozulib/include/cybozu/itoa.hpp +336 -0
  52. data/vendor/cybozulib/include/cybozu/json.hpp +120 -0
  53. data/vendor/cybozulib/include/cybozu/line_stream.hpp +149 -0
  54. data/vendor/cybozulib/include/cybozu/link_libeay32.hpp +21 -0
  55. data/vendor/cybozulib/include/cybozu/link_mpir.hpp +18 -0
  56. data/vendor/cybozulib/include/cybozu/link_ssleay32.hpp +19 -0
  57. data/vendor/cybozulib/include/cybozu/log.hpp +237 -0
  58. data/vendor/cybozulib/include/cybozu/minixml.hpp +452 -0
  59. data/vendor/cybozulib/include/cybozu/mmap.hpp +143 -0
  60. data/vendor/cybozulib/include/cybozu/mutex.hpp +144 -0
  61. data/vendor/cybozulib/include/cybozu/nlp/mecab.hpp +96 -0
  62. data/vendor/cybozulib/include/cybozu/nlp/plsi.hpp +315 -0
  63. data/vendor/cybozulib/include/cybozu/nlp/random.hpp +74 -0
  64. data/vendor/cybozulib/include/cybozu/nlp/sparse.hpp +529 -0
  65. data/vendor/cybozulib/include/cybozu/nlp/svd.hpp +486 -0
  66. data/vendor/cybozulib/include/cybozu/nlp/tfidf.hpp +226 -0
  67. data/vendor/cybozulib/include/cybozu/nlp/top_score.hpp +75 -0
  68. data/vendor/cybozulib/include/cybozu/option.hpp +743 -0
  69. data/vendor/cybozulib/include/cybozu/parallel.hpp +88 -0
  70. data/vendor/cybozulib/include/cybozu/pcg.hpp +72 -0
  71. data/vendor/cybozulib/include/cybozu/process.hpp +324 -0
  72. data/vendor/cybozulib/include/cybozu/quit_signal_handler.hpp +66 -0
  73. data/vendor/cybozulib/include/cybozu/random_generator.hpp +144 -0
  74. data/vendor/cybozulib/include/cybozu/regex.hpp +463 -0
  75. data/vendor/cybozulib/include/cybozu/select8.hpp +279 -0
  76. data/vendor/cybozulib/include/cybozu/serializer.hpp +363 -0
  77. data/vendor/cybozulib/include/cybozu/sha1.hpp +209 -0
  78. data/vendor/cybozulib/include/cybozu/sha2.hpp +506 -0
  79. data/vendor/cybozulib/include/cybozu/siphash.hpp +105 -0
  80. data/vendor/cybozulib/include/cybozu/socket.hpp +785 -0
  81. data/vendor/cybozulib/include/cybozu/ssl.hpp +203 -0
  82. data/vendor/cybozulib/include/cybozu/stacktrace.hpp +291 -0
  83. data/vendor/cybozulib/include/cybozu/stream.hpp +269 -0
  84. data/vendor/cybozulib/include/cybozu/string.hpp +1746 -0
  85. data/vendor/cybozulib/include/cybozu/string_operation.hpp +365 -0
  86. data/vendor/cybozulib/include/cybozu/sucvector.hpp +378 -0
  87. data/vendor/cybozulib/include/cybozu/test.hpp +373 -0
  88. data/vendor/cybozulib/include/cybozu/thread.hpp +229 -0
  89. data/vendor/cybozulib/include/cybozu/time.hpp +281 -0
  90. data/vendor/cybozulib/include/cybozu/tls.hpp +115 -0
  91. data/vendor/cybozulib/include/cybozu/unordered_map.hpp +13 -0
  92. data/vendor/cybozulib/include/cybozu/unordered_set.hpp +13 -0
  93. data/vendor/cybozulib/include/cybozu/v128.hpp +376 -0
  94. data/vendor/cybozulib/include/cybozu/wavelet_matrix.hpp +345 -0
  95. data/vendor/cybozulib/include/cybozu/xorshift.hpp +189 -0
  96. data/vendor/cybozulib/include/cybozu/zlib.hpp +325 -0
  97. data/vendor/cybozulib/include/sais.hxx +364 -0
  98. data/vendor/cybozulib/misc/make_select8tbl.cpp +26 -0
  99. data/vendor/cybozulib/mk.bat +37 -0
  100. data/vendor/cybozulib/readme.md +29 -0
  101. data/vendor/cybozulib/release.props +12 -0
  102. data/vendor/cybozulib/sample/Makefile +30 -0
  103. data/vendor/cybozulib/sample/csucvector_smpl.cpp +42 -0
  104. data/vendor/cybozulib/sample/data/svd/org/test1.S +4 -0
  105. data/vendor/cybozulib/sample/data/svd/org/test1.U +4 -0
  106. data/vendor/cybozulib/sample/data/svd/org/test1.V +6 -0
  107. data/vendor/cybozulib/sample/data/svd/test1 +4 -0
  108. data/vendor/cybozulib/sample/data/svd/test2 +4 -0
  109. data/vendor/cybozulib/sample/desymbol.cpp +127 -0
  110. data/vendor/cybozulib/sample/exception_smpl.cpp +46 -0
  111. data/vendor/cybozulib/sample/fmindex_smpl.cpp +231 -0
  112. data/vendor/cybozulib/sample/log_smpl.cpp +19 -0
  113. data/vendor/cybozulib/sample/mecab_smpl.cpp +37 -0
  114. data/vendor/cybozulib/sample/option2_smpl.cpp +68 -0
  115. data/vendor/cybozulib/sample/option_smpl.cpp +42 -0
  116. data/vendor/cybozulib/sample/plsi_smpl.cpp +207 -0
  117. data/vendor/cybozulib/sample/proj/exception_smpl.vcproj +184 -0
  118. data/vendor/cybozulib/sample/proj/mecab_smpl.vcproj +184 -0
  119. data/vendor/cybozulib/sample/proj/ssl_smpl/ssl_smpl.vcxproj +85 -0
  120. data/vendor/cybozulib/sample/proj/ssl_smpl.vcproj +347 -0
  121. data/vendor/cybozulib/sample/proj/stacktrace_smpl/stacktrace_smpl.vcxproj +85 -0
  122. data/vendor/cybozulib/sample/proj/svd_smpl.vcproj +184 -0
  123. data/vendor/cybozulib/sample/quit_signal_handler.cpp +30 -0
  124. data/vendor/cybozulib/sample/serializer_smpl.cpp +196 -0
  125. data/vendor/cybozulib/sample/socket_smpl.cpp +82 -0
  126. data/vendor/cybozulib/sample/ssl_smpl.cpp +39 -0
  127. data/vendor/cybozulib/sample/stacktrace_smpl.cpp +52 -0
  128. data/vendor/cybozulib/sample/svd_bench_smpl.cpp +143 -0
  129. data/vendor/cybozulib/sample/svd_smpl.cpp +94 -0
  130. data/vendor/cybozulib/sample/wm_bench_smpl.cpp +182 -0
  131. data/vendor/cybozulib/sample/zlib_smpl.cpp +41 -0
  132. data/vendor/cybozulib/src/Makefile +8 -0
  133. data/vendor/cybozulib/src/base/Makefile +19 -0
  134. data/vendor/cybozulib/test/Makefile +12 -0
  135. data/vendor/cybozulib/test/base/Makefile +37 -0
  136. data/vendor/cybozulib/test/base/array_test.cpp +173 -0
  137. data/vendor/cybozulib/test/base/atoi_test.cpp +774 -0
  138. data/vendor/cybozulib/test/base/atomic_test.cpp +49 -0
  139. data/vendor/cybozulib/test/base/base64_test.cpp +113 -0
  140. data/vendor/cybozulib/test/base/bit_operation_test.cpp +134 -0
  141. data/vendor/cybozulib/test/base/bitvector_test.cpp +204 -0
  142. data/vendor/cybozulib/test/base/condition_variable_cs_test.cpp +92 -0
  143. data/vendor/cybozulib/test/base/condition_variable_test.cpp +88 -0
  144. data/vendor/cybozulib/test/base/config_test.cpp +236 -0
  145. data/vendor/cybozulib/test/base/crypto_test.cpp +122 -0
  146. data/vendor/cybozulib/test/base/csucvector_test.cpp +63 -0
  147. data/vendor/cybozulib/test/base/csv_test.cpp +182 -0
  148. data/vendor/cybozulib/test/base/data/a.xml +26 -0
  149. data/vendor/cybozulib/test/base/endian_test.cpp +56 -0
  150. data/vendor/cybozulib/test/base/env_test.cpp +22 -0
  151. data/vendor/cybozulib/test/base/event_test.cpp +41 -0
  152. data/vendor/cybozulib/test/base/file_test.cpp +233 -0
  153. data/vendor/cybozulib/test/base/fmindex_test.cpp +118 -0
  154. data/vendor/cybozulib/test/base/format_test.cpp +12 -0
  155. data/vendor/cybozulib/test/base/frequency_test.cpp +104 -0
  156. data/vendor/cybozulib/test/base/itoa_test.cpp +522 -0
  157. data/vendor/cybozulib/test/base/line_stream_test.cpp +208 -0
  158. data/vendor/cybozulib/test/base/mecab_test.cpp +41 -0
  159. data/vendor/cybozulib/test/base/minixml_test.cpp +103 -0
  160. data/vendor/cybozulib/test/base/mmap_test.cpp +15 -0
  161. data/vendor/cybozulib/test/base/option_test.cpp +487 -0
  162. data/vendor/cybozulib/test/base/parallel_test.cpp +48 -0
  163. data/vendor/cybozulib/test/base/proj/array_test/array_test.vcxproj +86 -0
  164. data/vendor/cybozulib/test/base/proj/atoi_test/atoi_test.vcxproj +86 -0
  165. data/vendor/cybozulib/test/base/proj/atomic_test/atomic_test.vcxproj +86 -0
  166. data/vendor/cybozulib/test/base/proj/base64_test/base64_test.vcxproj +86 -0
  167. data/vendor/cybozulib/test/base/proj/condition_variable_cs_test/condition_variable_cs_test.vcxproj +86 -0
  168. data/vendor/cybozulib/test/base/proj/condition_variable_test/condition_variable_test.vcxproj +86 -0
  169. data/vendor/cybozulib/test/base/proj/config_test/config_test.vcxproj +86 -0
  170. data/vendor/cybozulib/test/base/proj/csv_test/csv_test.vcxproj +86 -0
  171. data/vendor/cybozulib/test/base/proj/endian_test/endian_test.vcxproj +86 -0
  172. data/vendor/cybozulib/test/base/proj/env_test/env_test.vcxproj +86 -0
  173. data/vendor/cybozulib/test/base/proj/event_test/event_test.vcxproj +86 -0
  174. data/vendor/cybozulib/test/base/proj/file_test/file_test.vcxproj +86 -0
  175. data/vendor/cybozulib/test/base/proj/itoa_test/itoa_test.vcxproj +86 -0
  176. data/vendor/cybozulib/test/base/proj/mecab_test/mecab_test.vcxproj +88 -0
  177. data/vendor/cybozulib/test/base/proj/minixml_test/minixml_test.vcxproj +86 -0
  178. data/vendor/cybozulib/test/base/proj/mmap_test/mmap_test.vcxproj +86 -0
  179. data/vendor/cybozulib/test/base/proj/serializer_test/serializer_test.vcxproj +86 -0
  180. data/vendor/cybozulib/test/base/proj/sha1_test/sha1_test.vcxproj +86 -0
  181. data/vendor/cybozulib/test/base/proj/stream_test/stream_test.vcxproj +86 -0
  182. data/vendor/cybozulib/test/base/proj/string_operation_test/string_operation_test.vcxproj +86 -0
  183. data/vendor/cybozulib/test/base/proj/string_test/string_test.vcxproj +86 -0
  184. data/vendor/cybozulib/test/base/proj/thread_test/thread_test.vcxproj +86 -0
  185. data/vendor/cybozulib/test/base/proj/time_test/time_test.vcxproj +86 -0
  186. data/vendor/cybozulib/test/base/proj/tls_test/tls_test.vcxproj +86 -0
  187. data/vendor/cybozulib/test/base/proj/zlib_test/zlib_test.vcxproj +86 -0
  188. data/vendor/cybozulib/test/base/random_generator_test.cpp +28 -0
  189. data/vendor/cybozulib/test/base/regex_test.cpp +74 -0
  190. data/vendor/cybozulib/test/base/serializer_test.cpp +483 -0
  191. data/vendor/cybozulib/test/base/sha1_test.cpp +61 -0
  192. data/vendor/cybozulib/test/base/sha2_test.cpp +191 -0
  193. data/vendor/cybozulib/test/base/siphash_test.cpp +33 -0
  194. data/vendor/cybozulib/test/base/socket_test.cpp +76 -0
  195. data/vendor/cybozulib/test/base/stream_test.cpp +101 -0
  196. data/vendor/cybozulib/test/base/string_operation_test.cpp +340 -0
  197. data/vendor/cybozulib/test/base/string_test.cpp +1705 -0
  198. data/vendor/cybozulib/test/base/sucvector_test.cpp +312 -0
  199. data/vendor/cybozulib/test/base/thread_test.cpp +62 -0
  200. data/vendor/cybozulib/test/base/time_test.cpp +164 -0
  201. data/vendor/cybozulib/test/base/tls_test.cpp +50 -0
  202. data/vendor/cybozulib/test/base/wavelet_matrix_test.cpp +145 -0
  203. data/vendor/cybozulib/test/base/zlib_test.cpp +371 -0
  204. data/vendor/cybozulib/test/nlp/Makefile +27 -0
  205. data/vendor/cybozulib/test/nlp/proj/random_test.vcproj +184 -0
  206. data/vendor/cybozulib/test/nlp/proj/sparse_test.vcproj +184 -0
  207. data/vendor/cybozulib/test/nlp/proj/svd_test.vcproj +184 -0
  208. data/vendor/cybozulib/test/nlp/random_test.cpp +62 -0
  209. data/vendor/cybozulib/test/nlp/sparse_test.cpp +347 -0
  210. data/vendor/cybozulib/test/nlp/svd_test.cpp +234 -0
  211. data/vendor/cybozulib/test/nlp/top_score_test.cpp +40 -0
  212. data/vendor/cybozulib/tool/create_vcproj.py +186 -0
  213. data/vendor/cybozulib/tool/vcproj_tmpl.py +185 -0
  214. data/vendor/msoffice/COPYRIGHT +27 -0
  215. data/vendor/msoffice/Makefile +29 -0
  216. data/vendor/msoffice/bin/64/msoc.dll +0 -0
  217. data/vendor/msoffice/bin/64/msocsample.exe +0 -0
  218. data/vendor/msoffice/bin/64/msoffice-crypt.exe +0 -0
  219. data/vendor/msoffice/bin/msoc.dll +0 -0
  220. data/vendor/msoffice/bin/msocsample.exe +0 -0
  221. data/vendor/msoffice/bin/msoffice-crypt.exe +0 -0
  222. data/vendor/msoffice/common.mk +71 -0
  223. data/vendor/msoffice/common.props +26 -0
  224. data/vendor/msoffice/debug.props +14 -0
  225. data/vendor/msoffice/include/attack.hpp +211 -0
  226. data/vendor/msoffice/include/cfb.hpp +777 -0
  227. data/vendor/msoffice/include/crypto_util.hpp +450 -0
  228. data/vendor/msoffice/include/custom_sha1.hpp +342 -0
  229. data/vendor/msoffice/include/decode.hpp +240 -0
  230. data/vendor/msoffice/include/encode.hpp +221 -0
  231. data/vendor/msoffice/include/make_dataspace.hpp +316 -0
  232. data/vendor/msoffice/include/msoc.h +129 -0
  233. data/vendor/msoffice/include/resource.hpp +7 -0
  234. data/vendor/msoffice/include/standard_encryption.hpp +145 -0
  235. data/vendor/msoffice/include/uint32vec.hpp +179 -0
  236. data/vendor/msoffice/include/util.hpp +212 -0
  237. data/vendor/msoffice/lib/.emptydir +0 -0
  238. data/vendor/msoffice/misc/decrypt-xls.vbs +46 -0
  239. data/vendor/msoffice/mk.bat +1 -0
  240. data/vendor/msoffice/mkdll.bat +3 -0
  241. data/vendor/msoffice/msoc.def +13 -0
  242. data/vendor/msoffice/msocsample.py +178 -0
  243. data/vendor/msoffice/msoffice12.sln +31 -0
  244. data/vendor/msoffice/readme.md +110 -0
  245. data/vendor/msoffice/release.props +28 -0
  246. data/vendor/msoffice/src/Makefile +19 -0
  247. data/vendor/msoffice/src/attack.cpp +124 -0
  248. data/vendor/msoffice/src/cfb_test.cpp +77 -0
  249. data/vendor/msoffice/src/minisample.c +54 -0
  250. data/vendor/msoffice/src/msocdll.cpp +276 -0
  251. data/vendor/msoffice/src/msocsample.c +136 -0
  252. data/vendor/msoffice/src/msoffice-crypt.cpp +219 -0
  253. data/vendor/msoffice/src/proj/attack/attack.vcxproj +88 -0
  254. data/vendor/msoffice/src/proj/main/msoffice-crypt.vcxproj +88 -0
  255. data/vendor/msoffice/src/sha1.cpp +234 -0
  256. data/vendor/msoffice/test/Makefile +20 -0
  257. data/vendor/msoffice/test/cfb_test.cpp +74 -0
  258. data/vendor/msoffice/test/hash_test.cpp +59 -0
  259. data/vendor/msoffice/test/proj/cfb/cfb_test.vcxproj +90 -0
  260. data/vendor/msoffice/test/proj/hash/hash_test.vcxproj +90 -0
  261. data/vendor/msoffice/test/sampl.bat +8 -0
  262. data/vendor/msoffice/test_all.py +46 -0
  263. data/vendor/update +4 -0
  264. metadata +351 -0
@@ -0,0 +1,785 @@
1
+ #pragma once
2
+ /**
3
+ @file
4
+ @brief tiny socket class
5
+
6
+ @author MITSUNARI Shigeo(@herumi)
7
+ @author MITSUNARI Shigeo
8
+ @remark mingw requires -lws2_32 option
9
+ */
10
+ #include <errno.h>
11
+ #include <assert.h>
12
+ #include <stdio.h>
13
+ #ifdef _WIN32
14
+ #ifndef WIN32_LEAN_AND_MEAN
15
+ #define WIN32_LEAN_AND_MEAN
16
+ #endif
17
+ #include <windows.h>
18
+ #include <winsock2.h>
19
+ #include <ws2tcpip.h> // for socklen_t
20
+ #ifdef _MSC_VER
21
+ #pragma comment(lib, "ws2_32.lib")
22
+ #pragma comment(lib, "iphlpapi.lib")
23
+ #pragma warning(push)
24
+ #pragma warning(disable : 4127) // constant condition
25
+ #endif
26
+ #else
27
+ #include <unistd.h>
28
+ #include <sys/socket.h>
29
+ #include <sys/ioctl.h>
30
+ #include <netinet/tcp.h>
31
+ #include <arpa/inet.h>
32
+ #include <netdb.h>
33
+ #include <memory.h>
34
+ #include <signal.h>
35
+ #endif
36
+ #ifndef NDEBUG
37
+ #include <stdio.h>
38
+ #endif
39
+
40
+ #include <cybozu/atomic.hpp>
41
+ #include <cybozu/exception.hpp>
42
+ #include <cybozu/itoa.hpp>
43
+ #include <string>
44
+
45
+ #ifdef __linux__
46
+ // #define CYBOZU_SOCKET_USE_EPOLL
47
+ #include <sys/epoll.h>
48
+ #endif
49
+
50
+ namespace cybozu {
51
+
52
+ #ifdef _MSC_VER
53
+ struct NetErrorNo : public cybozu::ErrorNo {
54
+ NetErrorNo(NativeErrorNo err)
55
+ : cybozu::ErrorNo(err)
56
+ {
57
+ }
58
+ NetErrorNo()
59
+ : cybozu::ErrorNo(WSAGetLastError())
60
+ {
61
+ }
62
+ };
63
+ #else
64
+ typedef cybozu::ErrorNo NetErrorNo;
65
+ #endif
66
+
67
+ #ifdef CYBOZU_SOCKET_USE_EPOLL
68
+
69
+ namespace experimental {
70
+
71
+ struct EpollEvent {
72
+ struct epoll_event ev_;
73
+ EpollEvent()
74
+ {
75
+ memset(&ev_, 0, sizeof(ev_));
76
+ }
77
+ void set(int fd, uint32_t events = EPOLLIN)
78
+ {
79
+ ev_.events = events;
80
+ ev_.data.fd = fd;
81
+ }
82
+ int getFd() const { return ev_.data.fd; }
83
+ };
84
+
85
+ class Epoll {
86
+ int efd_;
87
+ bool verify(const char *msg, int ret, int *err) const {
88
+ if (ret >= 0) return true;
89
+ if (err == 0) throw cybozu::Exception(msg) << cybozu::NetErrorNo();
90
+ *err = errno;
91
+ return false;
92
+ }
93
+ public:
94
+ Epoll() : efd_(-1) {}
95
+ bool init(int *err = 0)
96
+ {
97
+ efd_ = ::epoll_create1(0);
98
+ return verify("Epoll:init", efd_, err);
99
+ }
100
+ ~Epoll()
101
+ {
102
+ if (efd_ >= 0) ::close(efd_);
103
+ }
104
+ /*
105
+ throw if err == NULL
106
+ */
107
+ bool ctrl(int op, int fd, EpollEvent *ev, int *err = 0) {
108
+ int ret = ::epoll_ctl(efd_, op, fd, &ev->ev_);
109
+ return verify("Epoll:ctrl", ret, err);
110
+ }
111
+ bool add(int fd, uint32_t events = EPOLLIN, int *err = 0) {
112
+ EpollEvent ev;
113
+ ev.set(fd, events);
114
+ return ctrl(EPOLL_CTL_ADD, fd, &ev, err);
115
+ }
116
+ bool del(int fd, int *err = 0) {
117
+ return ctrl(EPOLL_CTL_DEL, fd, NULL, err);
118
+ }
119
+ /*
120
+ msec : 0 : block
121
+ */
122
+ int wait(EpollEvent *ev, int maxEv, int msec = 0)
123
+ {
124
+ /*
125
+ 0 : return immediately
126
+ -1 : block indefinitely
127
+ */
128
+ if (msec == 0) {
129
+ msec = -1;
130
+ } else if (msec == -1) {
131
+ msec = 0;
132
+ }
133
+ int ret = ::epoll_wait(efd_, &ev->ev_, maxEv, msec);
134
+ if (ret == 0) return 0; // timeout
135
+ if (ret < 0) return -errno;
136
+ return ret;
137
+ }
138
+ };
139
+
140
+ struct AutoLock {
141
+ Epoll& ep_;
142
+ int fd_;
143
+ AutoLock(Epoll& ep, int fd, int events = EPOLLIN)
144
+ : ep_(ep)
145
+ , fd_(fd)
146
+ {
147
+ ep_.add(fd, events);
148
+ }
149
+ ~AutoLock()
150
+ {
151
+ int err;
152
+ ep_.del(fd_, &err);
153
+ }
154
+ };
155
+
156
+ } // cybozu::experimental
157
+ #endif
158
+
159
+ namespace ssl {
160
+ class ClientSocket;
161
+ };
162
+
163
+ namespace socket_local {
164
+
165
+ #ifdef _WIN32
166
+ typedef SOCKET SocketHandle;
167
+ #else
168
+ typedef int SocketHandle;
169
+ #endif
170
+
171
+ struct InitTerm {
172
+ /** call once for init */
173
+ InitTerm()
174
+ {
175
+ #ifdef _WIN32
176
+ WSADATA data;
177
+ int err = ::WSAStartup(MAKEWORD(2, 2), &data);
178
+ if (err) {
179
+ fprintf(stderr, "WSAStartup failed : %d\n", err);
180
+ exit(1);
181
+ }
182
+ #else
183
+ ::signal(SIGPIPE, SIG_IGN);
184
+ #endif
185
+ }
186
+ /** call once for term */
187
+ ~InitTerm()
188
+ {
189
+ #ifdef _WIN32
190
+ ::WSACleanup();
191
+ #endif
192
+ }
193
+ void dummyCall() { }
194
+ };
195
+
196
+ template<int dummy = 0>
197
+ struct InstanceIsHere { static InitTerm it_; };
198
+
199
+ template<int dummy>
200
+ InitTerm InstanceIsHere<dummy>::it_;
201
+
202
+ struct DummyCall {
203
+ DummyCall() { InstanceIsHere<>::it_.dummyCall(); }
204
+ };
205
+
206
+ } // cybozu::socket_local
207
+
208
+ class SocketAddr {
209
+ union {
210
+ // http://www.coins.tsukuba.ac.jp/~syspro/2010/No6_files/sockaddr.html
211
+ struct sockaddr sa; /* 16byte */
212
+ struct sockaddr_in v4; /* 16byte */
213
+ struct sockaddr_in6 v6;
214
+ } addr_;
215
+ socklen_t addrlen_;
216
+ int family_;
217
+ friend class Socket;
218
+ void verify() // call in only Socket::accept
219
+ {
220
+ if (addrlen_ == sizeof(addr_.v4) && addr_.sa.sa_family == AF_INET) {
221
+ family_ = AF_INET;
222
+ return;
223
+ }
224
+ if (addrlen_ == sizeof(addr_.v6) && addr_.sa.sa_family == AF_INET6) {
225
+ family_ = AF_INET6;
226
+ return;
227
+ }
228
+ throw cybozu::Exception("cybozu:SocketAddr:verify") << addrlen_;
229
+ }
230
+ public:
231
+ SocketAddr()
232
+ : addrlen_(0)
233
+ , family_(0)
234
+ {
235
+ }
236
+ SocketAddr(const std::string& address, uint16_t port, bool forceIpV6 = false)
237
+ {
238
+ set(address, port, forceIpV6);
239
+ }
240
+ void set(const std::string& address, uint16_t port, bool forceIpV6 = false)
241
+ {
242
+ char portStr[16];
243
+ CYBOZU_SNPRINTF(portStr, sizeof(portStr), "%d", port);
244
+ memset(&addr_, 0, sizeof(addr_));
245
+ addrlen_ = 0;
246
+ family_ = 0;
247
+
248
+ struct addrinfo *result = 0;
249
+ struct addrinfo hints;
250
+ memset(&hints, 0, sizeof(struct addrinfo));
251
+ hints.ai_family = AF_INET;
252
+ hints.ai_socktype = SOCK_STREAM;
253
+ hints.ai_protocol = IPPROTO_TCP;
254
+ hints.ai_flags = AI_NUMERICSERV; // AI_PASSIVE;
255
+ const int s = getaddrinfo(address.c_str(), portStr, &hints, &result);
256
+ // s == EAI_AGAIN
257
+ if (s || forceIpV6) {
258
+ hints.ai_family = AF_INET6;
259
+ hints.ai_flags |= AI_V4MAPPED;
260
+ if (getaddrinfo(address.c_str(), portStr, &hints, &result)) {
261
+ goto ERR_EXIT;
262
+ }
263
+ }
264
+ {
265
+ bool found = false;
266
+ for (const struct addrinfo *p = result; p; p = p->ai_next) {
267
+ const int family = p->ai_family;
268
+ if (family == hints.ai_family) {
269
+ if (p->ai_addrlen > sizeof(addr_)) {
270
+ break;
271
+ }
272
+ memcpy(&addr_, p->ai_addr, p->ai_addrlen);
273
+ addrlen_ = (socklen_t)p->ai_addrlen;
274
+ family_ = family;
275
+ found = true;
276
+ break;
277
+ }
278
+ }
279
+ freeaddrinfo(result);
280
+ if (found) return;
281
+ }
282
+ ERR_EXIT:
283
+ throw cybozu::Exception("SocketAddr:set") << address << port << cybozu::NetErrorNo();
284
+ }
285
+ socklen_t getSize() const { return addrlen_; }
286
+ int getFamily() const { return family_; }
287
+ const struct sockaddr *get() const { return &addr_.sa; }
288
+ uint16_t getPort() const {
289
+ if (family_ == AF_INET) {
290
+ return ntohs(addr_.v4.sin_port);
291
+ } else if (family_ == AF_INET6) {
292
+ return ntohs(addr_.v6.sin6_port);
293
+ }
294
+ throw cybozu::Exception("SocketAddr:getPort:bad family") << family_;
295
+ }
296
+ // compare addr without port
297
+ bool hasSameAddr(const SocketAddr& rhs) const
298
+ {
299
+ const uint8_t *v4 = 0;
300
+ const uint8_t *v6 = 0;
301
+ if (family_ == AF_INET) {
302
+ if (rhs.family_ == AF_INET) return memcmp(&addr_.v4.sin_addr, &rhs.addr_.v4.sin_addr, sizeof(in_addr)) == 0;
303
+ if (rhs.family_ != AF_INET6) return false;
304
+ v4 = (const uint8_t*)&addr_.v4.sin_addr;
305
+ v6 = (const uint8_t*)&rhs.addr_.v6.sin6_addr;
306
+ } else if (family_ != AF_INET6) {
307
+ return false;
308
+ } else {
309
+ if (rhs.family_ == AF_INET6) return memcmp(&addr_.v6.sin6_addr, &rhs.addr_.v6.sin6_addr, sizeof(in6_addr)) == 0;
310
+ if (rhs.family_ != AF_INET) return false;
311
+ v4 = (const uint8_t*)&rhs.addr_.v4.sin_addr;
312
+ v6 = (const uint8_t*)&addr_.v6.sin6_addr;
313
+ }
314
+ // Ipv6-mapped?
315
+ const uint8_t header[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
316
+ return memcmp(v6, header, 12) == 0 && memcmp(v6 + 12, v4, 4) == 0;
317
+ }
318
+ std::string toStr() const
319
+ {
320
+ if (family_ == AF_INET || family_ == AF_INET6) {
321
+ char buf[INET6_ADDRSTRLEN];
322
+ assert(INET_ADDRSTRLEN <= INET6_ADDRSTRLEN);
323
+ const bool isIPv4 = family_ == AF_INET;
324
+ const void *pa = isIPv4 ? (const void*)&addr_.v4.sin_addr : (const void*)&addr_.v6.sin6_addr;
325
+ // not "const void*" because of vc
326
+ const char *p = inet_ntop(family_, const_cast<void*>(pa), buf, sizeof(buf));
327
+ if (!p) throw cybozu::Exception("cybozu:SocketAddr:toStr") << cybozu::NetErrorNo();
328
+ if (isIPv4) return std::string(p) + ':' + cybozu::itoa(getPort());
329
+ return std::string("[") + p + "]:" + cybozu::itoa(getPort());
330
+ }
331
+ throw cybozu::Exception("cybozu:SocketAddr:toStr:bad family_") << family_;
332
+ }
333
+ };
334
+ /*
335
+ socket class
336
+ @note ower is moved if copied
337
+ */
338
+ class Socket {
339
+ friend class cybozu::ssl::ClientSocket;
340
+ private:
341
+ cybozu::socket_local::SocketHandle sd_;
342
+ Socket(const Socket&);
343
+ void operator=(const Socket&);
344
+ #ifdef WIN32
345
+ void setTimeout(int type, int msec)
346
+ {
347
+ setSocketOption(type, msec);
348
+ }
349
+ /* return msec */
350
+ int getTimeout(int type) const
351
+ {
352
+ return getSocketOption(type);
353
+ }
354
+ #else
355
+ void setTimeout(int type, int msec)
356
+ {
357
+ struct timeval t;
358
+ t.tv_sec = msec / 1000;
359
+ t.tv_usec = (msec % 1000) * 1000;
360
+ setSocketOption(type, t);
361
+ }
362
+ /* return msec */
363
+ int getTimeout(int type) const
364
+ {
365
+ struct timeval t;
366
+ getSocketOption(type, &t);
367
+ return t.tv_sec * 1000 + t.tv_usec / 1000; /* msec */
368
+ }
369
+ #endif
370
+ void setBlocking(bool isBlocking)
371
+ {
372
+ #ifdef _WIN32
373
+ u_long val = isBlocking ? 0 : 1;
374
+ int ret = ::ioctlsocket(sd_, FIONBIO, &val);
375
+ #else
376
+ int val = isBlocking ? 0 : 1;
377
+ int ret = ::ioctl(sd_, FIONBIO, &val);
378
+ #endif
379
+ if (ret < 0) throw cybozu::Exception("Socket:setBlocking") << cybozu::NetErrorNo() << isBlocking;
380
+ }
381
+ public:
382
+ #ifndef _WIN32
383
+ static const int INVALID_SOCKET = -1;
384
+ #endif
385
+ Socket()
386
+ : sd_(INVALID_SOCKET)
387
+ {
388
+ }
389
+
390
+ bool isValid() const { return sd_ != INVALID_SOCKET; }
391
+
392
+ // move
393
+ #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
394
+ Socket(Socket&& rhs)
395
+ : sd_(INVALID_SOCKET)
396
+ {
397
+ sd_ = cybozu::AtomicExchange(&rhs.sd_, sd_);
398
+ }
399
+ #endif
400
+ // close and move
401
+ void moveFrom(Socket& rhs)
402
+ {
403
+ close();
404
+ sd_ = cybozu::AtomicExchange(&rhs.sd_, INVALID_SOCKET);
405
+ }
406
+ #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
407
+ void operator=(Socket&& rhs)
408
+ #else
409
+ void operator=(Socket& rhs)
410
+ #endif
411
+ {
412
+ moveFrom(rhs);
413
+ }
414
+
415
+ ~Socket()
416
+ {
417
+ close(cybozu::DontThrow);
418
+ }
419
+
420
+ bool close(bool dontThrow = false)
421
+ {
422
+ cybozu::socket_local::SocketHandle sd = cybozu::AtomicExchange(&sd_, INVALID_SOCKET);
423
+ if (sd == INVALID_SOCKET) return true;
424
+ #ifdef _WIN32
425
+ // ::shutdown(sd, SD_SEND);
426
+ // shutdown is called in closesocket
427
+ bool isOK = ::closesocket(sd) == 0;
428
+ #else
429
+ bool isOK = ::close(sd) == 0;
430
+ #endif
431
+ if (!dontThrow && !isOK) throw cybozu::Exception("Socket:close") << cybozu::NetErrorNo();
432
+ return isOK;
433
+ }
434
+ /*
435
+ how 0 : SHUTRD ; disallow read
436
+ 1 : SHUT_WR ; disallow write
437
+ 2 : SHUT_RDWR ; disallow read/write
438
+ */
439
+ bool shutdown(int how, bool dontThrow = false)
440
+ {
441
+ bool isOK = ::shutdown(sd_, how) == 0;
442
+ if (!dontThrow && !isOK) throw cybozu::Exception("Socket:waitForClose:shutdown") << cybozu::NetErrorNo();
443
+ return isOK;
444
+ }
445
+ /*
446
+ send FIN and wait for remote's close().
447
+ this function is used for the following situation.
448
+ sock.write()
449
+ sock.waitForClose()
450
+ sock.close()
451
+ */
452
+ void waitForClose()
453
+ {
454
+ if (sd_ == INVALID_SOCKET) return;
455
+ // send FIN and this socket can't write any data.
456
+ shutdown(1);
457
+ // wait for FIN from the peer.
458
+ char buf[1];
459
+ ssize_t readSize = readSome(buf, sizeof(buf));
460
+ if (readSize != 0) {
461
+ throw cybozu::Exception("Socket:waitForClose:readSome:bad size") << readSize;
462
+ }
463
+ }
464
+
465
+ /*!
466
+ receive data
467
+ @param buf [out] receive buffer
468
+ @param bufSize [in] receive buffer size(byte)
469
+ @note return read size
470
+ */
471
+ size_t readSome(void *buf, size_t bufSize)
472
+ {
473
+ int size = (int)(std::min)((size_t)0x7fffffff, bufSize);
474
+ #ifdef _WIN32
475
+ int readSize = ::recv(sd_, (char *)buf, size, 0);
476
+ #else
477
+ RETRY:
478
+ ssize_t readSize = ::read(sd_, buf, size);
479
+ if (readSize < 0 && errno == EINTR) goto RETRY;
480
+ #endif
481
+ if (readSize < 0) throw cybozu::Exception("Socket:readSome") << cybozu::NetErrorNo() << bufSize;
482
+ return readSize;
483
+ }
484
+
485
+ /*!
486
+ receive all data unless timeout
487
+ @param buf [out] receive buffer
488
+ @param bufSize [in] receive buffer size(byte)
489
+ */
490
+ void read(void *buf, size_t bufSize)
491
+ {
492
+ char *p = (char *)buf;
493
+ while (bufSize > 0) {
494
+ size_t readSize = readSome(p, bufSize);
495
+ if (readSize == 0) throw cybozu::Exception("Socket:read:readSize is zero");
496
+ p += readSize;
497
+ bufSize -= readSize;
498
+ }
499
+ }
500
+ /*!
501
+ write all data
502
+ @param buf [out] send buffer
503
+ @param bufSize [in] send buffer size(byte)
504
+ */
505
+ void write(bool *pb, const void *buf, size_t bufSize)
506
+ {
507
+ const char *p = (const char *)buf;
508
+ while (bufSize > 0) {
509
+ int size = (int)(std::min)(size_t(0x7fffffff), bufSize);
510
+ #ifdef _WIN32
511
+ int writeSize = ::send(sd_, p, size, 0);
512
+ #else
513
+ int writeSize = ::write(sd_, p, size);
514
+ if (writeSize < 0 && errno == EINTR) continue;
515
+ #endif
516
+ if (writeSize < 0) {
517
+ *pb = false;
518
+ return;
519
+ }
520
+ p += writeSize;
521
+ bufSize -= writeSize;
522
+ }
523
+ *pb = true;
524
+ }
525
+ void write(const void *buf, size_t bufSize)
526
+ {
527
+ bool b;
528
+ write(&b, buf, bufSize);
529
+ if (!b) throw cybozu::Exception("Socket:write") << cybozu::NetErrorNo() << bufSize;
530
+ }
531
+ /**
532
+ connect to address:port
533
+ @param address [in] address
534
+ @param port [in] port
535
+ @param msec: 0 : block
536
+ */
537
+ void connect(const std::string& address, uint16_t port, int msec = 0)
538
+ {
539
+ SocketAddr addr;
540
+ addr.set(address, port);
541
+ connect(addr, msec);
542
+ }
543
+ /**
544
+ connect to resolved socket addr
545
+ */
546
+ void connect(const cybozu::SocketAddr& addr, int msec = 0)
547
+ {
548
+ if (isValid()) throw cybozu::Exception("Socket:connect:already connect");
549
+ sd_ = ::socket(addr.getFamily(), SOCK_STREAM, IPPROTO_TCP);
550
+ if (!isValid()) {
551
+ throw cybozu::Exception("Socket:connect:socket") << cybozu::NetErrorNo();
552
+ }
553
+ if (msec == 0) {
554
+ if (::connect(sd_, addr.get(), addr.getSize()) < 0) {
555
+ throw cybozu::Exception("Socket:connect") << cybozu::NetErrorNo() << addr.toStr();
556
+ }
557
+ } else {
558
+ setBlocking(false);
559
+ if (::connect(sd_, addr.get(), addr.getSize()) < 0) {
560
+ #ifdef _WIN32
561
+ bool inProgress = WSAGetLastError() == WSAEWOULDBLOCK;
562
+ #else
563
+ bool inProgress = errno == EINPROGRESS;
564
+ #endif
565
+ if (!inProgress) throw cybozu::Exception("Socket:connect:not in progress") << cybozu::NetErrorNo() << addr.toStr();
566
+ if (!queryAccept(msec, false)) throw cybozu::Exception("Socket:connect:timeout") << addr.toStr();
567
+ int err = getSocketOption(SO_ERROR);
568
+ if (err != 0) throw cybozu::Exception("Socket::connect:bad socket") << cybozu::NetErrorNo(err);
569
+ }
570
+ setBlocking(true);
571
+ }
572
+ }
573
+
574
+ static const int allowIPv4 = 1;
575
+ static const int allowIPv6 = 2;
576
+ /**
577
+ init for server
578
+ @param port [in] port number
579
+ */
580
+ void bind(uint16_t port, int mode = allowIPv4 | allowIPv6)
581
+ {
582
+ const int family = (mode & allowIPv6) ? AF_INET6 : AF_INET;
583
+ sd_ = ::socket(family, SOCK_STREAM, IPPROTO_TCP);
584
+ if (!isValid()) {
585
+ throw cybozu::Exception("Socket:bind:socket") << cybozu::NetErrorNo();
586
+ }
587
+ setSocketOption(SO_REUSEADDR, 1);
588
+ struct sockaddr_in6 addr6;
589
+ struct sockaddr_in addr4;
590
+ struct sockaddr *addr;
591
+ socklen_t addrLen;
592
+ if (mode & allowIPv6) {
593
+ setSocketOption(IPV6_V6ONLY, (mode & allowIPv4) ? 0 : 1, IPPROTO_IPV6);
594
+ memset(&addr6, 0, sizeof(addr6));
595
+ addr6.sin6_family = AF_INET6;
596
+ addr6.sin6_port = htons(port);
597
+ addr = (struct sockaddr*)&addr6;
598
+ addrLen = sizeof(addr6);
599
+ } else {
600
+ memset(&addr4, 0, sizeof(addr4));
601
+ addr4.sin_family = AF_INET;
602
+ addr4.sin_port = htons(port);
603
+ addr = (struct sockaddr*)&addr4;
604
+ addrLen = sizeof(addr4);
605
+ }
606
+ if (::bind(sd_, addr, addrLen) == 0) {
607
+ if (::listen(sd_, SOMAXCONN) == 0) {
608
+ return;
609
+ }
610
+ }
611
+ cybozu::NetErrorNo keep;
612
+ close(cybozu::DontThrow);
613
+ throw cybozu::Exception("Socket:bind") << keep;
614
+ }
615
+
616
+ /**
617
+ return positive if accepted
618
+ return zero if timeout
619
+ return negative(-errno) if error
620
+ */
621
+ int queryAcceptNoThrow(int msec = 1000, bool checkWrite = true)
622
+ {
623
+ if (sd_ == INVALID_SOCKET) return -EBADF;
624
+ #ifdef CYBOZU_SOCKET_USE_EPOLL
625
+ int err;
626
+ experimental::Epoll ep;
627
+ if (!ep.init(&err)) return -err;
628
+ uint32_t events = checkWrite ? EPOLLIN : EPOLLOUT;
629
+ experimental::AutoLock al(ep, sd_, events);
630
+ experimental::EpollEvent ev;
631
+ int ret = ep.wait(&ev, 1, msec);
632
+ if (ret != 1) return ret;
633
+ assert(ev.getFd() == sd_);
634
+ return ret;
635
+ #else
636
+ #ifndef _WIN32
637
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms739169.aspx
638
+ if (sd_ >= FD_SETSIZE) return -EMFILE;
639
+ #endif
640
+ struct timeval timeout;
641
+ timeout.tv_sec = msec / 1000;
642
+ timeout.tv_usec = (msec % 1000) * 1000;
643
+ fd_set fds;
644
+ FD_ZERO(&fds);
645
+ FD_SET((unsigned)sd_, &fds);
646
+ int fdNum;
647
+ if (checkWrite) {
648
+ fdNum = ::select((int)sd_ + 1, &fds, 0, 0, &timeout);
649
+ } else {
650
+ fdNum = ::select((int)sd_ + 1, 0, &fds, 0, &timeout);
651
+ }
652
+ if (fdNum < 0) return -errno;
653
+ return fdNum;
654
+ #endif
655
+ }
656
+ /**
657
+ return true if acceptable, otherwise false
658
+ return false if one second passed
659
+ while (!server.queryAccept()) {
660
+ }
661
+ client.accept(server);
662
+ */
663
+ bool queryAccept(int msec = 1000, bool checkWrite = true)
664
+ {
665
+ int ret = queryAcceptNoThrow(msec, checkWrite);
666
+ if (ret < 0) throw cybozu::Exception("Socket:queryAccept") << cybozu::NetErrorNo(-ret);
667
+ return ret > 0;
668
+ }
669
+
670
+ /**
671
+ accept for server
672
+ */
673
+ void accept(Socket& client, SocketAddr *paddr = 0) const
674
+ {
675
+ if (paddr) {
676
+ struct sockaddr *psa = &paddr->addr_.sa;
677
+ paddr->addrlen_ = sizeof(paddr->addr_);
678
+ client.sd_ = ::accept(sd_, psa, &paddr->addrlen_);
679
+ paddr->verify();
680
+ } else {
681
+ client.sd_ = ::accept(sd_, 0, 0);
682
+ }
683
+ if (!client.isValid()) throw cybozu::Exception("Socket:accept") << cybozu::NetErrorNo();
684
+ }
685
+
686
+ template<typename T>
687
+ void setSocketOption(int optname, const T& value, int level = SOL_SOCKET)
688
+ {
689
+ bool isOK = setsockopt(sd_, level, optname, cybozu::cast<const char*>(&value), sizeof(T)) == 0;
690
+ if (!isOK) throw cybozu::Exception("Socket:setSocketOption") << cybozu::NetErrorNo();
691
+ }
692
+ template<typename T>
693
+ void getSocketOption(int optname, T* value, int level = SOL_SOCKET) const
694
+ {
695
+ socklen_t len = (socklen_t)sizeof(T);
696
+ bool isOK = getsockopt(sd_, level, optname, cybozu::cast<char*>(value), &len) == 0;
697
+ if (!isOK) throw cybozu::Exception("Socket:getSocketOption") << cybozu::NetErrorNo();
698
+ }
699
+ int getSocketOption(int optname) const
700
+ {
701
+ int ret;
702
+ getSocketOption(optname, &ret);
703
+ return ret;
704
+ }
705
+ /**
706
+ setup linger
707
+ */
708
+ void setLinger(uint16_t l_onoff, uint16_t l_linger)
709
+ {
710
+ struct linger linger;
711
+ linger.l_onoff = l_onoff;
712
+ linger.l_linger = l_linger;
713
+ setSocketOption(SO_LINGER, &linger);
714
+ }
715
+ /**
716
+ get receive buffer size
717
+ @retval positive buffer size(byte)
718
+ @retval -1 error
719
+ */
720
+ int getReceiveBufferSize() const
721
+ {
722
+ return getSocketOption(SO_RCVBUF);
723
+ }
724
+ /**
725
+ set receive buffer size
726
+ @param size [in] buffer size(byte)
727
+ */
728
+ void setReceiveBufferSize(int size)
729
+ {
730
+ setSocketOption(SO_RCVBUF, size);
731
+ }
732
+ /**
733
+ get send buffer size
734
+ @retval positive buffer size(byte)
735
+ @retval -1 error
736
+ */
737
+ int getSendBufferSize() const
738
+ {
739
+ return getSocketOption(SO_SNDBUF);
740
+ }
741
+ /**
742
+ sed send buffer size
743
+ @param size [in] buffer size(byte)
744
+ */
745
+ void setSendBufferSize(int size)
746
+ {
747
+ setSocketOption(SO_SNDBUF, size);
748
+ }
749
+ /**
750
+ set send timeout
751
+ @param msec [in] msec
752
+ */
753
+ void setSendTimeout(int msec)
754
+ {
755
+ setTimeout(SO_SNDTIMEO, msec);
756
+ }
757
+ /**
758
+ set receive timeout
759
+ @param msec [in] msec
760
+ */
761
+ void setReceiveTimeout(int msec)
762
+ {
763
+ setTimeout(SO_RCVTIMEO, msec);
764
+ }
765
+ /**
766
+ get send timeout(msec)
767
+ */
768
+ int getSendTimeout() const
769
+ {
770
+ return getTimeout(SO_SNDTIMEO);
771
+ }
772
+ /**
773
+ get receive timeout(msec)
774
+ */
775
+ int getReceiveTimeout() const
776
+ {
777
+ return getTimeout(SO_RCVTIMEO);
778
+ }
779
+ };
780
+
781
+ } // cybozu
782
+
783
+ #ifdef _MSC_VER
784
+ #pragma warning(pop)
785
+ #endif