Skip to content

Commit 86611b5

Browse files
committed
Add check for greetings. Closes gh-85
1 parent 3bf8566 commit 86611b5

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

src/tarantool.c

+5
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,15 @@ int __tarantool_connect(tarantool_object *t_obj) {
287287
GREETING_SIZE) == -1) {
288288
continue;
289289
}
290+
if (php_tp_verify_greetings(obj->greeting) == 0) {
291+
spprintf(&err, 0, "Bad greetings");
292+
goto ioexception;
293+
}
290294
++count;
291295
break;
292296
}
293297
if (count == 0) {
298+
ioexception:
294299
tarantool_throw_ioexception("%s", err);
295300
efree(err);
296301
return FAILURE;

src/tarantool_network.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ int tntll_stream_open(const char *host, int port, zend_string *pid,
7373
if (pid) options |= STREAM_OPEN_PERSISTENT;
7474
flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT;
7575
double_to_tv(TARANTOOL_G(timeout), &tv);
76-
// printf("'tm - %lu, %lu' ", tv.tv_sec, tv.tv_usec);
76+
// printf("timeout: 'sec(%d), usec(%d)'\n",
77+
// (int )tv.tv_sec, (int )tv.tv_usec);
7778

7879
const char *pid_str = pid == NULL ? NULL : pid->val;
7980
stream = php_stream_xport_create(addr, addr_len, options, flags,
@@ -89,9 +90,10 @@ int tntll_stream_open(const char *host, int port, zend_string *pid,
8990

9091
/* Set READ_TIMEOUT */
9192
double_to_tv(TARANTOOL_G(request_timeout), &tv);
92-
// printf("'rtv - %lu, %lu' ", tv.tv_sec, tv.tv_usec);
93+
// printf("request_timeout: 'sec(%d), usec(%d)'\n",
94+
// (int )tv.tv_sec, (int )tv.tv_usec);
9395

94-
if (tv.tv_sec != 0 || tv.tv_usec != 0) {
96+
if (tv.tv_sec != 0 && tv.tv_usec != 0) {
9597
php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT,
9698
0, &tv);
9799
}

src/tarantool_proto.c

+29-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ static size_t php_tp_sizeof_header(uint32_t request, uint32_t sync) {
1515
}
1616

1717
static char *php_tp_pack_header(smart_string *str, size_t size,
18-
uint32_t request, uint32_t sync) {
18+
uint32_t request, uint32_t sync) {
1919
char *sz = SSTR_POS(str);
2020
php_mp_pack_package_size(str, size);
2121
php_mp_pack_hash(str, 2);
@@ -433,3 +433,31 @@ int convert_iter_str(const char *i, size_t i_len) {
433433
};
434434
return -1;
435435
}
436+
437+
uint32_t php_tp_verify_greetings(char *greetingbuf) {
438+
/* Check basic structure - magic string and \n delimiters */
439+
if (memcmp(greetingbuf, "Tarantool ", strlen("Tarantool ")) != 0 ||
440+
greetingbuf[GREETING_SIZE / 2 - 1] != '\n' ||
441+
greetingbuf[GREETING_SIZE - 1] != '\n')
442+
return 0;
443+
444+
int h = GREETING_SIZE / 2;
445+
const char *pos = greetingbuf + strlen("Tarantool ");
446+
const char *end = greetingbuf + h;
447+
448+
/* Extract a version string - a string until ' ' */
449+
char version[20];
450+
const char *vend = (const char *) memchr(pos, ' ', end - pos);
451+
if (vend == NULL || (size_t)(vend - pos) >= sizeof(version))
452+
return 0;
453+
memcpy(version, pos, vend - pos);
454+
version[vend - pos] = '\0';
455+
pos = vend + 1;
456+
for (; pos < end && *pos == ' '; ++pos); /* skip spaces */
457+
458+
/* Parse a version string - 1.6.6-83-gc6b2129 or 1.6.7 */
459+
unsigned major, minor, patch;
460+
if (sscanf(version, "%u.%u.%u", &major, &minor, &patch) != 3)
461+
return 0;
462+
return version_id(major, minor, patch);
463+
}

src/tarantool_proto.h

+34
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#define GREETING_SIZE 128
88
#define SALT_PREFIX_SIZE 64
99

10+
#define GREETING_PROTOCOL_LEN_MAX 32
11+
1012
#define SPACE_SPACE 281
1113
#define SPACE_INDEX 289
1214

@@ -17,6 +19,36 @@
1719

1820
#include <php_tarantool.h>
1921

22+
/**
23+
* Pack version into uint32_t.
24+
* The highest byte or result means major version, next - minor,
25+
* middle - patch, last - revision.
26+
*/
27+
static inline uint32_t
28+
version_id(unsigned major, unsigned minor, unsigned patch)
29+
{
30+
return (((major << 8) | minor) << 8) | patch;
31+
}
32+
33+
static inline unsigned
34+
version_id_major(uint32_t version_id)
35+
{
36+
return (version_id >> 16) & 0xff;
37+
}
38+
39+
static inline unsigned
40+
version_id_minor(uint32_t version_id)
41+
{
42+
return (version_id >> 8) & 0xff;
43+
}
44+
45+
static inline unsigned
46+
version_id_patch(uint32_t version_id)
47+
{
48+
return version_id & 0xff;
49+
}
50+
51+
2052
/* header */
2153
enum tnt_header_key_t {
2254
TNT_CODE = 0x00,
@@ -122,4 +154,6 @@ void php_tp_reencode_length(smart_string *str, char *sz);
122154

123155
int convert_iter_str(const char *i, size_t i_len);
124156

157+
uint32_t php_tp_verify_greetings(char *greetingbuf);
158+
125159
#endif /* PHP_TNT_PROTO_H */

0 commit comments

Comments
 (0)