/* * 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; }
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 }