diff --git a/desync.c b/desync.c
index b65176a..4f69f39 100644
--- a/desync.c
+++ b/desync.c
@@ -457,16 +457,19 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize,
     }
     else if (type == IS_HTTPS && dp.tlsrec_n) {
         long lp = 0;
-        for (int i = 0; i < dp.tlsrec_n; i++) {
-            struct part part = dp.tlsrec[i];
-            
-            long pos = i * 5;
-            pos += gen_offset(part.pos, 
-                part.flag, n - pos, lp, type, host_pos, len);
-            
-            if (part.pos < 0 || part.flag) {
-                pos -= 5;
+        struct part part;
+        int i = 0, r = 0, rc = 0;
+        
+        for (; r > 0 || i < dp.tlsrec_n; rc++, r--) {
+            if (!r) {
+                part = dp.tlsrec[i];
+                r = part.r; i++;
             }
+            long pos = rc * 5;
+            pos += gen_offset(part.pos, 
+                part.flag, n - pos - 5, lp, type, host_pos - 5, len);
+            
+            pos += part.s * (part.r - r);
             if (pos < lp) {
                 LOG(LOG_E, "tlsrec cancel: %ld < %ld\n", pos, lp);
                 break;
@@ -488,20 +491,26 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize,
     }
     #endif
     long lp = offset;
+    struct part part;
+    int i = 0, r = 0;
     
-    for (int i = 0; i < dp.parts_n; i++) {
-        struct part part = dp.parts[i];
-        
-        long pos = gen_offset(part.pos, 
+    for (; r > 0 || i < dp.parts_n; r--) {
+        if (!r) {
+            part = dp.parts[i];
+            r = part.r; i++;
+        }
+        long pos = gen_offset(part.pos,
             part.flag, n, lp, type, host_pos, len);
             
+        pos += part.s * (part.r - r);
+        
         // after EAGAIN
         if (offset && pos <= offset) {
             continue;
         }
         else if (pos < 0 || pos > n || pos < lp) {
             LOG(LOG_E, "split cancel: pos=%ld-%ld, n=%zd\n", lp, pos, n);
-            continue;
+            break;
         }
         // send part
         ssize_t s = 0;
diff --git a/main.c b/main.c
index 00b74b7..ace467b 100644
--- a/main.c
+++ b/main.c
@@ -86,14 +86,14 @@ const char help_text[] = {
     "    -K, --proto <t,h,u>       Protocol whitelist: tls,http,udp\n"
     "    -H, --hosts <file|:str>   Hosts whitelist, filename or :string\n"
     "    -V, --pf <port[-portr]>   Ports range whitelist\n"
-    "    -s, --split <n[+s]>       Split packet at n\n"
-    "                              +s - add SNI offset\n"
-    "                              +h - add HTTP Host offset\n"
-    "    -d, --disorder <n[+s]>    Split and send reverse order\n"
-    "    -o, --oob <n[+s]>         Split and send as OOB data\n"
-    "    -q, --disoob <n[+s]>      Split and send reverse order as OOB data\n"
+    "    -s, --split <pos_t>       Position format: offset[:repeats:skip][+flag1[flag2]]\n"
+    "                              Flags: +s - SNI offset, +h - HTTP host offset\n"
+    "                              Additional flags: +e - end, +m - middle, +r - random\n"
+    "    -d, --disorder <pos_t>    Split and send reverse order\n"
+    "    -o, --oob <pos_t>         Split and send as OOB data\n"
+    "    -q, --disoob <pos_t>      Split and send reverse order as OOB data\n"
     #ifdef FAKE_SUPPORT
-    "    -f, --fake <n[+s]>        Split and send fake packet\n"
+    "    -f, --fake <pos_t>        Split and send fake packet\n"
     "    -t, --ttl <num>           TTL of fake packets, default 8\n"
     #ifdef __linux__
     "    -k, --ip-opt[=f|:str]     IP options of fake packets\n"
@@ -105,7 +105,7 @@ const char help_text[] = {
     #endif
     "    -e, --oob-data <char>     Set custom OOB data\n"
     "    -M, --mod-http <h,d,r>    Modify HTTP: hcsmix,dcsmix,rmspace\n"
-    "    -r, --tlsrec <n[+s]>      Make TLS record at position\n"
+    "    -r, --tlsrec <pos_t>      Make TLS record at position\n"
     "    -a, --udp-fake <count>    UDP fakes count, default 0\n"
     #ifdef __linux__
     "    -Y, --drop-sack           Drop packets with SACK extension\n"
@@ -376,6 +376,22 @@ int parse_offset(struct part *part, const char *str)
 {
     char *end = 0;
     long val = strtol(str, &end, 0);
+    
+    while (*end == ':') {
+        long rs = strtol(end + 1, &end, 0);
+        if (rs < 0 || rs > INT_MAX) {
+            return -1;
+        }
+        if (!part->r) {
+            if (!rs) 
+                return -1;
+            part->r = rs;
+        }
+        else {
+            part->s = rs;
+            break;
+        }
+    }
     if (*end == '+') {
         switch (*(end + 1)) {
             case 's':
diff --git a/params.h b/params.h
index 7f93c0a..c715496 100644
--- a/params.h
+++ b/params.h
@@ -55,6 +55,7 @@ struct part {
     int m;
     int flag;
     long pos;
+    int r, s;
 };
 
 struct packet {