static TDSRET tds_update_recv_wnd(TDSSOCKET *tds, TDS_UINT new_recv_wnd) { TDS72_SMP_HEADER *mars; TDSPACKET *packet; if (!tds->conn->mars || tds->sid < 0) return TDS_SUCCESS; packet = tds_get_packet(tds->conn, sizeof(*mars)); if (!packet) return TDS_FAIL; /* TODO check result */ packet->len = sizeof(*mars); packet->sid = tds->sid; mars = (TDS72_SMP_HEADER *) packet->buf; mars->signature = TDS72_SMP; mars->type = TDS_SMP_ACK; TDS_PUT_A2LE(&mars->sid, tds->sid); mars->size = TDS_HOST4LE(16); TDS_PUT_A4LE(&mars->seq, tds->send_seq); tds->recv_wnd = new_recv_wnd; TDS_PUT_A4LE(&mars->wnd, tds->recv_wnd); tds_mutex_lock(&tds->conn->list_mtx); tds_append_packet(&tds->conn->send_packets, packet); tds_mutex_unlock(&tds->conn->list_mtx); return TDS_SUCCESS; }
TDSRET tds_append_fin(TDSSOCKET *tds) { TDS72_SMP_HEADER mars; TDSPACKET *packet; if (!tds->conn->mars || tds->sid < 0) return TDS_SUCCESS; mars.signature = TDS72_SMP; mars.type = TDS_SMP_FIN; TDS_PUT_A2LE(&mars.sid, tds->sid); mars.size = TDS_HOST4LE(16); TDS_PUT_A4LE(&mars.seq, tds->send_seq); tds->recv_wnd = tds->recv_seq + 4; TDS_PUT_A4LE(&mars.wnd, tds->recv_wnd); /* do not use tds_get_packet as it require no lock ! */ packet = tds_alloc_packet(&mars, sizeof(mars)); if (!packet) return TDS_FAIL; /* TODO check result */ packet->sid = tds->sid; /* we already hold lock so do not lock */ tds_append_packet(&tds->conn->send_packets, packet); /* now is no more an active session */ tds->conn->sessions[tds->sid] = BUSY_SOCKET; tds_set_state(tds, TDS_DEAD); tds->sid = -1; return TDS_SUCCESS; }
static TDSPACKET* tds_build_packet(TDSSOCKET *tds, unsigned char *buf, unsigned len) { unsigned start; TDS72_SMP_HEADER mars[2], *p; TDSPACKET *packet; p = mars; if (buf[0] != TDS72_SMP && tds->conn->mars) { /* allocate a new sid */ if (tds->sid == -1) { p->signature = TDS72_SMP; p->type = TDS_SMP_SYN; /* start session */ /* FIXME check !!! */ tds_alloc_new_sid(tds); tds->recv_seq = 0; tds->send_seq = 0; tds->recv_wnd = 4; tds->send_wnd = 4; TDS_PUT_A2LE(&p->sid, tds->sid); p->size = TDS_HOST4LE(0x10); p->seq = TDS_HOST4LE(0); TDS_PUT_A4LE(&p->wnd, tds->recv_wnd); p++; } if (tds->sid >= 0) { p->signature = TDS72_SMP; p->type = TDS_SMP_DATA; TDS_PUT_A2LE(&p->sid, tds->sid); TDS_PUT_A4LE(&p->size, len+16); TDS_PUT_A4LE(&p->seq, ++tds->send_seq); /* this is the acknowledge we give to server to stop sending !!! */ tds->recv_wnd = tds->recv_seq + 4; TDS_PUT_A4LE(&p->wnd, tds->recv_wnd); p++; } } start = (p - mars) * sizeof(mars[0]); packet = tds_get_packet(tds->conn, len + start); if (TDS_LIKELY(packet)) { packet->sid = tds->sid; memcpy(packet->buf, mars, start); memcpy(packet->buf + start, buf, len); packet->len = len + start; } return packet; }
static int put_ucs4le(unsigned char *buf, size_t buf_len, ICONV_CHAR c) { if (buf_len < 4) return -E2BIG; TDS_PUT_A4LE(buf, c); return 4; }