trilogy 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -39,6 +39,8 @@ int trilogy_builder_init(trilogy_builder_t *builder, trilogy_buffer_t *buff, uin
39
39
  builder->buffer->len = 0;
40
40
 
41
41
  builder->seq = seq;
42
+ builder->packet_length = 0;
43
+ builder->packet_max_length = SIZE_MAX;
42
44
 
43
45
  return write_header(builder);
44
46
  }
@@ -60,10 +62,15 @@ void trilogy_builder_finalize(trilogy_builder_t *builder)
60
62
 
61
63
  int trilogy_builder_write_uint8(trilogy_builder_t *builder, uint8_t val)
62
64
  {
65
+ if (builder->packet_length >= builder->packet_max_length - 1) {
66
+ return TRILOGY_MAX_PACKET_EXCEEDED;
67
+ }
68
+
63
69
  CHECKED(trilogy_buffer_expand(builder->buffer, 1));
64
70
 
65
71
  builder->buffer->buff[builder->buffer->len++] = val;
66
72
  builder->fragment_length++;
73
+ builder->packet_length++;
67
74
 
68
75
  if (builder->fragment_length == TRILOGY_MAX_PACKET_LEN) {
69
76
  CHECKED(write_continuation_header(builder));
@@ -113,6 +120,44 @@ int trilogy_builder_write_uint64(trilogy_builder_t *builder, uint64_t val)
113
120
  return TRILOGY_OK;
114
121
  }
115
122
 
123
+ int trilogy_builder_write_float(trilogy_builder_t *builder, float val)
124
+ {
125
+ union {
126
+ float f;
127
+ uint32_t u;
128
+ } float_val;
129
+
130
+ float_val.f = val;
131
+
132
+ CHECKED(trilogy_builder_write_uint8(builder, float_val.u & 0xff));
133
+ CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 8) & 0xff));
134
+ CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 16) & 0xff));
135
+ CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 24) & 0xff));
136
+
137
+ return TRILOGY_OK;
138
+ }
139
+
140
+ int trilogy_builder_write_double(trilogy_builder_t *builder, double val)
141
+ {
142
+ union {
143
+ double d;
144
+ uint64_t u;
145
+ } double_val;
146
+
147
+ double_val.d = val;
148
+
149
+ CHECKED(trilogy_builder_write_uint8(builder, double_val.u & 0xff));
150
+ CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 8) & 0xff));
151
+ CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 16) & 0xff));
152
+ CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 24) & 0xff));
153
+ CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 32) & 0xff));
154
+ CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 40) & 0xff));
155
+ CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 48) & 0xff));
156
+ CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 56) & 0xff));
157
+
158
+ return TRILOGY_OK;
159
+ }
160
+
116
161
  int trilogy_builder_write_lenenc(trilogy_builder_t *builder, uint64_t val)
117
162
  {
118
163
  if (val < 251) {
@@ -137,6 +182,10 @@ int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, s
137
182
 
138
183
  size_t fragment_remaining = TRILOGY_MAX_PACKET_LEN - builder->fragment_length;
139
184
 
185
+ if (builder->packet_length >= builder->packet_max_length - len) {
186
+ return TRILOGY_MAX_PACKET_EXCEEDED;
187
+ }
188
+
140
189
  // if this buffer write is not going to straddle a fragment boundary:
141
190
  if (len < fragment_remaining) {
142
191
  CHECKED(trilogy_buffer_expand(builder->buffer, len));
@@ -145,6 +194,7 @@ int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, s
145
194
 
146
195
  builder->buffer->len += len;
147
196
  builder->fragment_length += len;
197
+ builder->packet_length += len;
148
198
 
149
199
  return TRILOGY_OK;
150
200
  }
@@ -157,6 +207,7 @@ int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, s
157
207
 
158
208
  builder->buffer->len += fragment_remaining;
159
209
  builder->fragment_length += fragment_remaining;
210
+ builder->packet_length += fragment_remaining;
160
211
 
161
212
  ptr += fragment_remaining;
162
213
  len -= fragment_remaining;
@@ -172,6 +223,7 @@ int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, s
172
223
 
173
224
  builder->buffer->len += len;
174
225
  builder->fragment_length += len;
226
+ builder->packet_length += len;
175
227
  }
176
228
 
177
229
  return TRILOGY_OK;
@@ -195,4 +247,15 @@ int trilogy_builder_write_string(trilogy_builder_t *builder, const char *data)
195
247
  return TRILOGY_OK;
196
248
  }
197
249
 
250
+ int trilogy_builder_set_max_packet_length(trilogy_builder_t *builder, size_t max_length)
251
+ {
252
+ if (builder->packet_length > max_length) {
253
+ return TRILOGY_MAX_PACKET_EXCEEDED;
254
+ }
255
+
256
+ builder->packet_max_length = max_length;
257
+
258
+ return TRILOGY_OK;
259
+ }
260
+
198
261
  #undef CHECKED
@@ -1,4 +1,3 @@
1
- #include <errno.h>
2
1
  #include <fcntl.h>
3
2
 
4
3
  #include "trilogy/client.h"
@@ -60,6 +59,10 @@ static int begin_command_phase(trilogy_builder_t *builder, trilogy_conn_t *conn,
60
59
  return rc;
61
60
  }
62
61
 
62
+ if (conn->socket->opts.max_allowed_packet > 0) {
63
+ trilogy_builder_set_max_packet_length(builder, conn->socket->opts.max_allowed_packet);
64
+ }
65
+
63
66
  conn->packet_parser.sequence_number = seq + 1;
64
67
 
65
68
  return 0;
@@ -72,11 +75,6 @@ static int read_packet(trilogy_conn_t *conn)
72
75
 
73
76
  if (nread < 0) {
74
77
  int rc = (int)nread;
75
- if (rc == TRILOGY_SYSERR) {
76
- if (errno == EINTR || errno == EAGAIN) {
77
- return TRILOGY_AGAIN;
78
- }
79
- }
80
78
  return rc;
81
79
  }
82
80
 
@@ -158,16 +156,6 @@ int trilogy_flush_writes(trilogy_conn_t *conn)
158
156
 
159
157
  if (bytes < 0) {
160
158
  int rc = (int)bytes;
161
- if (rc == TRILOGY_SYSERR) {
162
- if (errno == EINTR || errno == EAGAIN) {
163
- return TRILOGY_AGAIN;
164
- }
165
-
166
- if (errno == EPIPE) {
167
- return TRILOGY_CLOSED_CONNECTION;
168
- }
169
- }
170
-
171
159
  return rc;
172
160
  }
173
161
 
@@ -766,11 +754,186 @@ void trilogy_free(trilogy_conn_t *conn)
766
754
 
767
755
  int trilogy_discard(trilogy_conn_t *conn)
768
756
  {
769
- int rc = trilogy_sock_discard(conn->socket);
757
+ int rc = trilogy_sock_shutdown(conn->socket);
770
758
  if (rc == TRILOGY_OK) {
771
759
  trilogy_free(conn);
772
760
  }
773
761
  return rc;
774
762
  }
775
763
 
764
+ int trilogy_stmt_prepare_send(trilogy_conn_t *conn, const char *stmt, size_t stmt_len)
765
+ {
766
+ trilogy_builder_t builder;
767
+ int err = begin_command_phase(&builder, conn, 0);
768
+ if (err < 0) {
769
+ return err;
770
+ }
771
+
772
+ err = trilogy_build_stmt_prepare_packet(&builder, stmt, stmt_len);
773
+ if (err < 0) {
774
+ return err;
775
+ }
776
+
777
+ return begin_write(conn);
778
+ }
779
+
780
+ int trilogy_stmt_prepare_recv(trilogy_conn_t *conn, trilogy_stmt_t *stmt_out)
781
+ {
782
+ int err = read_packet(conn);
783
+
784
+ if (err < 0) {
785
+ return err;
786
+ }
787
+
788
+ switch (current_packet_type(conn)) {
789
+ case TRILOGY_PACKET_OK: {
790
+ err = trilogy_parse_stmt_ok_packet(conn->packet_buffer.buff, conn->packet_buffer.len, stmt_out);
791
+
792
+ if (err < 0) {
793
+ return err;
794
+ }
795
+
796
+ conn->warning_count = stmt_out->warning_count;
797
+
798
+ return TRILOGY_OK;
799
+ }
800
+
801
+ case TRILOGY_PACKET_ERR:
802
+ return read_err_packet(conn);
803
+
804
+ default:
805
+ return TRILOGY_UNEXPECTED_PACKET;
806
+ }
807
+ }
808
+
809
+ int trilogy_stmt_execute_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint8_t flags, trilogy_binary_value_t *binds)
810
+ {
811
+ trilogy_builder_t builder;
812
+ int err = begin_command_phase(&builder, conn, 0);
813
+ if (err < 0) {
814
+ return err;
815
+ }
816
+
817
+ err = trilogy_build_stmt_execute_packet(&builder, stmt->id, flags, binds, stmt->parameter_count);
818
+
819
+ if (err < 0) {
820
+ return err;
821
+ }
822
+
823
+ conn->packet_parser.sequence_number = builder.seq;
824
+
825
+ return begin_write(conn);
826
+ }
827
+
828
+ int trilogy_stmt_execute_recv(trilogy_conn_t *conn, uint64_t *column_count_out)
829
+ {
830
+ int err = read_packet(conn);
831
+
832
+ if (err < 0) {
833
+ return err;
834
+ }
835
+
836
+ switch (current_packet_type(conn)) {
837
+ case TRILOGY_PACKET_OK:
838
+ return read_ok_packet(conn);
839
+
840
+ case TRILOGY_PACKET_ERR:
841
+ return read_err_packet(conn);
842
+
843
+ default: {
844
+ trilogy_result_packet_t result_packet;
845
+ err = trilogy_parse_result_packet(conn->packet_buffer.buff, conn->packet_buffer.len, &result_packet);
846
+
847
+ if (err < 0) {
848
+ return err;
849
+ }
850
+
851
+ conn->column_count = result_packet.column_count;
852
+ *column_count_out = result_packet.column_count;
853
+
854
+ return TRILOGY_OK;
855
+ }
856
+ }
857
+ }
858
+
859
+ int trilogy_stmt_bind_data_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint16_t param_num, uint8_t *data,
860
+ size_t data_len)
861
+ {
862
+ trilogy_builder_t builder;
863
+ int err = begin_command_phase(&builder, conn, 0);
864
+ if (err < 0) {
865
+ return err;
866
+ }
867
+
868
+ err = trilogy_build_stmt_bind_data_packet(&builder, stmt->id, param_num, data, data_len);
869
+
870
+ if (err < 0) {
871
+ return err;
872
+ }
873
+
874
+ return begin_write(conn);
875
+ }
876
+
877
+ int trilogy_stmt_read_row(trilogy_conn_t *conn, trilogy_stmt_t *stmt, trilogy_column_packet_t *columns,
878
+ trilogy_binary_value_t *values_out)
879
+ {
880
+ int err = read_packet(conn);
881
+
882
+ if (err < 0) {
883
+ return err;
884
+ }
885
+
886
+ if (conn->capabilities & TRILOGY_CAPABILITIES_DEPRECATE_EOF && current_packet_type(conn) == TRILOGY_PACKET_EOF) {
887
+ if ((err = read_ok_packet(conn)) != TRILOGY_OK) {
888
+ return err;
889
+ }
890
+
891
+ return TRILOGY_EOF;
892
+ } else if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
893
+ return read_eof_packet(conn);
894
+ } else if (current_packet_type(conn) == TRILOGY_PACKET_ERR) {
895
+ return read_err_packet(conn);
896
+ } else {
897
+ return trilogy_parse_stmt_row_packet(conn->packet_buffer.buff, conn->packet_buffer.len, columns,
898
+ stmt->column_count, values_out);
899
+ }
900
+ }
901
+
902
+ int trilogy_stmt_reset_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt)
903
+ {
904
+ trilogy_builder_t builder;
905
+ int err = begin_command_phase(&builder, conn, 0);
906
+ if (err < 0) {
907
+ return err;
908
+ }
909
+
910
+ err = trilogy_build_stmt_reset_packet(&builder, stmt->id);
911
+ if (err < 0) {
912
+ return err;
913
+ }
914
+
915
+ return begin_write(conn);
916
+ }
917
+
918
+ int trilogy_stmt_reset_recv(trilogy_conn_t *conn) {
919
+ return read_generic_response(conn);
920
+ }
921
+
922
+ int trilogy_stmt_close_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt)
923
+ {
924
+ trilogy_builder_t builder;
925
+ int err = begin_command_phase(&builder, conn, 0);
926
+ if (err < 0) {
927
+ return err;
928
+ }
929
+
930
+ err = trilogy_build_stmt_close_packet(&builder, stmt->id);
931
+
932
+ if (err < 0) {
933
+ return err;
934
+ }
935
+
936
+ return begin_write(conn);
937
+ }
938
+
776
939
  #undef CHECKED