/* return 1 on success. * return 0 if could not send packet. * return -1 on failure (connection must be killed). */ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length, bool priority) { if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) { return -1; } bool sendpriority = 1; if (send_pending_data(con) == -1) { if (priority) { sendpriority = 0; } else { return 0; } } uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; uint16_t c_length = htons(length + crypto_box_MACBYTES); memcpy(packet, &c_length, sizeof(uint16_t)); int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) { return -1; } if (priority) { len = sendpriority ? send(con->sock, (const char *)packet, sizeof(packet), MSG_NOSIGNAL) : 0; if (len <= 0) { len = 0; } increment_nonce(con->sent_nonce); if ((unsigned int)len == sizeof(packet)) { return 1; } return add_priority(con, packet, sizeof(packet), len); } len = send(con->sock, (const char *)packet, sizeof(packet), MSG_NOSIGNAL); if (len <= 0) { return 0; } increment_nonce(con->sent_nonce); if ((unsigned int)len == sizeof(packet)) { return 1; } memcpy(con->last_packet, packet, sizeof(packet)); con->last_packet_length = sizeof(packet); con->last_packet_sent = len; return 1; }
static BOOL set_priority(int *plist, int psize, uschar *s, pri_item *index, int isize, uschar *which) { int sep = 0; BOOL first = TRUE; uschar *t; while ((t = string_nextinlist(&s, &sep, big_buffer, big_buffer_size)) != NULL) { int i; BOOL exclude = t[0] == '!'; if (first && !exclude) plist[0] = 0; first = FALSE; for (i = 0; i < isize; i++) { uschar *ss = strstric(t, index[i].name, FALSE); if (ss != NULL) { uschar *endss = ss + Ustrlen(index[i].name); if ((ss == t || !isalnum(ss[-1])) && !isalnum(*endss)) { if (exclude) remove_priority(plist, index[i].values); else { if (!add_priority(plist, psize, index[i].values)) { log_write(0, LOG_MAIN|LOG_PANIC, "GnuTLS init failed: %s " "priority table overflow", which); return FALSE; } } } } } } DEBUG(D_tls) { int *ptr = plist; debug_printf("adjusted %s priorities:", which); while (*ptr != 0) debug_printf(" %d", *ptr++); debug_printf("\n"); } return TRUE; }