int ObClientManager::do_send_request( const ObServer& server, const int32_t pcode, const int32_t version, const int64_t timeout, ObDataBuffer& in_buffer, ObPacket* &response) const { int rc = OB_SUCCESS; ObPacket* packet = new (std::nothrow) ObPacket(); if (NULL == packet) { rc = OB_ALLOCATE_MEMORY_FAILED; } else { packet->set_packet_code(pcode); packet->setChannelId(0); packet->set_api_version(version); packet->set_data(in_buffer); packet->set_source_timeout(timeout); } if (OB_SUCCESS == rc) { rc = packet->serialize(); if (OB_SUCCESS != rc) TBSYS_LOG(WARN, "packet serialize error"); } // serialize failed if (OB_SUCCESS != rc && NULL != packet) { packet->free(); } if (OB_SUCCESS == rc) { rc = do_send_packet(server, packet, timeout, response); } return rc; }
/* forward a packet - main routing function, all packets pass through here */ static void forward(imc_packet *p) { imc_info *i; int broadcast, isbroadcast; const char *to; imc_reminfo *route; imc_info *direct; imc_connect *c; char recievedfrom[IMC_MAXBUF]; /* SPAM fix - shogar */ imc_connect *rf; /* SPAM fix - shogar */ /* check for duplication, and register the packet in the sequence memory */ if (p->i.sequence && checkrepeat(imc_mudof(p->i.from), p->i.sequence)) return; /* check for packets we've already forwarded */ if (inpath(p->i.path, imc_name)) return; /* check for really old packets */ route=imc_find_reminfo(imc_mudof(p->i.from), 1); if (route) { if ((p->i.sequence+IMC_PACKET_LIFETIME) < route->top_sequence) { imc_stats.sequence_drops++; #ifdef LOG_LATE_PACKETS /* kind of spammy, but late packets are natural when the path is broken between sender and reciever if(imc_is_router) /* spare the muds from seeing this - shogar */ imc_logstring("sequence drop: %s (seq=%ld, top=%ld)", p->i.path, p->i.sequence, route->top_sequence); #endif return; } if (p->i.sequence > route->top_sequence) route->top_sequence=p->i.sequence; } /* update our routing info */ updateroutes(p->i.path); /* forward to our mud if it's for us */ if (!strcmp(imc_mudof(p->i.to), "*") || !strcasecmp(imc_mudof(p->i.to), imc_name)) { strcpy(p->to, imc_nameof(p->i.to)); /* strip the name from the 'to' */ strcpy(p->from, p->i.from); imc_recv(p); } /* if its only to us (ie. not broadcast) don't forward it */ if (!strcasecmp(imc_mudof(p->to), imc_name)) return; /* check if we should just drop it (policy rules) */ if (!can_forward(p)) return; /* convert a specific destination to a broadcast in some cases */ to=imc_mudof(p->i.to); isbroadcast=!strcmp(to, "*"); /* broadcasts are, well, broadcasts */ broadcast=1; /* unless we know better, flood packets */ i=0; /* make gcc happy */ direct=NULL; /* no direct connection to send on */ /* convert 'to' fields that we have a route for to a hop along the route */ if (!isbroadcast && (route=imc_find_reminfo(to, 0)) != NULL && route->route != NULL && !inpath(p->i.path, route->route)) /* avoid circular routing */ { /* check for a direct connection: if we find it, and the route isn't * to it, then the route is a little suspect.. also send it direct */ if (strcasecmp(to, route->route) && (i=imc_getinfo(to))!=NULL && i->connection) direct=i; to=route->route; } /* check for a direct connection */ if (!isbroadcast && (i=imc_getinfo(to)) != NULL && i->connection && !(i->flags & IMC_BROADCAST)) broadcast=0; if (broadcast) { /* need to forward a packet */ /* SPAM fix - hubcnt and who just gave us the packet- shogar */ int hubcnt,fromhub; hubcnt=0; fromhub=0; strcpy(recievedfrom,imc_lastinpath(p->i.path)); for (rf=imc_connect_list; rf; rf=rf->next) { if(rf->info && rf->info->name && !strcmp(recievedfrom,rf->info->name)) { if(rf->info->flags & IMC_HUB) fromhub=1; } } /* end SPAM fix */ for (c=imc_connect_list; c; c=c->next) if (c->state==IMC_CONNECTED) { /* don't forward to sites that have already received it, * or sites that don't need this packet */ if (inpath(p->i.path, c->info->name) || (p->i.stamp & c->info->noforward)!=0) continue; /* SPAM fix - shogar */ if(c->info->flags & IMC_HUB) { if(!imc_is_router) { if (fromhub) continue; if(hubcnt) { continue; } else { hubcnt=1; } } /* if for imc3 we need to do this - shogar */ /* if (imc_getkeyi(&p->data,"channel",0) == 2) continue; */ } /* end SPAM fix */ do_send_packet(c, p); } } else /* forwarding to a specific connection */ { /* but only if they haven't seen it (sanity check) */ if (i->connection && !inpath(p->i.path, i->name)) do_send_packet(i->connection, p); /* send on direct connection, if we have one */ if (direct && direct!=i && direct->connection && !inpath(p->i.path, direct->name)) do_send_packet(direct->connection, p); } }
int ObClientManager::get_next(const ObServer& server, const int64_t session_id, const int64_t timeout, ObDataBuffer& in_buffer, ObDataBuffer& out_buffer) const { int rc = OB_SUCCESS; ObPacket* response = NULL; //rc = send_request(server, pcode, version, timeout, in_buffer, response); ObPacket* packet = new (std::nothrow) ObPacket(); if (NULL == packet) { rc = OB_ALLOCATE_MEMORY_FAILED; } else { packet->set_packet_code(OB_SESSION_NEXT_REQUEST); packet->setChannelId(0); packet->set_api_version(0); packet->set_data(in_buffer); packet->set_source_timeout(timeout); packet->set_session_id(session_id); //TODO } if (OB_SUCCESS == rc) { rc = packet->serialize(); if (OB_SUCCESS != rc) TBSYS_LOG(WARN, "packet serialize error, code=%d", packet->get_packet_code()); } // serialize failed if (OB_SUCCESS != rc && NULL != packet) { packet->free(); } if (OB_SUCCESS == rc) { rc = do_send_packet(server, packet, timeout, response); } // deserialize response packet to out_buffer if (OB_SUCCESS == rc && NULL != response) { // copy response's inner_buffer to out_buffer. int64_t data_length = response->get_data_length(); ObDataBuffer* response_buffer = response->get_buffer(); if (out_buffer.get_remain() < data_length) { TBSYS_LOG(ERROR, "insufficient memory in out_buffer, remain:%ld, length=%ld", out_buffer.get_remain(), data_length); rc = OB_ERROR; } else { memcpy(out_buffer.get_data() + out_buffer.get_position(), response_buffer->get_data() + response_buffer->get_position(), data_length); out_buffer.get_position() += data_length; } } return rc; }