/* allocate a buffer for socket or tun layer */ void alloc_buf_sock_tun (struct buffer *buf, const struct frame *frame, const bool tuntap_buffer, const unsigned int align_mask) { /* allocate buffer for overlapped I/O */ *buf = alloc_buf (BUF_SIZE (frame)); ASSERT (buf_init (buf, FRAME_HEADROOM_ADJ (frame, align_mask))); buf->len = tuntap_buffer ? MAX_RW_SIZE_TUN (frame) : MAX_RW_SIZE_LINK (frame); ASSERT (buf_safe (buf, 0)); }
/* * force a null termination even it requires * truncation of the last char. */ void buf_null_terminate (struct buffer *buf) { char *last = (char *) BLAST (buf); if (last && *last == '\0') /* already terminated? */ return; if (!buf_safe (buf, 1)) /* make space for trailing null */ buf_inc_len (buf, -1); buf_write_u8 (buf, 0); }
void read_incoming_tun (struct context *c) { /* * Setup for read() call on TUN/TAP device. */ /*ASSERT (!c->c2.to_link.len);*/ perf_push (PERF_READ_IN_TUN); c->c2.buf = c->c2.buffers->read_tun_buf; #ifdef TUN_PASS_BUFFER read_tun_buffered (c->c1.tuntap, &c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame)); #else ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM (&c->c2.frame))); ASSERT (buf_safe (&c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame))); c->c2.buf.len = read_tun (c->c1.tuntap, BPTR (&c->c2.buf), MAX_RW_SIZE_TUN (&c->c2.frame)); #endif #ifdef PACKET_TRUNCATION_CHECK ipv4_packet_size_verify (BPTR (&c->c2.buf), BLEN (&c->c2.buf), TUNNEL_TYPE (c->c1.tuntap), "READ_TUN", &c->c2.n_trunc_tun_read); #endif /* Was TUN/TAP interface stopped? */ if (tuntap_stop (c->c2.buf.len)) { register_signal (c, SIGTERM, "tun-stop"); msg (M_INFO, "TUN/TAP interface has been stopped, exiting"); perf_pop (); return; } /* Was TUN/TAP I/O operation aborted? */ if (tuntap_abort(c->c2.buf.len)) { register_signal(c, SIGHUP, "tun-abort"); c->persist.restart_sleep_seconds = 10; msg(M_INFO, "TUN/TAP I/O operation aborted, restarting"); perf_pop(); return; } /* Check the status return from read() */ check_status (c->c2.buf.len, "read from TUN/TAP", NULL, c->c1.tuntap); perf_pop (); }
static void lz4_compress(struct buffer *buf, struct buffer work, struct compress_context *compctx, const struct frame *frame) { bool compressed; if (buf->len <= 0) { return; } compressed = do_lz4_compress(buf, &work, compctx, frame); /* On error do_lz4_compress sets buf len to zero, just return */ if (buf->len == 0) { return; } /* did compression save us anything? */ { uint8_t comp_head_byte = NO_COMPRESS_BYTE_SWAP; if (compressed && work.len < buf->len) { *buf = work; comp_head_byte = LZ4_COMPRESS_BYTE; } { uint8_t *head = BPTR(buf); uint8_t *tail = BEND(buf); ASSERT(buf_safe(buf, 1)); ++buf->len; /* move head byte of payload to tail */ *tail = *head; *head = comp_head_byte; } } }
bool tls_crypt_unwrap(const struct buffer *src, struct buffer *dst, struct crypto_options *opt) { static const char error_prefix[] = "tls-crypt unwrap error"; const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt; struct gc_arena gc; gc_init(&gc); ASSERT(opt); ASSERT(src->len > 0); ASSERT(ctx->cipher); ASSERT(packet_id_initialized(&opt->packet_id) || (opt->flags & CO_IGNORE_PACKET_ID)); dmsg(D_PACKET_CONTENT, "TLS-CRYPT UNWRAP FROM: %s", format_hex(BPTR(src), BLEN(src), 80, &gc)); if (buf_len(src) < TLS_CRYPT_OFF_CT) { CRYPT_ERROR("packet too short"); } /* Decrypt cipher text */ { int outlen = 0; /* Buffer overflow check (should never fail) */ if (!buf_safe(dst, BLEN(src) - TLS_CRYPT_OFF_CT + TLS_CRYPT_BLOCK_SIZE)) { CRYPT_ERROR("potential buffer overflow"); } if (!cipher_ctx_reset(ctx->cipher, BPTR(src) + TLS_CRYPT_OFF_TAG)) { CRYPT_ERROR("cipher reset failed"); } if (!cipher_ctx_update(ctx->cipher, BPTR(dst), &outlen, BPTR(src) + TLS_CRYPT_OFF_CT, BLEN(src) - TLS_CRYPT_OFF_CT)) { CRYPT_ERROR("cipher update failed"); } ASSERT(buf_inc_len(dst, outlen)); if (!cipher_ctx_final(ctx->cipher, BPTR(dst), &outlen)) { CRYPT_ERROR("cipher final failed"); } ASSERT(buf_inc_len(dst, outlen)); } /* Check authentication */ { const uint8_t *tag = BPTR(src) + TLS_CRYPT_OFF_TAG; uint8_t tag_check[TLS_CRYPT_TAG_SIZE] = { 0 }; dmsg(D_PACKET_CONTENT, "TLS-CRYPT UNWRAP AD: %s", format_hex(BPTR(src), TLS_CRYPT_OFF_TAG, 0, &gc)); dmsg(D_PACKET_CONTENT, "TLS-CRYPT UNWRAP TO: %s", format_hex(BPTR(dst), BLEN(dst), 80, &gc)); hmac_ctx_reset(ctx->hmac); hmac_ctx_update(ctx->hmac, BPTR(src), TLS_CRYPT_OFF_TAG); hmac_ctx_update(ctx->hmac, BPTR(dst), BLEN(dst)); hmac_ctx_final(ctx->hmac, tag_check); if (memcmp_constant_time(tag, tag_check, sizeof(tag_check))) { dmsg(D_CRYPTO_DEBUG, "tag : %s", format_hex(tag, sizeof(tag_check), 0, &gc)); dmsg(D_CRYPTO_DEBUG, "tag_check: %s", format_hex(tag_check, sizeof(tag_check), 0, &gc)); CRYPT_ERROR("packet authentication failed"); } } /* Check replay */ if (!(opt->flags & CO_IGNORE_PACKET_ID)) { struct packet_id_net pin; struct buffer tmp = *src; ASSERT(buf_advance(&tmp, TLS_CRYPT_OFF_PID)); ASSERT(packet_id_read(&pin, &tmp, true)); if (!crypto_check_replay(opt, &pin, error_prefix, &gc)) { CRYPT_ERROR("packet replay"); } } gc_free(&gc); return true; error_exit: crypto_clear_error(); dst->len = 0; gc_free(&gc); return false; }
bool tls_crypt_wrap(const struct buffer *src, struct buffer *dst, struct crypto_options *opt) { const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt; struct gc_arena gc; /* IV, packet-ID and implicit IV required for this mode. */ ASSERT(ctx->cipher); ASSERT(ctx->hmac); ASSERT(packet_id_initialized(&opt->packet_id)); ASSERT(hmac_ctx_size(ctx->hmac) == 256/8); gc_init(&gc); dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP FROM: %s", format_hex(BPTR(src), BLEN(src), 80, &gc)); /* Get packet ID */ if (!packet_id_write(&opt->packet_id.send, dst, true, false)) { msg(D_CRYPT_ERRORS, "TLS-CRYPT ERROR: packet ID roll over."); goto err; } dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s", format_hex(BPTR(dst), BLEN(dst), 0, &gc)); /* Buffer overflow check */ if (!buf_safe(dst, BLEN(src) + TLS_CRYPT_BLOCK_SIZE + TLS_CRYPT_TAG_SIZE)) { msg(D_CRYPT_ERRORS, "TLS-CRYPT WRAP: buffer size error, " "sc=%d so=%d sl=%d dc=%d do=%d dl=%d", src->capacity, src->offset, src->len, dst->capacity, dst->offset, dst->len); goto err; } /* Calculate auth tag and synthetic IV */ { uint8_t *tag = NULL; hmac_ctx_reset(ctx->hmac); hmac_ctx_update(ctx->hmac, BPTR(dst), BLEN(dst)); hmac_ctx_update(ctx->hmac, BPTR(src), BLEN(src)); ASSERT(tag = buf_write_alloc(dst, TLS_CRYPT_TAG_SIZE)); hmac_ctx_final(ctx->hmac, tag); dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP TAG: %s", format_hex(tag, TLS_CRYPT_TAG_SIZE, 0, &gc)); /* Use the 128 most significant bits of the tag as IV */ ASSERT(cipher_ctx_reset(ctx->cipher, tag)); } /* Encrypt src */ { int outlen = 0; ASSERT(cipher_ctx_update(ctx->cipher, BEND(dst), &outlen, BPTR(src), BLEN(src))); ASSERT(buf_inc_len(dst, outlen)); ASSERT(cipher_ctx_final(ctx->cipher, BPTR(dst), &outlen)); ASSERT(buf_inc_len(dst, outlen)); } dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP TO: %s", format_hex(BPTR(dst), BLEN(dst), 80, &gc)); gc_free(&gc); return true; err: crypto_clear_error(); dst->len = 0; gc_free(&gc); return false; }
static void lzo_compress(struct buffer *buf, struct buffer work, struct compress_context *compctx, const struct frame *frame) { lzo_uint zlen = 0; int err; bool compressed = false; if (buf->len <= 0) { return; } /* * In order to attempt compression, length must be at least COMPRESS_THRESHOLD, * and our adaptive level must give the OK. */ if (buf->len >= COMPRESS_THRESHOLD && lzo_compression_enabled(compctx)) { const size_t ps = PAYLOAD_SIZE(frame); ASSERT(buf_init(&work, FRAME_HEADROOM(frame))); ASSERT(buf_safe(&work, ps + COMP_EXTRA_BUFFER(ps))); if (buf->len > ps) { dmsg(D_COMP_ERRORS, "LZO compression buffer overflow"); buf->len = 0; return; } err = LZO_COMPRESS(BPTR(buf), BLEN(buf), BPTR(&work), &zlen, compctx->wu.lzo.wmem); if (err != LZO_E_OK) { dmsg(D_COMP_ERRORS, "LZO compression error: %d", err); buf->len = 0; return; } ASSERT(buf_safe(&work, zlen)); work.len = zlen; compressed = true; dmsg(D_COMP, "LZO compress %d -> %d", buf->len, work.len); compctx->pre_compress += buf->len; compctx->post_compress += work.len; /* tell adaptive level about our success or lack thereof in getting any size reduction */ if (compctx->flags & COMP_F_ADAPTIVE) { lzo_adaptive_compress_data(&compctx->wu.lzo.ac, buf->len, work.len); } } /* did compression save us anything ? */ if (compressed && work.len < buf->len) { uint8_t *header = buf_prepend(&work, 1); *header = LZO_COMPRESS_BYTE; *buf = work; } else { uint8_t *header = buf_prepend(buf, 1); *header = NO_COMPRESS_BYTE; } }
void openvpn_encrypt (struct buffer *buf, struct buffer work, const struct crypto_options *opt, const struct frame* frame) { struct gc_arena gc; gc_init (&gc); if (buf->len > 0 && opt->key_ctx_bi) { struct key_ctx *ctx = &opt->key_ctx_bi->encrypt; /* Do Encrypt from buf -> work */ if (ctx->cipher) { uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; const int iv_size = cipher_ctx_iv_length (ctx->cipher); const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher); int outlen; if (cipher_kt_mode_cbc(cipher_kt)) { CLEAR (iv_buf); /* generate pseudo-random IV */ if (opt->flags & CO_USE_IV) prng_bytes (iv_buf, iv_size); /* Put packet ID in plaintext buffer or IV, depending on cipher mode */ if (opt->packet_id) { struct packet_id_net pin; packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)); ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); } } else if (cipher_kt_mode_ofb_cfb(cipher_kt)) { struct packet_id_net pin; struct buffer b; ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */ ASSERT (opt->packet_id); /* for this mode. */ packet_id_alloc_outgoing (&opt->packet_id->send, &pin, true); memset (iv_buf, 0, iv_size); buf_set_write (&b, iv_buf, iv_size); ASSERT (packet_id_write (&pin, &b, true, false)); } else /* We only support CBC, CFB, or OFB modes right now */ { ASSERT (0); } /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */ ASSERT (buf_init (&work, FRAME_HEADROOM (frame))); /* set the IV pseudo-randomly */ if (opt->flags & CO_USE_IV) dmsg (D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex (iv_buf, iv_size, 0, &gc)); dmsg (D_PACKET_CONTENT, "ENCRYPT FROM: %s", format_hex (BPTR (buf), BLEN (buf), 80, &gc)); /* cipher_ctx was already initialized with key & keylen */ ASSERT (cipher_ctx_reset(ctx->cipher, iv_buf)); /* Buffer overflow check */ if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher))) { msg (D_CRYPT_ERRORS, "ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d cbs=%d", buf->capacity, buf->offset, buf->len, work.capacity, work.offset, work.len, cipher_ctx_block_size (ctx->cipher)); goto err; } /* Encrypt packet ID, payload */ ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))); ASSERT (buf_inc_len(&work, outlen)); /* Flush the encryption buffer */ ASSERT (cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen)); ASSERT (buf_inc_len(&work, outlen)); /* For all CBC mode ciphers, check the last block is complete */ ASSERT (cipher_kt_mode (cipher_kt) != OPENVPN_MODE_CBC || outlen == iv_size); /* prepend the IV to the ciphertext */ if (opt->flags & CO_USE_IV) { uint8_t *output = buf_prepend (&work, iv_size); ASSERT (output); memcpy (output, iv_buf, iv_size); } dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s", format_hex (BPTR (&work), BLEN (&work), 80, &gc)); } else /* No Encryption */ { if (opt->packet_id) { struct packet_id_net pin; packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)); ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); } work = *buf; } /* HMAC the ciphertext (or plaintext if !cipher) */ if (ctx->hmac) { uint8_t *output = NULL; hmac_ctx_reset (ctx->hmac); hmac_ctx_update (ctx->hmac, BPTR(&work), BLEN(&work)); output = buf_prepend (&work, hmac_ctx_size(ctx->hmac)); ASSERT (output); hmac_ctx_final (ctx->hmac, output); } *buf = work; } gc_free (&gc); return; err: crypto_clear_error(); buf->len = 0; gc_free (&gc); return; }
/* * If (opt->flags & CO_USE_IV) is not NULL, we will read an IV from the packet. * * Set buf->len to 0 and return false on decrypt error. * * On success, buf is set to point to plaintext, true * is returned. */ bool openvpn_decrypt (struct buffer *buf, struct buffer work, const struct crypto_options *opt, const struct frame* frame) { static const char error_prefix[] = "Authenticate/Decrypt packet error"; struct gc_arena gc; gc_init (&gc); if (buf->len > 0 && opt->key_ctx_bi) { struct key_ctx *ctx = &opt->key_ctx_bi->decrypt; struct packet_id_net pin; bool have_pin = false; /* Verify the HMAC */ if (ctx->hmac) { int hmac_len; uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */ hmac_ctx_reset(ctx->hmac); /* Assume the length of the input HMAC */ hmac_len = hmac_ctx_size (ctx->hmac); /* Authentication fails if insufficient data in packet for HMAC */ if (buf->len < hmac_len) CRYPT_ERROR ("missing authentication info"); hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len, BLEN (buf) - hmac_len); hmac_ctx_final (ctx->hmac, local_hmac); /* Compare locally computed HMAC with packet HMAC */ if (memcmp_constant_time (local_hmac, BPTR (buf), hmac_len)) CRYPT_ERROR ("packet HMAC authentication failed"); ASSERT (buf_advance (buf, hmac_len)); } /* Decrypt packet ID + payload */ if (ctx->cipher) { const int iv_size = cipher_ctx_iv_length (ctx->cipher); const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher); uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; int outlen; /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */ ASSERT (buf_init (&work, FRAME_HEADROOM_ADJ (frame, FRAME_HEADROOM_MARKER_DECRYPT))); /* use IV if user requested it */ CLEAR (iv_buf); if (opt->flags & CO_USE_IV) { if (buf->len < iv_size) CRYPT_ERROR ("missing IV info"); memcpy (iv_buf, BPTR (buf), iv_size); ASSERT (buf_advance (buf, iv_size)); } /* show the IV's initial state */ if (opt->flags & CO_USE_IV) dmsg (D_PACKET_CONTENT, "DECRYPT IV: %s", format_hex (iv_buf, iv_size, 0, &gc)); if (buf->len < 1) CRYPT_ERROR ("missing payload"); /* ctx->cipher was already initialized with key & keylen */ if (!cipher_ctx_reset (ctx->cipher, iv_buf)) CRYPT_ERROR ("cipher init failed"); /* Buffer overflow check (should never happen) */ if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher))) CRYPT_ERROR ("potential buffer overflow"); /* Decrypt packet ID, payload */ if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))) CRYPT_ERROR ("cipher update failed"); ASSERT (buf_inc_len(&work, outlen)); /* Flush the decryption buffer */ if (!cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen)) CRYPT_ERROR ("cipher final failed"); ASSERT (buf_inc_len(&work, outlen)); dmsg (D_PACKET_CONTENT, "DECRYPT TO: %s", format_hex (BPTR (&work), BLEN (&work), 80, &gc)); /* Get packet ID from plaintext buffer or IV, depending on cipher mode */ { if (cipher_kt_mode_cbc(cipher_kt)) { if (opt->packet_id) { if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM))) CRYPT_ERROR ("error reading CBC packet-id"); have_pin = true; } } else if (cipher_kt_mode_ofb_cfb(cipher_kt)) { struct buffer b; ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */ ASSERT (opt->packet_id); /* for this mode. */ buf_set_read (&b, iv_buf, iv_size); if (!packet_id_read (&pin, &b, true)) CRYPT_ERROR ("error reading CFB/OFB packet-id"); have_pin = true; } else /* We only support CBC, CFB, or OFB modes right now */ { ASSERT (0); } } } else { work = *buf; if (opt->packet_id) { if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM))) CRYPT_ERROR ("error reading packet-id"); have_pin = !BOOL_CAST (opt->flags & CO_IGNORE_PACKET_ID); } } if (have_pin) { packet_id_reap_test (&opt->packet_id->rec); if (packet_id_test (&opt->packet_id->rec, &pin)) { packet_id_add (&opt->packet_id->rec, &pin); if (opt->pid_persist && (opt->flags & CO_PACKET_ID_LONG_FORM)) packet_id_persist_save_obj (opt->pid_persist, opt->packet_id); } else { if (!(opt->flags & CO_MUTE_REPLAY_WARNINGS)) msg (D_REPLAY_ERRORS, "%s: bad packet ID (may be a replay): %s -- see the man page entry for --no-replay and --replay-window for more info or silence this warning with --mute-replay-warnings", error_prefix, packet_id_net_print (&pin, true, &gc)); goto error_exit; } } *buf = work; } gc_free (&gc); return true; error_exit: crypto_clear_error(); buf->len = 0; gc_free (&gc); return false; }
void check_send_occ_msg_dowork (struct context *c) { bool doit = false; c->c2.buf = c->c2.buffers->aux_buf; ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM (&c->c2.frame))); ASSERT (buf_safe (&c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame))); ASSERT (buf_write (&c->c2.buf, occ_magic, OCC_STRING_SIZE)); switch (c->c2.occ_op) { case OCC_REQUEST: if (!buf_write_u8 (&c->c2.buf, OCC_REQUEST)) break; dmsg (D_PACKET_CONTENT, "SENT OCC_REQUEST"); doit = true; break; case OCC_REPLY: if (!c->c2.options_string_local) break; if (!buf_write_u8 (&c->c2.buf, OCC_REPLY)) break; if (!buf_write (&c->c2.buf, c->c2.options_string_local, strlen (c->c2.options_string_local) + 1)) break; dmsg (D_PACKET_CONTENT, "SENT OCC_REPLY"); doit = true; break; case OCC_MTU_REQUEST: if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REQUEST)) break; dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_REQUEST"); doit = true; break; case OCC_MTU_REPLY: if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REPLY)) break; if (!buf_write_u16 (&c->c2.buf, c->c2.max_recv_size_local)) break; if (!buf_write_u16 (&c->c2.buf, c->c2.max_send_size_local)) break; dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_REPLY"); doit = true; break; case OCC_MTU_LOAD_REQUEST: if (!buf_write_u8 (&c->c2.buf, OCC_MTU_LOAD_REQUEST)) break; if (!buf_write_u16 (&c->c2.buf, c->c2.occ_mtu_load_size)) break; dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD_REQUEST"); doit = true; break; case OCC_MTU_LOAD: { int need_to_add; if (!buf_write_u8 (&c->c2.buf, OCC_MTU_LOAD)) break; need_to_add = min_int (c->c2.occ_mtu_load_size, EXPANDED_SIZE (&c->c2.frame)) - OCC_STRING_SIZE - sizeof (uint8_t) - EXTRA_FRAME (&c->c2.frame); while (need_to_add > 0) { /* * Fill the load test packet with pseudo-random bytes. */ if (!buf_write_u8 (&c->c2.buf, get_random () & 0xFF)) break; --need_to_add; } dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD min_int(%d-%d-%d-%d,%d) size=%d", c->c2.occ_mtu_load_size, OCC_STRING_SIZE, (int) sizeof (uint8_t), EXTRA_FRAME (&c->c2.frame), MAX_RW_SIZE_TUN (&c->c2.frame), BLEN (&c->c2.buf)); doit = true; } break; case OCC_EXIT: if (!buf_write_u8 (&c->c2.buf, OCC_EXIT)) break; dmsg (D_PACKET_CONTENT, "SENT OCC_EXIT"); doit = true; break; } if (doit) { /* * We will treat the packet like any other outgoing packet, * compress, encrypt, sign, etc. */ encrypt_sign (c, true); } c->c2.occ_op = -1; }
/* * Should we ping the remote? */ void check_ping_send_dowork (struct context *c) { c->c2.buf = c->c2.buffers->aux_buf; ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM (&c->c2.frame))); ASSERT (buf_safe (&c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame))); ASSERT (buf_write (&c->c2.buf, ping_string, sizeof (ping_string))); /* * We will treat the ping like any other outgoing packet, * encrypt, sign, etc. */ encrypt_sign (c, true); dmsg (D_PING, "SENT PING"); }