Ejemplo n.º 1
0
/*
 * return : true to bypass all processing from the stack
 *          false to go through the whole stack to process a given msg
 */
bool
dmsg_process(struct context *ctx, struct conn *conn, struct dmsg *dmsg)
{
    ASSERT(dmsg != NULL);
    ASSERT(conn->dyn_mode);

    switch(dmsg->type) {

        case GOSSIP_SYN:
           log_debug(LOG_DEBUG, "I have got a GOSSIP_SYN!!!!!!");
           dmsg_dump(dmsg);
           //TODOs: fix this to reply the 1st time sender
           //dnode_rsp_gos_syn(ctx, conn, dmsg->owner);
           dmsg_parse(dmsg);
           return true;

        case CRYPTO_HANDSHAKE:
           log_debug(LOG_DEBUG, "I have a crypto handshake msg and processing it now");
            //TODOs: will work on this to optimize the performance
           return true;

        case GOSSIP_SYN_REPLY:
           log_debug(LOG_DEBUG, "I have got a GOSSIP_SYN_REPLY!!!!!!");

           return true;
        default:
           log_debug(LOG_DEBUG, "nothing to do");
    }
       
    return false;
}
Ejemplo n.º 2
0
static bool 
dyn_parse_core(struct msg *r)
{
	struct dmsg *dmsg;
	struct mbuf *b;
	uint8_t *p;
	uint8_t ch;
	uint64_t num = 0;

	state = r->dyn_state;
	b = STAILQ_LAST(&r->mhdr, mbuf, next);

	dmsg = r->dmsg;
	if (dmsg == NULL) {
		r->dmsg = dmsg_get();
		dmsg = r->dmsg;
		if (dmsg == NULL) {//should track this as a dropped message
			goto error; //should count as OOM error
		}
	}

	//log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "dyn parser: parsed req %"PRIu64" res %d type %d", r->id, r->result, r->type, r->dyn_state);

	for (p = r->pos; p < b->last; p++) {
		ch = *p;
		switch (state) {
		case DYN_START:
			//log_debug(LOG_DEBUG, "DYN_START");
			if (ch == ' ') {
				break;
			} else if (isdigit(ch)) {
				num = ch - '0';
				state = DYN_MAGIC_NUMBER;
			} else {
				goto skip;
			}

			break;

		case DYN_MAGIC_NUMBER:
			//log_debug(LOG_DEBUG, "DYN_MAGIC_NUMBER");
			//log_debug(LOG_DEBUG, "num = %d", num);
			if (isdigit(ch))  {
				num = num*10 + (ch - '0');
			} else {
				if (num == MAGIC_NUMBER) {
					state = DYN_SPACES_BEFORE_MSG_ID;
				} else {
					goto error;
				}
			}

			break;

		case DYN_SPACES_BEFORE_MSG_ID:
			//log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_MSG_ID");
			if (ch == ' ') {
				break;
			} else if (isdigit(ch)) {
				num = ch - '0';
				state = DYN_MSG_ID;
			}  else {
				goto error;
			}

			break;

		case DYN_MSG_ID:
			log_debug(LOG_DEBUG, "DYN_MSG_ID");
			log_debug(LOG_DEBUG, "num = %d", num);
			if (isdigit(ch))  {
				num = num*10 + (ch - '0');
			} else if (ch != ' ') {
				goto error;
			} else {

				//if (num >= 0) {
				//log_debug(LOG_DEBUG, "MSG ID : %d", num);
				dmsg->id = num;
				state = DYN_SPACES_BEFORE_TYPE_ID;
				//} else {
					//   goto error;
				//}
			}
			break;

		case DYN_SPACES_BEFORE_TYPE_ID:
			log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_TYPE_ID");
			if (ch == ' ') {
				break;
			} else if (isdigit(ch)) {
				num = ch - '0';
				state = DYN_TYPE_ID;
			}  else {
				goto error;
			}

			break;

		case DYN_TYPE_ID:
			log_debug(LOG_DEBUG, "DYN_TYPE_ID");
			log_debug(LOG_DEBUG, "num = %d", num);
			if (isdigit(ch))  {
				num = num*10 + (ch - '0');
			} else {
				if (num > 0)  {
					log_debug(LOG_DEBUG, "Type Id: %d", num);
					dmsg->type = num;
					//state = DYN_SPACES_BEFORE_VERSION;
					state = DYN_SPACES_BEFORE_BIT_FIELD;
				} else {
					goto error;
				}
			}

			break;

		case DYN_SPACES_BEFORE_BIT_FIELD:
			if (ch == ' ') {
				break;
			} else if (isdigit(ch)) {
				num = ch - '0';
				state = DYN_BIT_FIELD;
			} else {
				goto error;
			}
			break;

		case DYN_BIT_FIELD:
			log_debug(LOG_DEBUG, "DYN_BIT_FIELD");
			log_debug(LOG_DEBUG, "num = %d", num);
			if (isdigit(ch))  {
				num = num*10 + (ch - '0');
			} else {
				if (ch == ' ')  {
					log_debug(LOG_DEBUG, "DYN_BIT_FIELD : %d", num);
					dmsg->bit_field = num & 0xF;
					state = DYN_SPACES_BEFORE_VERSION;
				} else {
					goto error;
				}
			}

			log_debug(LOG_DEBUG, "Post DYN_BIT_FIELD");
			log_debug(LOG_DEBUG, "num = %d", num);

			break;

		case DYN_SPACES_BEFORE_VERSION:
			log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_VERSION");
			if (ch == ' ') {
				break;
			} else if (isdigit(ch)) {
				num = ch - '0';
				state = DYN_VERSION;
			}  else {
				goto error;
			}

			break;

		case DYN_VERSION:
			log_debug(LOG_DEBUG, "DYN_VERSION");
			log_debug(LOG_DEBUG, "num = %d", num);
			if (isdigit(ch))  {
				num = num*10 + (ch - '0');
			} else {
				if (ch == ' ')  {
					//log_debug(LOG_DEBUG, "VERSION : %d", num);
					dmsg->version = num;
					state = DYN_SPACES_BEFORE_STAR;
				} else {
					goto error;
				}
			}

			break;

		case DYN_SPACES_BEFORE_STAR:
			//log_debug(LOG_DEBUG, "DYN_CRLF_BEFORE_STAR");
			if (ch == ' ')  {
				break;
			} else if (ch == '*') {
				state = DYN_DATA_LEN;
				num = 0;
			} else {
				goto error;
			}

			//else {
			//	state = DYN_STAR;
			//}

			break;

		//case DYN_STAR:
			//log_debug(LOG_DEBUG, "DYN_STAR");
		//	if (ch == '*') {
		//		state = DYN_DATA_LEN;
		//		num = 0;
		//	} else {
		//		goto error;
		//	}

		//	break;

		case DYN_DATA_LEN:
			log_debug(LOG_DEBUG, "DYN_DATA_LEN");
			log_debug(LOG_DEBUG, "num = %d", num);
			if (isdigit(ch))  {
				num = num*10 + (ch - '0');
			} else {
				if (ch == ' ')  {
					log_debug(LOG_DEBUG, "Data len: %d", num);
					dmsg->mlen = num;
					state = DYN_SPACE_BEFORE_DATA;
					num = 0;
				} else {
					goto error;
				}
			}
			break;

		case DYN_SPACE_BEFORE_DATA:
			log_debug(LOG_DEBUG, "DYN_SPACE_BEFORE_DATA");
			state = DYN_DATA;
			break;

		case DYN_DATA:
			log_debug(LOG_DEBUG, "DYN_DATA");
			p -= 1;
			if (dmsg->mlen > 0)  {
				dmsg->data = p;
				p += dmsg->mlen - 1;
				state = DYN_SPACES_BEFORE_PAYLOAD_LEN;
			} else {
				goto error;
			}

			break;

		case DYN_SPACES_BEFORE_PAYLOAD_LEN: //this only need in dynomite's custome msg
			log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_PAYLOAD_LEN");
			if (ch == ' ') {
				break;
			} else if (ch == '*') {
				state = DYN_PAYLOAD_LEN;
				num = 0;
			} else {
				goto error;
			}

			break;

		case DYN_PAYLOAD_LEN:
			if (isdigit(ch))  {
				num = num*10 + (ch - '0');
			} else {
				if (ch == CR)  {
					log_debug(LOG_DEBUG, "Payload len: %d", num);
					dmsg->plen = num;
					state = DYN_CRLF_BEFORE_DONE;
					num = 0;
				} else {
					goto error;
				}
			}
			break;

		case DYN_CRLF_BEFORE_DONE:
			//log_debug(LOG_DEBUG, "DYN_CRLF_BEFORE_DONE");
			if (*p == LF) {
				state = DYN_DONE;
			} else {
				goto error;
			}

			break;

		case DYN_DONE:
			//log_debug(LOG_DEBUG, "DYN_DONE");
			r->pos = p;
			dmsg->payload = p;
			r->dyn_state = DYN_DONE;
			b->pos = p;
			goto done;
			break;

		default:
			NOT_REACHED();
			break;

		}

	}

	done:

	dmsg->owner = r;
	dmsg->source_address = r->owner->addr;
    //r->mlen = mbuf_length(b);
	//log_debug(LOG_DEBUG, "at done with p at %d", p);
	dmsg_dump(r->dmsg);
	log_hexdump(LOG_VERB, b->pos, mbuf_length(b), "dyn: parsed req %"PRIu64" res %d "
			"type %d state %d rpos %d of %d", r->id, r->result, r->type,
			r->dyn_state, r->pos - b->pos, b->last - b->pos);


	return true;

	skip:
	//log_debug(LOG_DEBUG, "This is not a dyn message");
	dmsg->type = DMSG_UNKNOWN;
	dmsg->owner = r;
	dmsg->source_address = r->owner->addr;
	return true;

	error:
	log_debug(LOG_ERR, "at error");
	r->result = MSG_PARSE_ERROR;
	r->state = state;
	errno = EINVAL;

	log_hexdump(LOG_INFO, b->pos, mbuf_length(b), "parsed bad req %"PRIu64" "
			"res %d type %d state %d", r->id, r->result, r->type,
			r->state);
	return false;

	return true;    //fix me
}