/* * @return 1 if forwarded, 0 if discarded */ int ForwardPktOnLink (tw_lp * lp, Link * lnk, Packet * p) { double t, now = tw_now (lp); if (lnk->lastPktOutTime_ <= now) { /* No packet is being sent out. Therefore forward it right now */ t = p->size_ * 8 / ((double) lnk->bw_); /* Transmission delay */ lnk->lastPktOutTime_ = now + t; p->inPort_ = lnk->nbPort_; /* This will copied to the outgoing packet */ return ForwardPacket (lp, tw_getlp (lnk->neighbour_), p, t + lnk->latency_); } if (p->size_ + (lnk->lastPktOutTime_ - now) / 8 * lnk->bw_ > lnk->bufSize_ + SMALL_FLOAT) { /* Buffer is full. Discard the packet * The buffered packets include the one being sent except the portion * that has been sent. */ #ifdef DEBUG_PKT_DISCARD printf ("%lf : pkt(%d:%lu) at %d discarded\n", tw_now (lp), _addrToIdx[p->srcAddr_], p->od_.sqn_, lp->id); fflush (stdout); #endif return 0; } /* The buffer is not zero, some packet is being sent. * Schedule to forward this packet at a future time */ p->inPort_ = lnk->nbPort_; /* This will copied to the outgoing packet */ lnk->lastPktOutTime_ += p->size_ * 8 / ((double) lnk->bw_); return ForwardPacket (lp, tw_getlp (lnk->neighbour_), p, lnk->lastPktOutTime_ + lnk->latency_ - now); }
void CClientManager::SetEventFlag(TPacketSetEventFlag* p) { ForwardPacket(HEADER_DG_SET_EVENT_FLAG, p, sizeof(TPacketSetEventFlag)); bool bChanged = false; typeof(m_map_lEventFlag.begin()) it = m_map_lEventFlag.find(p->szFlagName); if (it == m_map_lEventFlag.end()) { bChanged = true; m_map_lEventFlag.insert(std::make_pair(std::string(p->szFlagName), p->lValue)); } else if (it->second != p->lValue) { bChanged = true; it->second = p->lValue; } if (bChanged) { char szQuery[1024]; snprintf(szQuery, sizeof(szQuery), "REPLACE INTO quest%s (dwPID, szName, szState, lValue) VALUES(0, '%s', '', %ld)", GetTablePostfix(), p->szFlagName, p->lValue); szQuery[1023] = '\0'; //CDBManager::instance().ReturnQuery(szQuery, QID_QUEST_SAVE, 0, NULL); CDBManager::instance().AsyncQuery(szQuery); sys_log(0, "HEADER_GD_SET_EVENT_FLAG : Changed CClientmanager::SetEventFlag(%s %d) ", p->szFlagName, p->lValue); return; } sys_log(0, "HEADER_GD_SET_EVENT_FLAG : No Changed CClientmanager::SetEventFlag(%s %d) ", p->szFlagName, p->lValue); }
void CClientManager::GuildCreate(CPeer * peer, DWORD dwGuildID) { sys_log(0, "GuildCreate %u", dwGuildID); ForwardPacket(HEADER_DG_GUILD_LOAD, &dwGuildID, sizeof(DWORD)); CGuildManager::instance().Load(dwGuildID); }
void CClientManager::UpdateHorseName(TPacketUpdateHorseName* data, CPeer* peer) { char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "REPLACE INTO horse_name VALUES(%u, '%s')", data->dwPlayerID, data->szHorseName); std::auto_ptr<SQLMsg> pmsg_insert(CDBManager::instance().DirectQuery(szQuery)); ForwardPacket(HEADER_DG_UPDATE_HORSE_NAME, data, sizeof(TPacketUpdateHorseName), 0, peer); }
void CClientManager::GuildChangeMaster(TPacketChangeGuildMaster* p) { if (CGuildManager::instance().ChangeMaster(p->dwGuildID, p->idFrom, p->idTo) == true) { TPacketChangeGuildMaster packet; packet.dwGuildID = p->dwGuildID; packet.idFrom = 0; packet.idTo = 0; ForwardPacket(HEADER_DG_ACK_CHANGE_GUILD_MASTER, &packet, sizeof(packet)); } }
void CClientManager::SendGuildSkillUsable(DWORD guild_id, DWORD dwSkillVnum, bool bUsable) { sys_log(0, "SendGuildSkillUsable Send %u %d %s", guild_id, dwSkillVnum, bUsable?"true":"false"); TPacketGuildSkillUsableChange p; p.dwGuild = guild_id; p.dwSkillVnum = dwSkillVnum; p.bUsable = bUsable; ForwardPacket(HEADER_DG_GUILD_SKILL_USABLE_CHANGE, &p, sizeof(TPacketGuildSkillUsableChange)); }
void CClientManager::GuildRemoveMember(CPeer* peer, TPacketGuild* p) { sys_log(0, "GuildRemoveMember %u %u", p->dwGuild, p->dwInfo); char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_member%s WHERE pid=%u and guild_id=%u", GetTablePostfix(), p->dwInfo, p->dwGuild); CDBManager::instance().AsyncQuery(szQuery); snprintf(szQuery, sizeof(szQuery), "REPLACE INTO quest%s (dwPID, szName, szState, lValue) VALUES(%u, 'guild_manage', 'withdraw_time', %u)", GetTablePostfix(), p->dwInfo, (DWORD) GetCurrentTime()); CDBManager::instance().AsyncQuery(szQuery); ForwardPacket(HEADER_DG_GUILD_REMOVE_MEMBER, p, sizeof(TPacketGuild)); }
void CClientManager::GuildAddMember(CPeer* peer, TPacketGDGuildAddMember * p) { CGuildManager::instance().TouchGuild(p->dwGuild); sys_log(0, "GuildAddMember %u %u", p->dwGuild, p->dwPID); char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "INSERT INTO guild_member%s VALUES(%u, %u, %d, 0, 0)", GetTablePostfix(), p->dwPID, p->dwGuild, p->bGrade); std::auto_ptr<SQLMsg> pmsg_insert(CDBManager::instance().DirectQuery(szQuery)); snprintf(szQuery, sizeof(szQuery), "SELECT pid, grade, is_general, offer, level, job, name FROM guild_member%s, player%s WHERE guild_id = %u and pid = id and pid = %u", GetTablePostfix(), GetTablePostfix(), p->dwGuild, p->dwPID); std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery)); if (pmsg->Get()->uiNumRows == 0) { sys_err("Query failed when getting guild member data %s", pmsg->stQuery.c_str()); return; } MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult); if (!row[0] || !row[1]) return; TPacketDGGuildMember dg; dg.dwGuild = p->dwGuild; str_to_number(dg.dwPID, row[0]); str_to_number(dg.bGrade, row[1]); str_to_number(dg.isGeneral, row[2]); str_to_number(dg.dwOffer, row[3]); str_to_number(dg.bLevel, row[4]); str_to_number(dg.bJob, row[5]); strlcpymt(dg.szName, row[6], sizeof(dg.szName)); ForwardPacket(HEADER_DG_GUILD_ADD_MEMBER, &dg, sizeof(TPacketDGGuildMember)); }
void CServerKillCamForwarder::DropOldestPacket() { if (m_history.Empty()) { CryFatalError("We're trying to drop a packet to make space for new data but there's nothing left in the buffer\n"); } BufferType::iterator itPacket=m_history.Begin(); IActor *pActor=*(IActor**)m_history.GetData(sizeof(IActor*)); CActor::KillCamFPData *pPacket=(CActor::KillCamFPData*)m_history.GetData(sizeof(CActor::KillCamFPData)); // If packet in queue to be forwarded, send immediately before dropping for (std::deque<SForwardingPacket>::iterator it=m_forwarding.begin(), end=m_forwarding.end(); it!=end; ++it) { SForwardingPacket &forward=*it; if (forward.iterator<=itPacket && forward.pActor==pActor && forward.packetID==pPacket->m_packetId) { CryLog("Server forwarder queue is overflowing! Forcing packet send to free space\n"); ForwardPacket(forward, pPacket); } } }
void CClientManager::LoadEventFlag() { char szQuery[1024]; snprintf(szQuery, sizeof(szQuery), "SELECT szName, lValue FROM quest%s WHERE dwPID = 0", GetTablePostfix()); std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery)); SQLResult* pRes = pmsg->Get(); if (pRes->uiNumRows) { MYSQL_ROW row; while ((row = mysql_fetch_row(pRes->pSQLResult))) { TPacketSetEventFlag p; strlcpymt(p.szFlagName, row[0], sizeof(p.szFlagName)); str_to_number(p.lValue, row[1]); sys_log(0, "EventFlag Load %s %d", p.szFlagName, p.lValue); m_map_lEventFlag.insert(std::make_pair(std::string(p.szFlagName), p.lValue)); ForwardPacket(HEADER_DG_SET_EVENT_FLAG, &p, sizeof(TPacketSetEventFlag)); } } }
void CServerKillCamForwarder::Update() { CTimeValue now=gEnv->pTimer->GetCurrTime(); const float k_timeout=2.0f; if (!m_forwarding.empty()) { int maxCycles=m_forwarding.size(); bool bSent=false; do { SForwardingPacket &forward=m_forwarding.front(); CActor::KillCamFPData* packet=FindPacket(forward.iterator, forward.pActor, forward.packetID); if (packet) { ForwardPacket(forward, packet); bSent=true; if (forward.m_sent>=forward.m_numPackets) m_forwarding.pop_front(); } else { if (forward.m_sent!=forward.m_numPackets) { CryLog("Underflowed forwarding packetID %d from actor %s after sending %d packets\n", forward.packetID, forward.pActor->GetEntity()->GetName(), forward.m_sent); if (forward.m_lastPacketTime.GetDifferenceInSeconds(now)>=k_timeout) { CryLog("Underflowing packet timed out, did the client disconnect? Giving up :(\n"); } else { // Re-add to the end of the list for trying later (forward packet can arrive before all source packets have arrived) m_forwarding.push_back(forward); } } m_forwarding.pop_front(); maxCycles--; } } while (!bSent && maxCycles>0); } }
void CClientManager::GuildDisband(CPeer* peer, TPacketGuild* p) { sys_log(0, "GuildDisband %u", p->dwGuild); char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild%s WHERE id=%u", GetTablePostfix(), p->dwGuild); CDBManager::instance().AsyncQuery(szQuery); snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_grade%s WHERE guild_id=%u", GetTablePostfix(), p->dwGuild); CDBManager::instance().AsyncQuery(szQuery); snprintf(szQuery, sizeof(szQuery), "REPLACE INTO quest%s (dwPID, szName, szState, lValue) SELECT pid, 'guild_manage', 'withdraw_time', %u FROM guild_member%s WHERE guild_id = %u", GetTablePostfix(), (DWORD) GetCurrentTime(), GetTablePostfix(), p->dwGuild); CDBManager::instance().AsyncQuery(szQuery); snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_member%s WHERE guild_id=%u", GetTablePostfix(), p->dwGuild); CDBManager::instance().AsyncQuery(szQuery); snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_comment%s WHERE guild_id=%u", GetTablePostfix(), p->dwGuild); CDBManager::instance().AsyncQuery(szQuery); ForwardPacket(HEADER_DG_GUILD_DISBAND, p, sizeof(TPacketGuild)); }
void CClientManager::GuildChangeMemberData(CPeer* peer, TPacketGuildChangeMemberData* p) { sys_log(0, "GuildChangeMemberData %u %u %d %d", p->pid, p->offer, p->level, p->grade); ForwardPacket(HEADER_DG_GUILD_CHANGE_MEMBER_DATA, p, sizeof(TPacketGuildChangeMemberData), 0, peer); }
/* ------------------------------------------------------------------------- * Function : BmfTunPacketCaptured * Description: Handle an IP packet, captured outgoing on the tuntap interface * Input : encapsulationUdpData - space for the encapsulation header, followed by * the captured outgoing IP packet * Output : none * Return : none * Data Used : none * Notes : The packet is assumed to be captured on a socket of family * PF_PACKET and type SOCK_DGRAM (cooked). * ------------------------------------------------------------------------- */ static void BmfTunPacketCaptured(unsigned char* encapsulationUdpData) { union olsr_ip_addr srcIp; union olsr_ip_addr dstIp; union olsr_ip_addr broadAddr; struct TBmfInterface* walker; unsigned char* ipPacket; u_int16_t ipPacketLen; struct ip* ipHeader; u_int32_t crc32; struct TEncapHeader* encapHdr; #ifndef NODEBUG struct ipaddr_str srcIpBuf, dstIpBuf; #endif ipPacket = GetIpPacket(encapsulationUdpData); ipPacketLen = GetIpTotalLength(ipPacket); ipHeader = GetIpHeader(encapsulationUdpData); dstIp.v4 = ipHeader->ip_dst; broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast); /* Only forward multicast packets. If configured, also forward local broadcast packets */ if (IsMulticast(&dstIp) || (EnableLocalBroadcast != 0 && ipequal(&dstIp, &broadAddr))) { /* continue */ } else { return; } srcIp.v4 = ipHeader->ip_src; OLSR_PRINTF( 8, "%s: outgoing pkt of %ld bytes captured on tuntap interface \"%s\": %s->%s\n", PLUGIN_NAME_SHORT, (long)ipPacketLen, EtherTunTapIfName, olsr_ip_to_string(&srcIpBuf, &srcIp), olsr_ip_to_string(&dstIpBuf, &dstIp)); /* Calculate packet fingerprint */ crc32 = PacketCrc32(ipPacket, ipPacketLen); /* Check if this packet was seen recently */ if (CheckAndMarkRecentPacket(crc32)) { OLSR_PRINTF( 8, "%s: --> discarding: packet is duplicate\n", PLUGIN_NAME_SHORT); return; } /* Compose encapsulation header */ encapHdr = (struct TEncapHeader*) encapsulationUdpData; memset (encapHdr, 0, ENCAP_HDR_LEN); encapHdr->type = BMF_ENCAP_TYPE; encapHdr->len = BMF_ENCAP_LEN; encapHdr->reserved = 0; encapHdr->crc32 = htonl(crc32); /* Check with each network interface what needs to be done on it */ for (walker = BmfInterfaces; walker != NULL; walker = walker->next) { /* Is the forwarding interface OLSR-enabled? */ if (walker->olsrIntf != NULL) { /* On an OLSR interface: encapsulate and forward packet. */ EncapsulateAndForwardPacket(walker, encapsulationUdpData, NULL, NULL, NULL); } else { /* On a non-OLSR interface: what to do? * Answer 1: nothing. Multicast routing between non-OLSR interfaces * is to be done by other protocols (e.g. PIM, DVMRP). * Answer 2 (better): Forward it. */ ForwardPacket (walker, ipPacket, ipPacketLen, "forwarded from non-OLSR to non-OLSR interface"); } /* if */ } /* for */ } /* BmfTunPacketCaptured */
/* ------------------------------------------------------------------------- * Function : BmfEncapsulationPacketReceived * Description: Handle a received BMF-encapsulation packet * Input : intf - the network interface on which the packet was received * forwardedBy - the IP node that forwarded the packet to me * forwardedTo - the destination IP address of the encapsulation * packet, in case the packet was received promiscuously. * Pass NULL if the packet is received normally (unicast or * broadcast). * encapsulationUdpData - the encapsulating IP UDP data, containting * the BMF encapsulation header, followed by the encapsulated * IP packet * Output : none * Return : none * Data Used : BmfInterfaces * ------------------------------------------------------------------------- */ static void BmfEncapsulationPacketReceived( struct TBmfInterface* intf, union olsr_ip_addr* forwardedBy, union olsr_ip_addr* forwardedTo, unsigned char* encapsulationUdpData) { int iAmMpr; /* True (1) if I am selected as MPR by 'forwardedBy' */ unsigned char* ipPacket; /* The encapsulated IP packet */ u_int16_t ipPacketLen; /* Length of the encapsulated IP packet */ struct ip* ipHeader; /* IP header inside the encapsulated IP packet */ union olsr_ip_addr mcSrc; /* Original source of the encapsulated multicast packet */ union olsr_ip_addr mcDst; /* Multicast destination of the encapsulated packet */ struct TEncapHeader* encapsulationHdr; struct TBmfInterface* walker; #ifndef NODEBUG struct ipaddr_str mcSrcBuf, mcDstBuf, forwardedByBuf, forwardedToBuf; #endif /* Are we talking to ourselves? */ if (if_ifwithaddr(forwardedBy) != NULL) { return; } /* Discard encapsulated packets received on a non-OLSR interface */ if (intf->olsrIntf == NULL) { return; } /* Retrieve details about the encapsulated IP packet */ ipPacket = GetIpPacket(encapsulationUdpData); ipPacketLen = GetIpTotalLength(ipPacket); ipHeader = GetIpHeader(encapsulationUdpData); mcSrc.v4 = ipHeader->ip_src; mcDst.v4 = ipHeader->ip_dst; /* Increase counter */ intf->nBmfPacketsRx++; /* Beware: not possible to call olsr_ip_to_string more than 4 times in same printf */ OLSR_PRINTF( 8, "%s: encapsulated pkt of %ld bytes incoming on \"%s\": %s->%s, forwarded by %s to %s\n", PLUGIN_NAME_SHORT, (long)ipPacketLen, intf->ifName, olsr_ip_to_string(&mcSrcBuf, &mcSrc), olsr_ip_to_string(&mcDstBuf, &mcDst), olsr_ip_to_string(&forwardedByBuf, forwardedBy), forwardedTo != NULL ? olsr_ip_to_string(&forwardedToBuf, forwardedTo) : "me"); /* Get encapsulation header */ encapsulationHdr = (struct TEncapHeader*) encapsulationUdpData; /* Verify correct format of BMF encapsulation header */ if (encapsulationHdr->type != BMF_ENCAP_TYPE || encapsulationHdr->len != BMF_ENCAP_LEN || ntohs(encapsulationHdr->reserved != 0)) { OLSR_PRINTF( 8, "%s: --> discarding: format of BMF encapsulation header not recognized\n", PLUGIN_NAME_SHORT); return; } /* Check if this packet was seen recently */ if (CheckAndMarkRecentPacket(ntohl(encapsulationHdr->crc32))) { /* Increase counter */ intf->nBmfPacketsRxDup++; OLSR_PRINTF( 8, "%s: --> discarding: packet is duplicate\n", PLUGIN_NAME_SHORT); return; } if (EtherTunTapFd >= 0) { /* Unpack the encapsulated IP packet and deliver it locally, by sending * a copy into the local IP stack via the EtherTunTap interface */ union olsr_ip_addr broadAddr; int nBytesToWrite, nBytesWritten; unsigned char* bufferToWrite; /* If the encapsulated IP packet is a local broadcast packet, * update its destination address to match the subnet of the EtherTunTap * interface */ broadAddr.v4.s_addr = htonl(EtherTunTapIpBroadcast); CheckAndUpdateLocalBroadcast(ipPacket, &broadAddr); bufferToWrite = ipPacket; nBytesToWrite = ipPacketLen; /* Write the packet into the EtherTunTap interface for local delivery */ nBytesWritten = write(EtherTunTapFd, bufferToWrite, nBytesToWrite); if (nBytesWritten != nBytesToWrite) { BmfPError("write() error forwarding encapsulated pkt on \"%s\"", EtherTunTapIfName); } else { OLSR_PRINTF( 8, "%s: --> unpacked and delivered locally on \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName); } } /* if (EtherTunTapFd >= 0) */ /* Check if I am MPR for the forwarder */ iAmMpr = (olsr_lookup_mprs_set(MainAddressOf(forwardedBy)) != NULL); /* Check with each network interface what needs to be done on it */ for (walker = BmfInterfaces; walker != NULL; walker = walker->next) { /* What to do with the packet on a non-OLSR interface? Unpack * encapsulated packet, and forward it. * * What to do with the packet on an OLSR interface? Forward it only * if the forwarding node has selected us as MPR (iAmMpr). * * Note that the packet is always coming in on an OLSR interface, because * it is an encapsulated BMF packet. */ /* To a non-OLSR interface: unpack the encapsulated IP packet and forward it */ if (walker->olsrIntf == NULL) { ForwardPacket (walker, ipPacket, ipPacketLen, "unpacked and forwarded to non-OLSR interface"); } /* if (walker->olsrIntf == NULL) */ /* To an OLSR interface: forward the packet, but only if this node is * selected as MPR by the forwarding node */ else if (iAmMpr) { EncapsulateAndForwardPacket ( walker, encapsulationUdpData, &mcSrc, forwardedBy, forwardedTo); } /* else if (iAmMpr) */ else /* walker->olsrIntf != NULL && !iAmMpr */ { #ifndef NODEBUG struct ipaddr_str buf; #endif /* 'walker' is an OLSR interface, but I am not selected as MPR. In that * case, don't forward. */ OLSR_PRINTF( 8, "%s: --> not forwarding on \"%s\": I am not selected as MPR by %s\n", PLUGIN_NAME_SHORT, walker->ifName, olsr_ip_to_string(&buf, forwardedBy)); } /* else */ } /* for */ } /* BmfEncapsulationPacketReceived */
/* ------------------------------------------------------------------------- * Function : BmfPacketCaptured * Description: Handle a captured IP packet * Input : intf - the network interface on which the packet was captured * sllPkttype - the type of packet. Either PACKET_OUTGOING, * PACKET_BROADCAST or PACKET_MULTICAST. * encapsulationUdpData - space for the encapsulation header, followed by * the captured IP packet * Output : none * Return : none * Data Used : BmfInterfaces * Notes : The IP packet is assumed to be captured on a socket of family * PF_PACKET and type SOCK_DGRAM (cooked). * ------------------------------------------------------------------------- */ static void BmfPacketCaptured( struct TBmfInterface* intf, unsigned char sllPkttype, unsigned char* encapsulationUdpData) { union olsr_ip_addr src; /* Source IP address in captured packet */ union olsr_ip_addr dst; /* Destination IP address in captured packet */ union olsr_ip_addr* origIp; /* Main OLSR address of source of captured packet */ struct TBmfInterface* walker; int isFromOlsrIntf; int isFromOlsrNeighbor; int iAmMpr; unsigned char* ipPacket; /* The captured IP packet... */ u_int16_t ipPacketLen; /* ...and its length */ struct ip* ipHeader; /* The IP header inside the captured IP packet */ u_int32_t crc32; struct TEncapHeader* encapHdr; #ifndef NODEBUG struct ipaddr_str srcBuf, dstBuf; #endif ipHeader = GetIpHeader(encapsulationUdpData); dst.v4 = ipHeader->ip_dst; /* Only forward multicast packets. If configured, also forward local broadcast packets */ if (IsMulticast(&dst) || (EnableLocalBroadcast != 0 && ipequal(&dst, &intf->broadAddr))) { /* continue */ } else { return; } ipPacket = GetIpPacket(encapsulationUdpData); /* Don't forward fragments of IP packets: there is no way to distinguish fragments * of BMF encapsulation packets from other fragments. * Well yes, there is the IP-ID, which can be kept in a list to relate a fragment * to earlier sent BMF packets, but... sometimes the second fragment comes in earlier * than the first fragment, so that the list is not yet up to date and the second * fragment is not recognized as a BMF packet. * Also, don't forward OLSR packets (UDP port 698) and BMF encapsulated packets */ if (IsIpFragment(ipPacket) || IsOlsrOrBmfPacket(ipPacket)) { return; } /* Increase counter */ intf->nBmfPacketsRx++; /* Check if the frame is captured on an OLSR-enabled interface */ isFromOlsrIntf = (intf->olsrIntf != NULL); /* Retrieve the length of the captured packet */ ipPacketLen = GetIpTotalLength(ipPacket); src.v4 = ipHeader->ip_src; OLSR_PRINTF( 8, "%s: %s pkt of %ld bytes captured on %s interface \"%s\": %s->%s\n", PLUGIN_NAME_SHORT, sllPkttype == PACKET_OUTGOING ? "outgoing" : "incoming", (long)ipPacketLen, isFromOlsrIntf ? "OLSR" : "non-OLSR", intf->ifName, olsr_ip_to_string(&srcBuf, &src), olsr_ip_to_string(&dstBuf, &dst)); /* Lookup main address of source in the MID table of OLSR */ origIp = MainAddressOf(&src); /* Calculate packet fingerprint */ crc32 = PacketCrc32(ipPacket, ipPacketLen); /* Check if this packet was seen recently */ if (CheckAndMarkRecentPacket(crc32)) { /* Increase counter */ intf->nBmfPacketsRxDup++; OLSR_PRINTF( 8, "%s: --> discarding: packet is duplicate\n", PLUGIN_NAME_SHORT); return; } /* Compose encapsulation header */ encapHdr = (struct TEncapHeader*) encapsulationUdpData; memset (encapHdr, 0, ENCAP_HDR_LEN); encapHdr->type = BMF_ENCAP_TYPE; encapHdr->len = BMF_ENCAP_LEN; encapHdr->reserved = 0; encapHdr->crc32 = htonl(crc32); /* Check if the frame is captured on an OLSR interface from an OLSR neighbor. * TODO: get_best_link_to_neighbor() may be very CPU-expensive, a simpler call * would do here (something like 'get_any_link_to_neighbor()'). */ isFromOlsrNeighbor = (isFromOlsrIntf /* The frame is captured on an OLSR interface... */ && get_best_link_to_neighbor(origIp) != NULL); /* ...from an OLSR neighbor */ /* Check with OLSR if I am MPR for that neighbor */ iAmMpr = olsr_lookup_mprs_set(origIp) != NULL; /* Check with each network interface what needs to be done on it */ for (walker = BmfInterfaces; walker != NULL; walker = walker->next) { /* Is the forwarding interface OLSR-enabled? */ int isToOlsrIntf = (walker->olsrIntf != NULL); /* Depending on certain conditions, we decide whether or not to forward * the packet, and if it is forwarded, in which form (encapsulated * or not, TTL decreased or not). These conditions are: * - is the packet is coming in on an OLSR interface or not? (isFromOlsrIntf) * - is the packet going out on an OLSR interface or not? (isToOlsrIntf) * - if the packet if coming in on an OLSR interface: * - is the node that forwarded the packet my OLSR-neighbor? (isFromOlsrNeighbor) * - has the node that forwarded the packet selected me as MPR? (iAmMpr) * * Based on these conditions, the following cases can be distinguished: * * - Case 1: Packet coming in on an OLSR interface. What to * do with it on an OLSR interface? * Answer: * - Case 1.1: If the forwarding node is an OLSR neighbor that has *not* * selected me as MPR: don't forward the packet. * - Case 1.2: If the forwarding node is an OLSR neighbor that has selected * me as MPR: encapsulate and forward the packet. * - Case 1.3: If the forwarding node is not an OLSR neighbor: encapsulate * and forward the packet. * NOTE: Case 1.3 is a special case. In the perfect world, we expect to * see only OLSR-neighbors on OLSR-enabled interfaces. Sometimes, however, * ignorant users will connect a host not running OLSR, to a LAN in * which there are hosts running OLSR. Of course these ignorant users, * expecting magic, want to see their multicast packets being forwarded * through the network. * * - Case 2: Packet coming in on an OLSR interface. What to do with it on a * non-OLSR interface? * Answer: Forward it. * * - Case 3: Packet coming in on a non-OLSR interface. What to * do with it on an OLSR interface? * Answer: Encapsulate and forward it. * * - Case 4: Packet coming in on non-OLSR interface. What to do with it on a * non-OLSR interface? * Answer 1: nothing. Multicast routing between non-OLSR interfaces * is to be done by other protocols (e.g. PIM, DVMRP). * Answer 2 (better): Forward it. */ if (isFromOlsrIntf && isToOlsrIntf) { /* Case 1: Forward from an OLSR interface to an OLSR interface */ if (isFromOlsrNeighbor && !iAmMpr) { /* Case 1.1 */ { #ifndef NODEBUG struct ipaddr_str buf; #endif OLSR_PRINTF( 8, "%s: --> not encap-forwarding on \"%s\": I am not selected as MPR by neighbor %s\n", PLUGIN_NAME_SHORT, walker->ifName, olsr_ip_to_string(&buf, &src)); } } else if (sllPkttype == PACKET_OUTGOING && intf == walker) { OLSR_PRINTF( 8, "%s: --> not encap-forwarding on \"%s\": pkt was captured on that interface\n", PLUGIN_NAME_SHORT, walker->ifName); } else { /* Case 1.2 and 1.3 */ EncapsulateAndForwardPacket(walker, encapsulationUdpData, NULL, NULL, NULL); } } /* if (isFromOlsrIntf && isToOlsrIntf) */ else if (isFromOlsrIntf && !isToOlsrIntf) { /* Case 2: Forward from OLSR interface to non-OLSR interface */ ForwardPacket (walker, ipPacket, ipPacketLen, "forwarded to non-OLSR interface"); } /* else if (isFromOlsrIntf && !isToOlsrIntf) */ else if (!isFromOlsrIntf && isToOlsrIntf) { /* Case 3: Forward from a non-OLSR interface to an OLSR interface. * Encapsulate and forward packet. */ EncapsulateAndForwardPacket(walker, encapsulationUdpData, NULL, NULL, NULL); } /* else if (!isFromOlsrIntf && isToOlsrIntf) */ else { /* Case 4: Forward from non-OLSR interface to non-OLSR interface. */ /* Don't forward on interface on which packet was received */ if (intf == walker) { OLSR_PRINTF( 8, "%s: --> not forwarding on \"%s\": pkt was captured on that interface\n", PLUGIN_NAME_SHORT, walker->ifName); } else { ForwardPacket (walker, ipPacket, ipPacketLen, "forwarded from non-OLSR to non-OLSR interface"); } /* if (intf == walker) */ } /* if */ } /* for */ } /* BmfPacketCaptured */
void CClientManager::GuildWar(CPeer* peer, TPacketGuildWar* p) { switch (p->bWar) { case GUILD_WAR_SEND_DECLARE: sys_log(0, "GuildWar: GUILD_WAR_SEND_DECLARE type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo); CGuildManager::instance().AddDeclare(p->bType, p->dwGuildFrom, p->dwGuildTo); break; case GUILD_WAR_REFUSE: sys_log(0, "GuildWar: GUILD_WAR_REFUSE type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo); CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo); break; /* case GUILD_WAR_WAIT_START: CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo); if (!CGuildManager::instance().WaitStart(p)) p->bWar = GUILD_WAR_CANCEL; break; */ case GUILD_WAR_WAIT_START: sys_log(0, "GuildWar: GUILD_WAR_WAIT_START type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo); case GUILD_WAR_RESERVE: // 길드전 예약 if (p->bWar != GUILD_WAR_WAIT_START) sys_log(0, "GuildWar: GUILD_WAR_RESERVE type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo); CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo); if (!CGuildManager::instance().ReserveWar(p)) p->bWar = GUILD_WAR_CANCEL; else p->bWar = GUILD_WAR_RESERVE; break; case GUILD_WAR_ON_WAR: // 길드전을 시작 시킨다. (필드전은 바로 시작 됨) sys_log(0, "GuildWar: GUILD_WAR_ON_WAR type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo); CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo); CGuildManager::instance().StartWar(p->bType, p->dwGuildFrom, p->dwGuildTo); break; case GUILD_WAR_OVER: // 길드전 정상 종료 sys_log(0, "GuildWar: GUILD_WAR_OVER type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo); CGuildManager::instance().RecvWarOver(p->dwGuildFrom, p->dwGuildTo, p->bType, p->lWarPrice); break; case GUILD_WAR_END: // 길드전 비정상 종료 sys_log(0, "GuildWar: GUILD_WAR_END type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo); CGuildManager::instance().RecvWarEnd(p->dwGuildFrom, p->dwGuildTo); return; // NOTE: RecvWarEnd에서 패킷을 보내므로 따로 브로드캐스팅 하지 않는다. case GUILD_WAR_CANCEL : sys_log(0, "GuildWar: GUILD_WAR_CANCEL type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo); CGuildManager::instance().CancelWar(p->dwGuildFrom, p->dwGuildTo); break; } ForwardPacket(HEADER_DG_GUILD_WAR, p, sizeof(TPacketGuildWar)); }
void CClientManager::GuildChangeGrade(CPeer* peer, TPacketGuild* p) { sys_log(0, "GuildChangeGrade %u %u", p->dwGuild, p->dwInfo); ForwardPacket(HEADER_DG_GUILD_CHANGE_GRADE, p, sizeof(TPacketGuild)); }
void CClientManager::GuildExpUpdate(CPeer* peer, TPacketGuildExpUpdate* p) { sys_log(0, "GuildExpUpdate %d", p->amount); ForwardPacket(HEADER_DG_GUILD_EXP_UPDATE, p, sizeof(TPacketGuildExpUpdate), 0, peer); }
void CClientManager::GuildSkillUpdate(CPeer* peer, TPacketGuildSkillUpdate* p) { sys_log(0, "GuildSkillUpdate %d", p->amount); ForwardPacket(HEADER_DG_GUILD_SKILL_UPDATE, p, sizeof(TPacketGuildSkillUpdate)); }