Version 2.1.1n
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@6350 e7ae566f-a301-0410-adde-c780ea21d3b5
... | ... |
@@ -896,8 +896,11 @@ buffer_list_new (const int max_size) |
896 | 896 |
void |
897 | 897 |
buffer_list_free (struct buffer_list *ol) |
898 | 898 |
{ |
899 |
- buffer_list_reset (ol); |
|
900 |
- free (ol); |
|
899 |
+ if (ol) |
|
900 |
+ { |
|
901 |
+ buffer_list_reset (ol); |
|
902 |
+ free (ol); |
|
903 |
+ } |
|
901 | 904 |
} |
902 | 905 |
|
903 | 906 |
bool |
... | ... |
@@ -924,9 +927,21 @@ buffer_list_reset (struct buffer_list *ol) |
924 | 924 |
void |
925 | 925 |
buffer_list_push (struct buffer_list *ol, const unsigned char *str) |
926 | 926 |
{ |
927 |
- if (!ol->max_size || ol->size < ol->max_size) |
|
927 |
+ if (str) |
|
928 |
+ { |
|
929 |
+ const size_t len = strlen ((const char *)str); |
|
930 |
+ struct buffer_entry *e = buffer_list_push_data (ol, str, len+1); |
|
931 |
+ if (e) |
|
932 |
+ e->buf.len = len; /* Don't count trailing '\0' as part of length */ |
|
933 |
+ } |
|
934 |
+} |
|
935 |
+ |
|
936 |
+struct buffer_entry * |
|
937 |
+buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size) |
|
938 |
+{ |
|
939 |
+ struct buffer_entry *e = NULL; |
|
940 |
+ if (data && (!ol->max_size || ol->size < ol->max_size)) |
|
928 | 941 |
{ |
929 |
- struct buffer_entry *e; |
|
930 | 942 |
ALLOC_OBJ_CLEAR (e, struct buffer_entry); |
931 | 943 |
|
932 | 944 |
++ol->size; |
... | ... |
@@ -940,15 +955,18 @@ buffer_list_push (struct buffer_list *ol, const unsigned char *str) |
940 | 940 |
ASSERT (!ol->head); |
941 | 941 |
ol->head = e; |
942 | 942 |
} |
943 |
- e->buf = string_alloc_buf ((const char *) str, NULL); |
|
943 |
+ e->buf = alloc_buf (size); |
|
944 |
+ memcpy (e->buf.data, data, size); |
|
945 |
+ e->buf.len = (int)size; |
|
944 | 946 |
ol->tail = e; |
945 | 947 |
} |
948 |
+ return e; |
|
946 | 949 |
} |
947 | 950 |
|
948 | 951 |
struct buffer * |
949 | 952 |
buffer_list_peek (struct buffer_list *ol) |
950 | 953 |
{ |
951 |
- if (ol->head) |
|
954 |
+ if (ol && ol->head) |
|
952 | 955 |
return &ol->head->buf; |
953 | 956 |
else |
954 | 957 |
return NULL; |
... | ... |
@@ -993,10 +1011,10 @@ buffer_list_aggregate (struct buffer_list *bl, const size_t max) |
993 | 993 |
} |
994 | 994 |
} |
995 | 995 |
|
996 |
-static void |
|
996 |
+void |
|
997 | 997 |
buffer_list_pop (struct buffer_list *ol) |
998 | 998 |
{ |
999 |
- if (ol->head) |
|
999 |
+ if (ol && ol->head) |
|
1000 | 1000 |
{ |
1001 | 1001 |
struct buffer_entry *e = ol->head->next; |
1002 | 1002 |
free_buf (&ol->head->buf); |
... | ... |
@@ -851,8 +851,10 @@ bool buffer_list_defined (const struct buffer_list *ol); |
851 | 851 |
void buffer_list_reset (struct buffer_list *ol); |
852 | 852 |
|
853 | 853 |
void buffer_list_push (struct buffer_list *ol, const unsigned char *str); |
854 |
+struct buffer_entry *buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size); |
|
854 | 855 |
struct buffer *buffer_list_peek (struct buffer_list *ol); |
855 | 856 |
void buffer_list_advance (struct buffer_list *ol, int n); |
857 |
+void buffer_list_pop (struct buffer_list *ol); |
|
856 | 858 |
|
857 | 859 |
void buffer_list_aggregate (struct buffer_list *bl, const size_t max); |
858 | 860 |
|
... | ... |
@@ -2266,6 +2266,7 @@ key_state_free (struct key_state *ks, bool clear) |
2266 | 2266 |
free_buf (&ks->plaintext_read_buf); |
2267 | 2267 |
free_buf (&ks->plaintext_write_buf); |
2268 | 2268 |
free_buf (&ks->ack_write_buf); |
2269 |
+ buffer_list_free(ks->paybuf); |
|
2269 | 2270 |
|
2270 | 2271 |
if (ks->send_reliable) |
2271 | 2272 |
{ |
... | ... |
@@ -3064,6 +3065,17 @@ key_source2_read (struct key_source2 *k2, |
3064 | 3064 |
return 1; |
3065 | 3065 |
} |
3066 | 3066 |
|
3067 |
+static void |
|
3068 |
+flush_payload_buffer (struct tls_multi *multi, struct key_state *ks) |
|
3069 |
+{ |
|
3070 |
+ struct buffer *b; |
|
3071 |
+ while ((b = buffer_list_peek (ks->paybuf))) |
|
3072 |
+ { |
|
3073 |
+ key_state_write_plaintext_const (multi, ks, b->data, b->len); |
|
3074 |
+ buffer_list_pop (ks->paybuf); |
|
3075 |
+ } |
|
3076 |
+} |
|
3077 |
+ |
|
3067 | 3078 |
/* |
3068 | 3079 |
* Macros for key_state_soft_reset & tls_process |
3069 | 3080 |
*/ |
... | ... |
@@ -3978,6 +3990,9 @@ tls_process (struct tls_multi *multi, |
3978 | 3978 |
/* Set outgoing address for data channel packets */ |
3979 | 3979 |
link_socket_set_outgoing_addr (NULL, to_link_socket_info, &ks->remote_addr, session->common_name, session->opt->es); |
3980 | 3980 |
|
3981 |
+ /* Flush any payload packets that were buffered before our state transitioned to S_ACTIVE */ |
|
3982 |
+ flush_payload_buffer (multi, ks); |
|
3983 |
+ |
|
3981 | 3984 |
#ifdef MEASURE_TLS_HANDSHAKE_STATS |
3982 | 3985 |
show_tls_performance_stats(); |
3983 | 3986 |
#endif |
... | ... |
@@ -5077,6 +5092,13 @@ tls_send_payload (struct tls_multi *multi, |
5077 | 5077 |
if (key_state_write_plaintext_const (multi, ks, data, size) == 1) |
5078 | 5078 |
ret = true; |
5079 | 5079 |
} |
5080 |
+ else |
|
5081 |
+ { |
|
5082 |
+ if (!ks->paybuf) |
|
5083 |
+ ks->paybuf = buffer_list_new (0); |
|
5084 |
+ buffer_list_push_data (ks->paybuf, data, (size_t)size); |
|
5085 |
+ ret = true; |
|
5086 |
+ } |
|
5080 | 5087 |
|
5081 | 5088 |
ERR_clear_error (); |
5082 | 5089 |
|
... | ... |
@@ -376,6 +376,8 @@ struct key_state |
376 | 376 |
struct reliable *rec_reliable; /* order incoming ciphertext packets before we pass to TLS */ |
377 | 377 |
struct reliable_ack *rec_ack; /* buffers all packet IDs we want to ACK back to sender */ |
378 | 378 |
|
379 |
+ struct buffer_list *paybuf; |
|
380 |
+ |
|
379 | 381 |
int n_bytes; /* how many bytes sent/recvd since last key exchange */ |
380 | 382 |
int n_packets; /* how many packets sent/recvd since last key exchange */ |
381 | 383 |
|
... | ... |
@@ -531,11 +531,9 @@ socket_defined (const socket_descriptor_t sd) |
531 | 531 |
#endif |
532 | 532 |
|
533 | 533 |
/* |
534 |
- * Don't compile the struct buffer_list code unless something needs it |
|
534 |
+ * Compile the struct buffer_list code |
|
535 | 535 |
*/ |
536 |
-#if defined(ENABLE_MANAGEMENT) || defined(ENABLE_PF) |
|
537 | 536 |
#define ENABLE_BUFFER_LIST |
538 |
-#endif |
|
539 | 537 |
|
540 | 538 |
/* |
541 | 539 |
* Do we have pthread capability? |