1diff -purN -x CVS -x '*~' -x '.*' -x 'obj-*' srtp-ws/include/srtp.h srtp/include/srtp.h
2--- srtp-ws/include/srtp.h	2009-04-22 19:06:22.000000000 -0400
3+++ srtp/include/srtp.h	2009-04-23 15:17:49.000000000 -0400
4@@ -225,6 +225,12 @@ typedef struct srtp_policy_t {
5                                 *   for this stream (if any)             */
6   unsigned long  window_size;  /**< The window size to use for replay
7 				*   protection. */
8+  int        allow_repeat_tx;  /**< Whether retransmissions of
9+				*   packets with the same sequence number
10+				*   are allowed.  (Note that such repeated
11+				*   transmissions must have the same RTP
12+				*   payload, or a severe security weakness
13+				*   is introduced!)                      */
14   struct srtp_policy_t *next;  /**< Pointer to next stream policy.       */
15 } srtp_policy_t;
16
17diff -purN -x CVS -x '*~' -x '.*' -x 'obj-*' srtp-ws/include/srtp_priv.h srtp/include/srtp_priv.h
18--- srtp-ws/include/srtp_priv.h	2007-06-15 14:17:40.000000000 -0400
19+++ srtp/include/srtp_priv.h	2009-04-22 19:27:10.000000000 -0400
20@@ -218,6 +218,7 @@ typedef struct srtp_stream_ctx_t {
21   sec_serv_t rtcp_services;
22   key_limit_ctx_t *limit;
23   direction_t direction;
24+  int        allow_repeat_tx;
25   ekt_stream_t ekt;
26   struct srtp_stream_ctx_t *next;   /* linked list of streams */
27 } srtp_stream_ctx_t;
28diff -purN -x CVS -x '*~' -x '.*' -x 'obj-*' srtp-ws/srtp/srtp.c srtp/srtp/srtp.c
29--- srtp-ws/srtp/srtp.c	2009-04-22 19:18:43.000000000 -0400
30+++ srtp/srtp/srtp.c	2009-04-22 19:30:23.000000000 -0400
31@@ -280,6 +280,7 @@ srtp_stream_clone(const srtp_stream_ctx_
32   if (status)
33     return status;
34   rdb_init(&str->rtcp_rdb);
35+  str->allow_repeat_tx = stream_template->allow_repeat_tx;
36
37   /* set ssrc to that provided */
38   str->ssrc = ssrc;
39@@ -525,6 +526,9 @@ srtp_stream_init(srtp_stream_ctx_t *srtp
40    /* initialize SRTCP replay database */
41    rdb_init(&srtp->rtcp_rdb);
42
43+   /* initialize allow_repeat_tx */
44+   srtp->allow_repeat_tx = p->allow_repeat_tx;
45+
46    /* DAM - no RTCP key limit at present */
47
48    /* initialize keys */
49@@ -732,9 +736,12 @@ srtp_stream_init(srtp_stream_ctx_t *srtp
50     */
51    delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
52    status = rdbx_check(&stream->rtp_rdbx, delta);
53-   if (status)
54-     return status;  /* we've been asked to reuse an index */
55-   rdbx_add_index(&stream->rtp_rdbx, delta);
56+   if (status) {
57+     if (status != err_status_replay_fail || !stream->allow_repeat_tx)
58+       return status;  /* we've been asked to reuse an index */
59+   }
60+   else
61+     rdbx_add_index(&stream->rtp_rdbx, delta);
62
63 #ifdef NO_64BIT_MATH
64    debug_print2(mod_srtp, "estimated packet index: %08x%08x",
65diff -purN -x CVS -x '*~' -x '.*' -x 'obj-*' srtp-ws/test/dtls_srtp_driver.c srtp/test/dtls_srtp_driver.c
66--- srtp-ws/test/dtls_srtp_driver.c	2009-04-23 15:50:48.000000000 -0400
67+++ srtp/test/dtls_srtp_driver.c	2009-04-23 15:51:11.000000000 -0400
68@@ -185,6 +185,7 @@ test_dtls_srtp() {
69   policy.ssrc.type  = ssrc_any_inbound;
70   policy.ekt = NULL;
71   policy.window_size = 128;
72+  policy.allow_repeat_tx = 0;
73   policy.next = NULL;
74
75   err = srtp_add_stream(s, &policy);
76diff -purN -x CVS -x '*~' -x '.*' -x 'obj-*' srtp-ws/test/rtpw.c srtp/test/rtpw.c
77--- srtp-ws/test/rtpw.c	2009-04-22 19:16:52.000000000 -0400
78+++ srtp/test/rtpw.c	2009-04-23 15:16:18.000000000 -0400
79@@ -331,6 +331,7 @@ main (int argc, char *argv[]) {
80     policy.key  = (uint8_t *) key;
81     policy.next = NULL;
82     policy.window_size = 128;
83+    policy.allow_repeat_tx = 0;
84     policy.rtp.sec_serv = sec_servs;
85     policy.rtcp.sec_serv = sec_serv_none;  /* we don't do RTCP anyway */
86
87@@ -384,6 +385,7 @@ main (int argc, char *argv[]) {
88     policy.rtcp.auth_tag_len   = 0;
89     policy.rtcp.sec_serv       = sec_serv_none;
90     policy.window_size         = 0;
91+    policy.allow_repeat_tx     = 0;
92     policy.next                = NULL;
93   }
94
95diff -purN -x CVS -x '*~' -x '.*' -x 'obj-*' srtp-ws/test/srtp_driver.c srtp/test/srtp_driver.c
96--- srtp-ws/test/srtp_driver.c	2009-04-22 19:16:52.000000000 -0400
97+++ srtp/test/srtp_driver.c	2009-04-23 15:16:18.000000000 -0400
98@@ -323,6 +323,7 @@ main (int argc, char *argv[]) {
99     policy.key  = test_key;
100     policy.ekt = NULL;
101     policy.window_size = 128;
102+    policy.allow_repeat_tx = 0;
103     policy.next = NULL;
104
105     printf("mips estimate: %e\n", mips);
106@@ -992,7 +993,8 @@ srtp_session_print_policy(srtp_t srtp) {
107            "# rtcp cipher:   %s\r\n"
108 	   "# rtcp auth:     %s\r\n"
109 	   "# rtcp services: %s\r\n"
110-	   "# window size:   %lu\r\n",
111+	   "# window size:   %lu\r\n"
112+	   "# tx rtx allowed:%s\r\n",
113 	   direction[stream->direction],
114 	   stream->rtp_cipher->type->description,
115 	   stream->rtp_auth->type->description,
116@@ -1000,7 +1002,8 @@ srtp_session_print_policy(srtp_t srtp) {
117 	   stream->rtcp_cipher->type->description,
118 	   stream->rtcp_auth->type->description,
119 	   serv_descr[stream->rtcp_services],
120-	   rdbx_get_window_size(&stream->rtp_rdbx));
121+	   rdbx_get_window_size(&stream->rtp_rdbx),
122+	   stream->allow_repeat_tx ? "true" : "false");
123   }
124
125   /* loop over streams in session, printing the policy of each */
126@@ -1016,7 +1019,8 @@ srtp_session_print_policy(srtp_t srtp) {
127            "# rtcp cipher:   %s\r\n"
128 	   "# rtcp auth:     %s\r\n"
129 	   "# rtcp services: %s\r\n"
130-	   "# window size:   %lu\r\n",
131+	   "# window size:   %lu\r\n"
132+	   "# tx rtx allowed:%s\r\n",
133 	   stream->ssrc,
134 	   stream->rtp_cipher->type->description,
135 	   stream->rtp_auth->type->description,
136@@ -1024,7 +1028,8 @@ srtp_session_print_policy(srtp_t srtp) {
137 	   stream->rtcp_cipher->type->description,
138 	   stream->rtcp_auth->type->description,
139 	   serv_descr[stream->rtcp_services],
140-	   rdbx_get_window_size(&stream->rtp_rdbx));
141+	   rdbx_get_window_size(&stream->rtp_rdbx),
142+	   stream->allow_repeat_tx ? "true" : "false");
143
144     /* advance to next stream in the list */
145     stream = stream->next;
146@@ -1180,6 +1185,7 @@ srtp_validate() {
147   policy.key  = test_key;
148   policy.ekt = NULL;
149   policy.window_size = 128;
150+  policy.allow_repeat_tx = 0;
151   policy.next = NULL;
152
153   status = srtp_create(&srtp_snd, &policy);
154@@ -1337,6 +1343,7 @@ const srtp_policy_t default_policy = {
155   test_key,
156   NULL,        /* indicates that EKT is not in use */
157   128,         /* replay window size */
158+  0,           /* retransmission not allowed */
159   NULL
160 };
161
162@@ -1361,6 +1368,7 @@ const srtp_policy_t aes_tmmh_policy = {
163   test_key,
164   NULL,        /* indicates that EKT is not in use */
165   128,         /* replay window size */
166+  0,           /* retransmission not allowed */
167   NULL
168 };
169
170@@ -1385,6 +1393,7 @@ const srtp_policy_t tmmh_only_policy = {
171   test_key,
172   NULL,        /* indicates that EKT is not in use */
173   128,         /* replay window size */
174+  0,           /* retransmission not allowed */
175   NULL
176 };
177
178@@ -1409,6 +1418,7 @@ const srtp_policy_t aes_only_policy = {
179   test_key,
180   NULL,        /* indicates that EKT is not in use */
181   128,         /* replay window size */
182+  0,           /* retransmission not allowed */
183   NULL
184 };
185
186@@ -1433,6 +1443,7 @@ const srtp_policy_t hmac_only_policy = {
187   test_key,
188   NULL,        /* indicates that EKT is not in use */
189   128,         /* replay window size */
190+  0,           /* retransmission not allowed */
191   NULL
192 };
193
194@@ -1457,6 +1468,7 @@ const srtp_policy_t null_policy = {
195   test_key,
196   NULL,        /* indicates that EKT is not in use */
197   128,         /* replay window size */
198+  0,           /* retransmission not allowed */
199   NULL
200 };
201
202@@ -1495,6 +1507,7 @@ const srtp_policy_t hmac_only_with_ekt_p
203   test_key,
204   &ekt_test_policy,        /* indicates that EKT is not in use */
205   128,         /* replay window size */
206+  0,           /* retransmission not allowed */
207   NULL
208 };
209
210@@ -1548,5 +1561,6 @@ const srtp_policy_t wildcard_policy = {
211   test_key,
212   NULL,
213   128,         /* replay window size */
214+  0,           /* retransmission not allowed */
215   NULL
216 };
217