diff -u -r -x .DS_Store openvpn-2.4.6.old/src/openvpn/socket.c openvpn-2.4.6.new/src/openvpn/socket.c
--- openvpn-2.4.6.old/src/openvpn/socket.c	2018-07-28 06:02:25.000000000 -0400
+++ openvpn-2.4.6.new/src/openvpn/socket.c	2018-07-28 06:02:25.000000000 -0400
@@ -54,6 +54,53 @@
     IPv6_TCP_HEADER_SIZE,
 };
 
+int buffer_mask (struct buffer *buf, const char *mask, int xormasklen) {
+	int i;
+	uint8_t *b;
+	if (  xormasklen > 0  ) {
+		for (i = 0, b = BPTR (buf); i < BLEN(buf); i++, b++) {
+			*b = *b ^ mask[i % xormasklen];
+		}
+	}
+	return BLEN (buf);
+}
+
+int buffer_xorptrpos (struct buffer *buf) {
+	int i;
+	uint8_t *b;
+	for (i = 0, b = BPTR (buf); i < BLEN(buf); i++, b++) {
+		*b = *b ^ i+1;
+	}
+	return BLEN (buf);
+}
+
+int buffer_reverse (struct buffer *buf) {
+/* This function has been rewritten for Tunnelblick. The buffer_reverse function at
+ * https://github.com/clayface/openvpn_xorpatch
+ * makes a copy of the buffer and it writes to the byte **after** the
+ * buffer contents, so if the buffer is full then it writes outside of the buffer.
+ * This rewritten version does neither.
+ *
+ * For interoperability, this rewritten version preserves the behavior of the original
+ * function: it does not modify the first character of the buffer. So it does not
+ * actually reverse the contents of the buffer. Instead, it changes 'abcde' to 'aedcb'.
+ * (Of course, the actual buffer contents are bytes, and not necessarily characters.)
+ */
+  int len = BLEN(buf);
+  if (  len > 2  ) {                           /* Leave '', 'a', and 'ab' alone */
+    int i;
+    uint8_t *b_start = BPTR (buf) + 1;	        /* point to first byte to swap */
+    uint8_t *b_end   = BPTR (buf) + (len - 1); /* point to last byte to swap */
+    uint8_t tmp;
+    for (i = 0; i < (len-1)/2; i++, b_start++, b_end--) {
+      tmp = *b_start;
+      *b_start = *b_end;
+      *b_end = tmp;
+    }
+  }
+  return len;
+}
+
 /*
  * Convert sockflags/getaddr_flags into getaddr_flags
  */
