iodine 0.1.21 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of iodine might be problematic. Click here for more details.

Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -2
  3. data/.travis.yml +23 -2
  4. data/CHANGELOG.md +9 -2
  5. data/README.md +232 -179
  6. data/Rakefile +13 -1
  7. data/bin/config.ru +63 -0
  8. data/bin/console +6 -0
  9. data/bin/echo +42 -32
  10. data/bin/http-hello +62 -0
  11. data/bin/http-playground +124 -0
  12. data/bin/playground +62 -0
  13. data/bin/poc/Gemfile.lock +23 -0
  14. data/bin/poc/README.md +37 -0
  15. data/bin/poc/config.ru +66 -0
  16. data/bin/poc/gemfile +1 -0
  17. data/bin/poc/www/index.html +57 -0
  18. data/bin/raw-rbhttp +35 -0
  19. data/bin/raw_broadcast +66 -0
  20. data/bin/test_with_faye +40 -0
  21. data/bin/ws-broadcast +108 -0
  22. data/bin/ws-echo +108 -0
  23. data/exe/iodine +59 -0
  24. data/ext/iodine/base64.c +264 -0
  25. data/ext/iodine/base64.h +72 -0
  26. data/ext/iodine/bscrypt-common.h +109 -0
  27. data/ext/iodine/bscrypt.h +49 -0
  28. data/ext/iodine/extconf.rb +41 -0
  29. data/ext/iodine/hex.c +123 -0
  30. data/ext/iodine/hex.h +70 -0
  31. data/ext/iodine/http.c +200 -0
  32. data/ext/iodine/http.h +128 -0
  33. data/ext/iodine/http1.c +402 -0
  34. data/ext/iodine/http1.h +56 -0
  35. data/ext/iodine/http1_simple_parser.c +473 -0
  36. data/ext/iodine/http1_simple_parser.h +59 -0
  37. data/ext/iodine/http_request.h +128 -0
  38. data/ext/iodine/http_response.c +1606 -0
  39. data/ext/iodine/http_response.h +393 -0
  40. data/ext/iodine/http_response_http1.h +374 -0
  41. data/ext/iodine/iodine_core.c +641 -0
  42. data/ext/iodine/iodine_core.h +70 -0
  43. data/ext/iodine/iodine_http.c +615 -0
  44. data/ext/iodine/iodine_http.h +19 -0
  45. data/ext/iodine/iodine_websocket.c +430 -0
  46. data/ext/iodine/iodine_websocket.h +21 -0
  47. data/ext/iodine/libasync.c +552 -0
  48. data/ext/iodine/libasync.h +117 -0
  49. data/ext/iodine/libreact.c +347 -0
  50. data/ext/iodine/libreact.h +244 -0
  51. data/ext/iodine/libserver.c +912 -0
  52. data/ext/iodine/libserver.h +435 -0
  53. data/ext/iodine/libsock.c +950 -0
  54. data/ext/iodine/libsock.h +478 -0
  55. data/ext/iodine/misc.c +181 -0
  56. data/ext/iodine/misc.h +76 -0
  57. data/ext/iodine/random.c +193 -0
  58. data/ext/iodine/random.h +48 -0
  59. data/ext/iodine/rb-call.c +127 -0
  60. data/ext/iodine/rb-call.h +60 -0
  61. data/ext/iodine/rb-libasync.h +79 -0
  62. data/ext/iodine/rb-rack-io.c +389 -0
  63. data/ext/iodine/rb-rack-io.h +17 -0
  64. data/ext/iodine/rb-registry.c +213 -0
  65. data/ext/iodine/rb-registry.h +33 -0
  66. data/ext/iodine/sha1.c +359 -0
  67. data/ext/iodine/sha1.h +85 -0
  68. data/ext/iodine/sha2.c +825 -0
  69. data/ext/iodine/sha2.h +138 -0
  70. data/ext/iodine/siphash.c +136 -0
  71. data/ext/iodine/siphash.h +15 -0
  72. data/ext/iodine/spnlock.h +235 -0
  73. data/ext/iodine/websockets.c +696 -0
  74. data/ext/iodine/websockets.h +120 -0
  75. data/ext/iodine/xor-crypt.c +189 -0
  76. data/ext/iodine/xor-crypt.h +107 -0
  77. data/iodine.gemspec +25 -18
  78. data/lib/iodine.rb +57 -58
  79. data/lib/iodine/http.rb +0 -189
  80. data/lib/iodine/protocol.rb +36 -245
  81. data/lib/iodine/version.rb +1 -1
  82. data/lib/rack/handler/iodine.rb +145 -2
  83. metadata +115 -37
  84. data/bin/core_http_test +0 -51
  85. data/bin/em playground +0 -56
  86. data/bin/hello_world +0 -75
  87. data/bin/setup +0 -7
  88. data/lib/iodine/client.rb +0 -5
  89. data/lib/iodine/core.rb +0 -102
  90. data/lib/iodine/core_init.rb +0 -143
  91. data/lib/iodine/http/hpack.rb +0 -553
  92. data/lib/iodine/http/http1.rb +0 -251
  93. data/lib/iodine/http/http2.rb +0 -507
  94. data/lib/iodine/http/rack_support.rb +0 -108
  95. data/lib/iodine/http/request.rb +0 -462
  96. data/lib/iodine/http/response.rb +0 -474
  97. data/lib/iodine/http/session.rb +0 -143
  98. data/lib/iodine/http/websocket_client.rb +0 -335
  99. data/lib/iodine/http/websocket_handler.rb +0 -101
  100. data/lib/iodine/http/websockets.rb +0 -336
  101. data/lib/iodine/io.rb +0 -56
  102. data/lib/iodine/logging.rb +0 -46
  103. data/lib/iodine/settings.rb +0 -158
  104. data/lib/iodine/ssl_connector.rb +0 -48
  105. data/lib/iodine/timers.rb +0 -95
data/ext/iodine/misc.c ADDED
@@ -0,0 +1,181 @@
1
+ /*
2
+ (un)copyright: Boaz segev, 2016
3
+ License: Public Domain except for any non-public-domain algorithms, which are
4
+ subject to their own licenses.
5
+
6
+ Feel free to copy, use and enjoy in accordance with to the license(s).
7
+ */
8
+ #ifndef _GNU_SOURCE
9
+ #define _GNU_SOURCE
10
+ #endif
11
+ #include "misc.h"
12
+ /* ***************************************************************************
13
+ Other helper functions
14
+ */
15
+
16
+ #ifdef HAS_UNIX_FEATURES
17
+ #include <fcntl.h>
18
+ #include <limits.h>
19
+ #include <errno.h>
20
+ #include <unistd.h>
21
+ #include <sys/types.h>
22
+ #include <sys/stat.h>
23
+
24
+ /**
25
+ Allocates memory and dumps the whole file into the memory allocated.
26
+
27
+ Remember to call `free` when done.
28
+
29
+ Returns the number of bytes allocated. On error, returns 0 and sets the
30
+ container pointer to NULL.
31
+
32
+ This function has some Unix specific properties that resolve links and user
33
+ folder referencing.
34
+ */
35
+ fdump_s* bscrypt_fdump(const char* file_path, size_t size_limit) {
36
+ struct stat f_data;
37
+ int file = -1;
38
+ fdump_s* container = NULL;
39
+ size_t file_path_len;
40
+ if (file_path == NULL || (file_path_len = strlen(file_path)) == 0 ||
41
+ file_path_len > PATH_MAX)
42
+ return NULL;
43
+
44
+ char real_public_path[PATH_MAX + 1];
45
+ real_public_path[PATH_MAX] = 0;
46
+ if (file_path[0] == '~' && getenv("HOME") && file_path_len <= PATH_MAX) {
47
+ strcpy(real_public_path, getenv("HOME"));
48
+ memcpy(real_public_path + strlen(real_public_path), file_path + 1,
49
+ file_path_len);
50
+ file_path = real_public_path;
51
+ }
52
+
53
+ if (stat(file_path, &f_data))
54
+ goto error;
55
+ if (size_limit == 0 || f_data.st_size < size_limit)
56
+ size_limit = f_data.st_size;
57
+ container = malloc(size_limit + sizeof(fdump_s));
58
+ if (!container)
59
+ goto error;
60
+ container->length = size_limit;
61
+ file = open(file_path, O_RDONLY);
62
+ if (file < 0)
63
+ goto error;
64
+ if (read(file, container->data, size_limit) < size_limit)
65
+ goto error;
66
+ close(file);
67
+ return container;
68
+ error:
69
+ if (container)
70
+ free(container), (container = NULL);
71
+ if (file >= 0)
72
+ close(file);
73
+ return 0;
74
+ }
75
+
76
+ #endif /* HAS_UNIX_FEATURES */
77
+
78
+ /**
79
+ A faster (yet less localized) alternative to `gmtime_r`.
80
+
81
+ See the libc `gmtime_r` documentation for details.
82
+
83
+ Falls back to `gmtime_r` for dates before epoch.
84
+ */
85
+ struct tm* bscrypt_gmtime(const time_t* timer, struct tm* tmbuf) {
86
+ // static char* DAYS[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
87
+ // static char * Months = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
88
+ // "Jul",
89
+ // "Aug", "Sep", "Oct", "Nov", "Dec"};
90
+ static uint8_t month_len[] = {
91
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, // nonleap year
92
+ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // leap year
93
+ };
94
+ if (*timer < 0)
95
+ return gmtime_r(timer, tmbuf);
96
+ ssize_t tmp;
97
+ tmbuf->tm_gmtoff = 0;
98
+ tmbuf->tm_zone = "UTC";
99
+ tmbuf->tm_isdst = 0;
100
+ tmbuf->tm_year = 70; // tm_year == The number of years since 1900
101
+ tmbuf->tm_mon = 0;
102
+ // for seconds up to weekdays, we build up, as small values clean up larger
103
+ // values.
104
+ tmp = ((ssize_t)*timer);
105
+ tmbuf->tm_sec = tmp % 60;
106
+ tmp = tmp / 60;
107
+ tmbuf->tm_min = tmp % 60;
108
+ tmp = tmp / 60;
109
+ tmbuf->tm_hour = tmp % 24;
110
+ tmp = tmp / 24;
111
+ // day of epoch was a thursday. Add + 3 so sunday == 0...
112
+ tmbuf->tm_wday = (tmp + 3) % 7;
113
+ // tmp == number of days since epoch
114
+ #define DAYS_PER_400_YEARS ((400 * 365) + 97)
115
+ while (tmp >= DAYS_PER_400_YEARS) {
116
+ tmbuf->tm_year += 400;
117
+ tmp -= DAYS_PER_400_YEARS;
118
+ }
119
+ #undef DAYS_PER_400_YEARS
120
+ #define DAYS_PER_100_YEARS ((100 * 365) + 24)
121
+ while (tmp >= DAYS_PER_100_YEARS) {
122
+ tmbuf->tm_year += 100;
123
+ tmp -= DAYS_PER_100_YEARS;
124
+ if (((tmbuf->tm_year / 100) & 3) ==
125
+ 0) // leap century divisable by 400 => add leap
126
+ --tmp;
127
+ }
128
+ #undef DAYS_PER_100_YEARS
129
+ #define DAYS_PER_32_YEARS ((32 * 365) + 8)
130
+ while (tmp >= DAYS_PER_32_YEARS) {
131
+ tmbuf->tm_year += 32;
132
+ tmp -= DAYS_PER_32_YEARS;
133
+ }
134
+ #undef DAYS_PER_32_YEARS
135
+ #define DAYS_PER_8_YEARS ((8 * 365) + 2)
136
+ while (tmp >= DAYS_PER_8_YEARS) {
137
+ tmbuf->tm_year += 8;
138
+ tmp -= DAYS_PER_8_YEARS;
139
+ }
140
+ #undef DAYS_PER_8_YEARS
141
+ #define DAYS_PER_4_YEARS ((4 * 365) + 1)
142
+ while (tmp >= DAYS_PER_4_YEARS) {
143
+ tmbuf->tm_year += 4;
144
+ tmp -= DAYS_PER_4_YEARS;
145
+ }
146
+ #undef DAYS_PER_4_YEARS
147
+ while (tmp >= 365) {
148
+ tmbuf->tm_year += 1;
149
+ tmp -= 365;
150
+ if ((tmbuf->tm_year & 3) == 0) { // leap year
151
+ if (tmp > 0) {
152
+ --tmp;
153
+ continue;
154
+ } else {
155
+ tmp += 365;
156
+ --tmbuf->tm_year;
157
+ break;
158
+ }
159
+ }
160
+ }
161
+ tmbuf->tm_yday = tmp;
162
+ if ((tmbuf->tm_year & 3) == 1) {
163
+ // regular year
164
+ for (size_t i = 0; i < 12; i++) {
165
+ if (tmp < month_len[i])
166
+ break;
167
+ tmp -= month_len[i];
168
+ ++tmbuf->tm_mon;
169
+ }
170
+ } else {
171
+ // leap year
172
+ for (size_t i = 12; i < 24; i++) {
173
+ if (tmp < month_len[i])
174
+ break;
175
+ tmp -= month_len[i];
176
+ ++tmbuf->tm_mon;
177
+ }
178
+ }
179
+ tmbuf->tm_mday = tmp;
180
+ return tmbuf;
181
+ }
data/ext/iodine/misc.h ADDED
@@ -0,0 +1,76 @@
1
+ /*
2
+ (un)copyright: Boaz segev, 2016
3
+ License: Public Domain except for any non-public-domain algorithms, which are
4
+ subject to their own licenses.
5
+
6
+ Feel free to copy, use and enjoy in accordance with to the license(s).
7
+ */
8
+ #ifndef bscrypt_MISC_H
9
+ #define bscrypt_MISC_H
10
+ #include "bscrypt-common.h"
11
+ #include <time.h>
12
+ /* *****************************************************************************
13
+ C++ extern
14
+ */
15
+ #if defined(__cplusplus)
16
+ extern "C" {
17
+ #endif
18
+
19
+ /* ***************************************************************************
20
+ Miscellaneous helper functions
21
+
22
+ i.e. file content dumping and GMT time alternative to `gmtime_r`.
23
+ */
24
+
25
+ #ifdef HAS_UNIX_FEATURES
26
+
27
+ /**
28
+ File dump data.
29
+
30
+ This struct (or, a pointer to this struct) is returned
31
+ by the `bscrypt.fdump`
32
+ function on success.
33
+
34
+ To free the pointer returned, simply call `free`.
35
+ */
36
+ typedef struct {
37
+ size_t length;
38
+ char data[];
39
+ } fdump_s;
40
+
41
+ /**
42
+ Allocates memory and dumps the whole file into the
43
+ memory allocated.
44
+ Remember
45
+ to call `free` when done.
46
+
47
+ Returns the number of bytes allocated. On error,
48
+ returns 0 and sets the
49
+ container pointer to NULL.
50
+
51
+ This function has some Unix specific properties that
52
+ resolve links and user
53
+ folder referencing.
54
+ */
55
+ fdump_s *bscrypt_fdump(const char *file_path, size_t size_limit);
56
+
57
+ #endif /* HAS_UNIX_FEATURES */
58
+
59
+ /**
60
+ A faster (yet less localized) alternative to
61
+ `gmtime_r`.
62
+
63
+ See the libc `gmtime_r` documentation for details.
64
+
65
+ Falls back to `gmtime_r` for dates before epoch.
66
+ */
67
+ struct tm *bscrypt_gmtime(const time_t *timer, struct tm *tmbuf);
68
+
69
+ /* *****************************************************************************
70
+ C++ extern finish
71
+ */
72
+ #if defined(__cplusplus)
73
+ }
74
+ #endif
75
+
76
+ #endif
@@ -0,0 +1,193 @@
1
+ /*
2
+ (un)copyright: Boaz segev, 2016
3
+ License: Public Domain except for any non-public-domain algorithms, which are
4
+ subject to their own licenses.
5
+
6
+ Feel free to copy, use and enjoy in accordance with to the license(s).
7
+ */
8
+ #ifndef _GNU_SOURCE
9
+ #define _GNU_SOURCE
10
+ #endif
11
+ #include "random.h"
12
+
13
+ #if defined(USE_ALT_RANDOM) || !defined(HAS_UNIX_FEATURES)
14
+ #include <time.h>
15
+ #include "sha2.h"
16
+ uint32_t bscrypt_rand32(void) {
17
+ bits256_u pseudo = bscrypt_rand256();
18
+ return pseudo.ints[3];
19
+ }
20
+
21
+ uint64_t bscrypt_rand64(void) {
22
+ bits256_u pseudo = bscrypt_rand256();
23
+ return pseudo.words[3];
24
+ }
25
+
26
+ bits128_u bscrypt_rand128(void) {
27
+ bits256_u pseudo = bscrypt_rand256();
28
+ bits128_u ret;
29
+ ret.words[0] = pseudo.words[0];
30
+ ret.words[1] = pseudo.words[1];
31
+ return ret;
32
+ }
33
+
34
+ bits256_u bscrypt_rand256(void) {
35
+ clock_t cpu_state = clock();
36
+ time_t the_time;
37
+ time(&the_time);
38
+ bits256_u pseudo;
39
+ sha2_s sha2 = bscrypt_sha2_init(SHA_256);
40
+ bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
41
+ bscrypt_sha2_write(&sha2, &the_time, sizeof(the_time));
42
+ bscrypt_sha2_write(&sha2, &cpu_state - 2, 64); /* whatever's on the stack */
43
+ bscrypt_sha2_result(&sha2);
44
+ pseudo.words[0] = sha2.digest.i64[0];
45
+ pseudo.words[1] = sha2.digest.i64[1];
46
+ pseudo.words[2] = sha2.digest.i64[2];
47
+ pseudo.words[3] = sha2.digest.i64[3];
48
+ return pseudo;
49
+ }
50
+
51
+ void bscrypt_rand_bytes(void *target, size_t length) {
52
+ clock_t cpu_state = clock();
53
+ time_t the_time;
54
+ time(&the_time);
55
+ sha2_s sha2 = bscrypt_sha2_init(SHA_512);
56
+ bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
57
+ bscrypt_sha2_write(&sha2, &the_time, sizeof(the_time));
58
+ bscrypt_sha2_write(&sha2, &cpu_state - 2, 64); /* whatever's on the stack */
59
+ bscrypt_sha2_result(&sha2);
60
+ while (length > 64) {
61
+ memcpy(target, sha2.digest.str, 64);
62
+ length -= 64;
63
+ target += 64;
64
+ bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
65
+ bscrypt_sha2_result(&sha2);
66
+ }
67
+ if (length > 32) {
68
+ memcpy(target, sha2.digest.str, 32);
69
+ length -= 32;
70
+ target += 32;
71
+ bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
72
+ bscrypt_sha2_result(&sha2);
73
+ }
74
+ if (length > 16) {
75
+ memcpy(target, sha2.digest.str, 16);
76
+ length -= 16;
77
+ target += 16;
78
+ bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
79
+ bscrypt_sha2_result(&sha2);
80
+ }
81
+ if (length > 8) {
82
+ memcpy(target, sha2.digest.str, 8);
83
+ length -= 8;
84
+ target += 8;
85
+ bscrypt_sha2_write(&sha2, &cpu_state, sizeof(cpu_state));
86
+ bscrypt_sha2_result(&sha2);
87
+ }
88
+ while (length) {
89
+ *((uint8_t *)target) = sha2.digest.str[length];
90
+ ++target;
91
+ --length;
92
+ }
93
+ }
94
+
95
+ #else
96
+ /* ***************************************************************************
97
+ Unix Random Engine (use built in machine)
98
+ */
99
+ #include <fcntl.h>
100
+ #include <errno.h>
101
+ #include <unistd.h>
102
+ #include <pthread.h>
103
+
104
+ /* ***************************************************************************
105
+ Machine specific changes
106
+ */
107
+ // #ifdef __linux__
108
+ // #undef bswap16
109
+ // #undef bswap32
110
+ // #undef bswap64
111
+ // #include <machine/bswap.h>
112
+ // #endif
113
+ #ifdef HAVE_X86Intrin
114
+ // #undef bswap16
115
+ /*
116
+ #undef bswap32
117
+ #define bswap32(i) \
118
+ { __asm__("bswap %k0" : "+r"(i) :); }
119
+ */
120
+ #undef bswap64
121
+ #define bswap64(i) \
122
+ { __asm__("bswapq %0" : "+r"(i) :); }
123
+
124
+ // shadow sched_yield as _mm_pause for spinwait
125
+ #define sched_yield() _mm_pause()
126
+ #endif
127
+
128
+ /* ***************************************************************************
129
+ Random ... (why is this not a system call?)
130
+ */
131
+
132
+ /* rand generator management */
133
+ static int _rand_fd_ = -1;
134
+ static void close_rand_fd(void) {
135
+ if (_rand_fd_ >= 0)
136
+ close(_rand_fd_);
137
+ _rand_fd_ = -1;
138
+ }
139
+ static void init_rand_fd(void) {
140
+ if (_rand_fd_ < 0) {
141
+ while ((_rand_fd_ = open("/dev/urandom", O_RDONLY)) == -1) {
142
+ if (errno == ENXIO)
143
+ perror("bscrypt fatal error, caanot initiate random generator"),
144
+ exit(-1);
145
+ sched_yield();
146
+ }
147
+ }
148
+ atexit(close_rand_fd);
149
+ }
150
+ /* rand function template */
151
+ #define MAKE_RAND_FUNC(type, func_name) \
152
+ type func_name(void) { \
153
+ if (_rand_fd_ < 0) \
154
+ init_rand_fd(); \
155
+ type ret; \
156
+ while (read(_rand_fd_, &ret, sizeof(type)) < 0) \
157
+ sched_yield(); \
158
+ return ret; \
159
+ }
160
+ /* rand functions */
161
+ MAKE_RAND_FUNC(uint32_t, bscrypt_rand32);
162
+ MAKE_RAND_FUNC(uint64_t, bscrypt_rand64);
163
+ MAKE_RAND_FUNC(bits128_u, bscrypt_rand128);
164
+ MAKE_RAND_FUNC(bits256_u, bscrypt_rand256);
165
+ /* clear template */
166
+ #undef MAKE_RAND_FUNC
167
+
168
+ void bscrypt_rand_bytes(void *target, size_t length) {
169
+ if (_rand_fd_ < 0)
170
+ init_rand_fd();
171
+ while (read(_rand_fd_, target, length) < 0)
172
+ sched_yield();
173
+ }
174
+ #endif /* Unix Random */
175
+
176
+ /*******************************************************************************
177
+ Random
178
+ */
179
+ #if defined(DEBUG) && DEBUG == 1
180
+ void bscrypt_test_random(void) {
181
+ clock_t start, end;
182
+ bscrypt_rand256();
183
+ start = clock();
184
+ for (size_t i = 0; i < 100000; i++) {
185
+ bscrypt_rand256();
186
+ }
187
+ end = clock();
188
+ fprintf(stderr,
189
+ "+ bscrypt Random generator available\n+ bscrypt 100K X 256bit "
190
+ "Random %lu CPU clock count\n",
191
+ end - start);
192
+ }
193
+ #endif