Bug #43 » 0001-bug-41-patch.patch
src/stream-tcp-reassemble.c | ||
---|---|---|
if (SEQ_GT(list_seg->seq, (list_seg->prev->seq +
|
||
list_seg->prev->payload_len)))
|
||
{
|
||
packet_length = list_seg->payload_len + (list_seg->seq - seg->seq);
|
||
SCLogDebug("list_seg->prev %p list_seg->prev->seq %"PRIu32" "
|
||
"list_seg->prev->payload_len %"PRIu16"",
|
||
list_seg->prev, list_seg->prev->seq,
|
||
list_seg->prev->payload_len);
|
||
if (SEQ_LT(list_seg->prev->seq, seg->seq)) {
|
||
packet_length = list_seg->payload_len + (list_seg->seq -
|
||
seg->seq);
|
||
} else {
|
||
packet_length = list_seg->payload_len + (list_seg->seq -
|
||
(list_seg->prev->seq + list_seg->prev->payload_len));
|
||
}
|
||
TcpSegment *new_seg = StreamTcpGetSegment(packet_length);
|
||
if (new_seg == NULL) {
|
||
... | ... | |
TcpSegment *list_seg,
|
||
TcpSegment *seg)
|
||
{
|
||
SCEnter();
|
||
uint16_t overlap = 0;
|
||
uint16_t packet_length;
|
||
char end_before = FALSE;
|
||
... | ... | |
overlap = (list_seg->seq + list_seg->payload_len) - seg->seq;
|
||
end_after = TRUE;
|
||
SCLogDebug("starts beyond list seq, before list end, ends at list end: "
|
||
SCLogDebug("starts beyond list seq, ends after list seq end: "
|
||
"seg->seq %" PRIu32 ", seg->payload_len %"PRIu16" (%"PRIu32") "
|
||
"list_seg->seq %" PRIu32 ", list_seg->payload_len %" PRIu32 " "
|
||
"(%"PRIu32") overlap is %" PRIu32 "", seg->seq, seg->payload_len,
|
||
... | ... | |
uint16_t idx = segment_pool_idx[packet_length];
|
||
SCLogError(SC_ERR_POOL_EMPTY, "segment_pool[%"PRIu16"] is"
|
||
" empty", idx);
|
||
return -1;
|
||
SCReturnInt(-1);
|
||
}
|
||
new_seg->payload_len = packet_length;
|
||
new_seg->seq = list_seg->seq + list_seg->payload_len;
|
||
... | ... | |
list_seg->next = new_seg;
|
||
SCLogDebug("new_seg %p, new_seg->next %p, new_seg->prev %p, "
|
||
"list_seg->next %p", new_seg, new_seg->next,
|
||
new_seg->prev, list_seg->next);
|
||
"list_seg->next %p new_seg->seq %"PRIu32"", new_seg,
|
||
new_seg->next, new_seg->prev, list_seg->next,
|
||
new_seg->seq);
|
||
StreamTcpSegmentDataReplace(new_seg, seg, new_seg->seq,
|
||
new_seg->payload_len);
|
||
... | ... | |
break;
|
||
}
|
||
if (end_before == TRUE || end_same == TRUE || handle_beyond == FALSE)
|
||
return 1;
|
||
SCReturnInt(1);
|
||
}
|
||
return 0;
|
||
SCReturnInt(0);
|
||
}
|
||
int StreamTcpReassembleHandleSegmentHandleData(TcpSession *ssn,
|
||
... | ... | |
* because we've reassembled up to the ra_base_seq point already,
|
||
* so we won't do anything with segments before it anyway. */
|
||
SCLogDebug("checking for pre ra_base_seq %"PRIu32" seg %p seq %"PRIu32""
|
||
" len %"PRIu16", combined %"PRIu32"", stream->ra_base_seq,
|
||
seg, seg->seq, seg->payload_len, seg->seq+seg->payload_len);
|
||
" len %"PRIu16", combined %"PRIu32" and stream->last_ack "
|
||
"%"PRIu32"", stream->ra_base_seq, seg, seg->seq,
|
||
seg->payload_len, seg->seq+seg->payload_len, stream->last_ack);
|
||
/** \todo we should probably not even insert them into the seglist */
|
||
if (SEQ_LEQ((seg->seq + seg->payload_len), (stream->ra_base_seq+1))) {
|
||
... | ... | |
payload_len = seg->payload_len;
|
||
}
|
||
}
|
||
SCLogDebug("payload_offset is %"PRIu16", payload_len is %"PRIu16""
|
||
" and stream->last_ack is %"PRIu32"", payload_offset,
|
||
payload_len, stream->last_ack);
|
||
/* copy the data into the smsg */
|
||
uint16_t copy_size = sizeof (smsg->data.data) - smsg_offset;
|
||
if (copy_size > payload_len) {
|
||
... | ... | |
if (SCLogDebugEnabled()) {
|
||
BUG_ON(copy_size > sizeof(smsg->data.data));
|
||
}
|
||
SCLogDebug("copy_size is %"PRIu16"", copy_size);
|
||
memcpy(smsg->data.data + smsg_offset, seg->payload + payload_offset,
|
||
copy_size);
|
||
smsg_offset += copy_size;
|
||
... | ... | |
payload_offset += copy_size;
|
||
payload_len -= copy_size;
|
||
SCLogDebug("payload_offset is %"PRIu16", seg->payload_len is "
|
||
"%"PRIu16" and stream->last_ack is %"PRIu32"",
|
||
payload_offset, seg->payload_len, stream->last_ack);
|
||
if (SCLogDebugEnabled()) {
|
||
BUG_ON(payload_offset > seg->payload_len);
|
||
}
|
src/stream-tcp.c | ||
---|---|---|
static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
|
||
StreamTcpThread *stt, TcpSession *ssn)
|
||
{
|
||
SCEnter();
|
||
if (ssn == NULL)
|
||
return -1;
|
||
SCReturnInt(-1);
|
||
if (PKT_IS_TOCLIENT(p)) {
|
||
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ "
|
||
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
|
||
TCP_GET_SEQ(p), TCP_GET_ACK(p));
|
||
} else {
|
||
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
|
||
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
|
||
TCP_GET_SEQ(p), TCP_GET_ACK(p));
|
||
}
|
||
switch(p->tcph->th_flags) {
|
||
case TH_FIN:
|
||
... | ... | |
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
|
||
if (!ValidTimestamp(ssn, p))
|
||
return -1;
|
||
SCReturnInt(-1);
|
||
}
|
||
if (PKT_IS_TOCLIENT(p)) {
|
||
... | ... | |
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
|
||
" != %" PRIu32 " from stream", ssn,
|
||
TCP_GET_SEQ(p), ssn->server.next_seq);
|
||
return -1;
|
||
SCReturnInt(-1);
|
||
}
|
||
StreamTcpPacketSetState(p, ssn, TCP_LAST_ACK);
|
||
... | ... | |
SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
|
||
"%" PRIu32 "", ssn, ssn->server.next_seq,
|
||
ssn->client.last_ack);
|
||
} else {
|
||
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ "
|
||
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
|
||
TCP_GET_SEQ(p), TCP_GET_ACK(p));
|
||
if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) ||
|
||
SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack +
|
||
ssn->client.window)))
|
||
{
|
||
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
|
||
" != %" PRIu32 " from stream", ssn,
|
||
TCP_GET_SEQ(p), ssn->client.next_seq);
|
||
SCReturnInt(-1);
|
||
}
|
||
StreamTcpPacketSetState(p, ssn, TCP_LAST_ACK);
|
||
SCLogDebug("ssn %p: state changed to TCP_LAST_ACK", ssn);
|
||
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
|
||
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
|
||
ssn->server.last_ack = TCP_GET_ACK(p);
|
||
if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY))
|
||
StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn,
|
||
&ssn->client, p);
|
||
SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
|
||
"%" PRIu32 "", ssn, ssn->client.next_seq,
|
||
ssn->server.last_ack);
|
||
}
|
||
break;
|
||
case TH_ACK:
|
||
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
|
||
if (!ValidTimestamp(ssn, p))
|
||
return -1;
|
||
SCReturnInt(-1);
|
||
}
|
||
if (PKT_IS_TOCLIENT(p)) {
|
||
... | ... | |
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
|
||
" != %" PRIu32 " from stream", ssn,
|
||
TCP_GET_SEQ(p), ssn->server.next_seq);
|
||
return -1;
|
||
SCReturnInt(-1);
|
||
}
|
||
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
|
||
... | ... | |
SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
|
||
"%" PRIu32 "", ssn, ssn->server.next_seq,
|
||
ssn->client.last_ack);
|
||
} else {
|
||
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ "
|
||
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
|
||
TCP_GET_SEQ(p), TCP_GET_ACK(p));
|
||
if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) ||
|
||
SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack +
|
||
ssn->client.window)))
|
||
{
|
||
SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 ""
|
||
" != %" PRIu32 " from stream", ssn,
|
||
TCP_GET_SEQ(p), ssn->client.next_seq);
|
||
SCReturnInt(-1);
|
||
}
|
||
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
|
||
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
|
||
ssn->server.last_ack = TCP_GET_ACK(p);
|
||
if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY))
|
||
StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn,
|
||
&ssn->client, p);
|
||
SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
|
||
"%" PRIu32 "", ssn, ssn->client.next_seq,
|
||
ssn->server.last_ack);
|
||
}
|
||
break;
|
||
default:
|
||
SCLogDebug("ssn %p: default case", ssn);
|
||
break;
|
||
}
|
||
return 0;
|
||
SCReturnInt(0);
|
||
}
|
||
/**
|
- « Previous
- 1
- 2
- 3
- Next »