char* body; /* body position */
unsigned int b_size; /* buffer size-1 (extra space for 0-term)*/
int content_len;
- int has_content_len; /* 1 if content_length was parsed ok*/
- int complete; /* 1 if one req has been fully read, 0 otherwise*/
+ unsigned short flags; /* F_TCP_REQ_HAS_CLEN | F_TCP_REQ_COMPLETE */
int bytes_to_go; /* how many bytes we have still to read from the body*/
enum tcp_req_errors error;
enum tcp_req_states state;
};
+/* tcp_req flags */
+#define F_TCP_REQ_HAS_CLEN 1
+#define F_TCP_REQ_COMPLETE 2
+
+#define TCP_REQ_HAS_CLEN(tr) ((tr)->flags & F_TCP_REQ_HAS_CLEN)
+#define TCP_REQ_COMPLETE(tr) ((tr)->flags & F_TCP_REQ_COMPLETE)
struct tcp_connection;
#define content_len_beg_case \
case ' ': \
case '\t': \
- if (!r->has_content_len) r->state=H_STARTWS; \
+ if (!TCP_REQ_HAS_CLEN(r)) r->state=H_STARTWS; \
else r->state=H_SKIP; \
/* not interested if we already found one */ \
break; \
case 'C': \
case 'c': \
- if(!r->has_content_len) r->state=H_CONT_LEN1; \
+ if(!TCP_REQ_HAS_CLEN(r)) r->state=H_CONT_LEN1; \
else r->state=H_SKIP; \
break; \
case 'l': \
case 'L': \
/* short form for Content-Length */ \
- if (!r->has_content_len) r->state=H_L_COLON; \
+ if (!TCP_REQ_HAS_CLEN(r)) r->state=H_L_COLON; \
else r->state=H_SKIP; \
break
r->bytes_to_go-=remaining;
p+=remaining;
if (r->bytes_to_go==0){
- r->complete=1;
+ r->flags|=F_TCP_REQ_COMPLETE;
goto skip;
}
break;
case '\n':
/* found LF LF */
r->state=H_BODY;
- if (r->has_content_len){
+ if (TCP_REQ_HAS_CLEN(r)){
r->body=p+1;
r->bytes_to_go=r->content_len;
if (r->bytes_to_go==0){
- r->complete=1;
+ r->flags|=F_TCP_REQ_COMPLETE;
p++;
goto skip;
}
if (*p=='\n'){
/* found LF CR LF */
r->state=H_BODY;
- if (r->has_content_len){
+ if (TCP_REQ_HAS_CLEN(r)){
r->body=p+1;
r->bytes_to_go=r->content_len;
if (r->bytes_to_go==0){
- r->complete=1;
+ r->flags|=F_TCP_REQ_COMPLETE;
p++;
goto skip;
}
case H_SKIP_EMPTY_CRLFCR_FOUND:
if (*p=='\n'){
r->state = H_PING_CRLF;
- r->complete = 1;
- r->has_content_len = 1; /* hack to avoid error check */
+ r->flags |= F_TCP_REQ_HAS_CLEN |
+ F_TCP_REQ_COMPLETE; /* hack to avoid error check */
p++;
goto skip;
}else{
/* using has_content_len as a flag if there should be
* fingerprint or no
*/
- r->has_content_len = (mc == MAGIC_COOKIE) ? 1 : 0;
+ r->flags |= (mc == MAGIC_COOKIE) ? F_TCP_REQ_HAS_CLEN : 0;
r->body += sizeof(struct stun_hdr);
p = r->body;
r->body += body_len;
p = r->body;
r->state = H_STUN_END;
- r->complete = 1;
- r->has_content_len = 1; /* hack to avoid error check */
+ r->flags |= F_TCP_REQ_COMPLETE |
+ F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
goto skip;
}
else {
case ' ':
case '\t': /* FIXME: check if line contains only WS */
r->state=H_SKIP;
- r->has_content_len=1;
+ r->flags|=F_TCP_REQ_HAS_CLEN;
break;
case '\n':
/* end of line, parse successful */
r->state=H_LF;
- r->has_content_len=1;
+ r->flags|=F_TCP_REQ_HAS_CLEN;
break;
default:
LOG(L_ERR, "ERROR: tcp_read_headers: bad "
* if req. is complete we might have a second unparsed
* request after it, so postpone release_with_eof
*/
- if (unlikely((con->state==S_CONN_EOF) && (req->complete==0))) {
+ if (unlikely((con->state==S_CONN_EOF) &&
+ (! TCP_REQ_COMPLETE(req)))) {
DBG( "tcp_read_req: EOF\n");
resp=CONN_EOF;
goto end_req;
resp=CONN_ERROR;
goto end_req;
}
- if (likely(req->complete)){
+ if (likely(TCP_REQ_COMPLETE(req))){
#ifdef EXTRA_DEBUG
DBG("tcp_read_req: end of header part\n");
DBG("- received from: port %d\n", con->rcv.src_port);
DBG("tcp_read_req: headers:\n%.*s.\n",
(int)(req->body-req->start), req->start);
#endif
- if (likely(req->has_content_len)){
+ if (likely(TCP_REQ_HAS_CLEN(req))){
DBG("tcp_read_req: content-length= %d\n", req->content_len);
#ifdef EXTRA_DEBUG
DBG("tcp_read_req: body:\n%.*s\n", req->content_len,req->body);
req->body=0;
req->error=TCP_REQ_OK;
req->state=H_SKIP_EMPTY;
- req->complete=req->content_len=req->has_content_len=0;
+ req->flags=0;
+ req->content_len=0;
req->bytes_to_go=0;
req->pos=req->buf+size;
#ifdef USE_STUN
int is_msg_complete(struct tcp_req* r)
{
- if (r->has_content_len == 1) {
+ if (TCP_REQ_HAS_CLEN(r)) {
r->state = H_STUN_FP;
return 0;
}
else {
/* STUN message is complete */
r->state = H_STUN_END;
- r->complete = 1;
- r->has_content_len = 1; /* hack to avoid error check */
+ r->flags |= F_TCP_REQ_COMPLETE |
+ F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
return 1;
}
}