diff --git a/src/d_net.c b/src/d_net.c index b7486330e..96c95d079 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -179,12 +179,6 @@ typedef struct // ack return to send (like sliding window protocol) UINT8 firstacktosend; - // when no consecutive packets are received we keep in mind what packets - // we already received in a queue - UINT8 acktosend_head; - UINT8 acktosend_tail; - UINT8 acktosend[MAXACKTOSEND]; - // automatically send keep alive packet when not enough trafic tic_t lasttimeacktosend_sent; // detect connection lost @@ -214,10 +208,9 @@ FUNCMATH static inline INT32 cmpack(UINT8 a, UINT8 b) /** Sets freeack to a free acknum and copies the netbuffer in the ackpak table * * \param freeack The address to store the free acknum at - * \param lowtimer ??? * \return True if a free acknum was found */ -static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) +static boolean GetFreeAcknum(UINT8 *freeack) { netnode_t *node = &nodes[doomcom->remotenode]; INT32 i, numfreeslot = 0; @@ -248,17 +241,8 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) node->nextacknum++; ackpak[i].destinationnode = (UINT8)(node - nodes); ackpak[i].length = doomcom->datalength; - if (lowtimer) - { - // Lowtime means can't be sent now so try it as soon as possible - ackpak[i].senttime = 0; - ackpak[i].resentnum = 1; - } - else - { - ackpak[i].senttime = I_GetTime(); - ackpak[i].resentnum = 0; - } + ackpak[i].senttime = I_GetTime(); + ackpak[i].resentnum = 0; memcpy(ackpak[i].pak.raw, netbuffer, ackpak[i].length); *freeack = ackpak[i].acknum; @@ -275,38 +259,6 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) return false; } -/** Counts how many acks are free - * - * \param urgent True if the type of the packet meant to - * use an ack is lower than PT_CANFAIL - * If for some reason you don't want use it - * for any packet type in particular, - * just set to false - * \return The number of free acks - * - */ -INT32 Net_GetFreeAcks(boolean urgent) -{ - INT32 i, numfreeslot = 0; - INT32 n = 0; // Number of free acks found - - for (i = 0; i < MAXACKPACKETS; i++) - if (!ackpak[i].acknum) - { - // For low priority packets, make sure to let freeslots so urgent packets can be sent - if (!urgent) - { - numfreeslot++; - if (numfreeslot <= URGENTFREESLOTNUM) - continue; - } - - n++; - } - - return n; -} - // Get a ack to send in the queue of this node static UINT8 GetAcktosend(INT32 node) { @@ -323,18 +275,11 @@ static void RemoveAck(INT32 i) Net_CloseConnection(node); } -typedef enum -{ - GPACK_OK = 0, - GPACK_DUPLICATE, - GPACK_OUTOFORDER, -} goodpacket_e; - // We have got a packet, proceed the ack request and ack return -static int Processackpak(void) +static boolean Processackpak(void) { INT32 i; - int goodpacket = GPACK_OK; + boolean goodpacket = true; netnode_t *node = &nodes[doomcom->remotenode]; doomdata_t *netbuffer = DOOMCOM_DATA(doomcom); @@ -360,124 +305,32 @@ static int Processackpak(void) { DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); duppacket++; - goodpacket = GPACK_DUPLICATE; // Discard packet (duplicate) + goodpacket = false; // Discard packet (duplicate) } else { - // Check if it is not already in the queue - for (i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND) - if (node->acktosend[i] == ack) - { - DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); - duppacket++; - goodpacket = GPACK_DUPLICATE; // Discard packet (duplicate) - break; - } - if (goodpacket == GPACK_OK) + // Is a good packet so increment the acknowledge number, + // Then search for a "hole" in the queue + UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); + if (!nextfirstack) + nextfirstack = 1; + + if (ack == nextfirstack) { - // Is a good packet so increment the acknowledge number, - // Then search for a "hole" in the queue - UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); - if (!nextfirstack) - nextfirstack = 1; - - if (ack == nextfirstack) - { - UINT8 hm1; // head - 1 - boolean change = true; - - node->firstacktosend = nextfirstack++; - if (!nextfirstack) - nextfirstack = 1; - hm1 = (UINT8)((node->acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND); - while (change) - { - change = false; - for (i = node->acktosend_tail; i != node->acktosend_head; - i = (i+1) % MAXACKTOSEND) - { - if (cmpack(node->acktosend[i], nextfirstack) <= 0) - { - if (node->acktosend[i] == nextfirstack) - { - node->firstacktosend = nextfirstack++; - if (!nextfirstack) - nextfirstack = 1; - change = true; - } - if (i == node->acktosend_tail) - { - node->acktosend[node->acktosend_tail] = 0; - node->acktosend_tail = (UINT8)((i+1) % MAXACKTOSEND); - } - else if (i == hm1) - { - node->acktosend[hm1] = 0; - node->acktosend_head = hm1; - hm1 = (UINT8)((hm1-1+MAXACKTOSEND) % MAXACKTOSEND); - } - } - } - } - } - else // Out of order packet - { - // Don't increment firsacktosend, put it in asktosend queue - // Will be incremented when the nextfirstack comes (code above) - UINT8 newhead = (UINT8)((node->acktosend_head+1) % MAXACKTOSEND); - DEBFILE(va("out of order packet (%d expected)\n", nextfirstack)); - if (newhead != node->acktosend_tail) - { - node->acktosend[node->acktosend_head] = ack; - node->acktosend_head = newhead; - } - else // Buffer full discard packet, sender will resend it - { // We can admit the packet but we will not detect the duplication after :( - DEBFILE("no more freeackret\n"); - goodpacket = GPACK_OUTOFORDER; - } - } + node->firstacktosend = nextfirstack; + } + else // Out of order packet + { + // Don't increment firsacktosend, put it in asktosend queue + // Will be incremented when the nextfirstack comes (code above) + DEBFILE(va("out of order packet (%d expected)\n", nextfirstack)); + goodpacket = false; } } } - // return values: 0 = ok, 1 = duplicate, 2 = out of order return goodpacket; } -// send special packet with only ack on it -void Net_SendAcks(INT32 node) -{ - doomdata_t *netbuffer = DOOMCOM_DATA(doomcom); - netbuffer->packettype = PT_NOTHING; - memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND); - HSendPacket(node, false, 0, MAXACKTOSEND); -} - -static void GotAcks(void) -{ - INT32 i, j; - - doomdata_t *netbuffer = DOOMCOM_DATA(doomcom); - - for (j = 0; j < MAXACKTOSEND; j++) - if (netbuffer->u.textcmd[j]) - for (i = 0; i < MAXACKPACKETS; i++) - if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode) - { - if (ackpak[i].acknum == netbuffer->u.textcmd[j]) - RemoveAck(i); - // nextacknum is first equal to acknum, then when receiving bigger ack - // there is big chance the packet is lost - // When resent, nextacknum = nodes[node].nextacknum - // will redo the same but with different value - else if (cmpack(ackpak[i].nextacknum, netbuffer->u.textcmd[j]) <= 0 - && ackpak[i].senttime > 0) - { - ackpak[i].senttime--; // hurry up - } - } -} - void Net_ConnectionTimeout(INT32 node) { // Don't timeout several times @@ -538,11 +391,6 @@ void Net_AckTicker(void) // This is something like node open flag if (nodes[i].firstacktosend) { - // We haven't sent a packet for a long time - // Acknowledge packet if needed - if (nodes[i].lasttimeacktosend_sent + ACKTOSENDTIMEOUT < I_GetTime()) - Net_SendAcks(i); - if (!(nodes[i].flags & NF_CLOSE) && nodes[i].lasttimepacketreceived + connectiontimeout < I_GetTime()) { @@ -556,38 +404,12 @@ void Net_AckTicker(void) // (the higher layer doesn't have room, or something else ....) void Net_UnAcknowledgePacket(INT32 node) { - doomdata_t *netbuffer = DOOMCOM_DATA(doomcom); - INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND; DEBFILE(va("UnAcknowledge node %d\n", node)); if (!node) return; - if (nodes[node].acktosend[hm1] == netbuffer->ack) - { - nodes[node].acktosend[hm1] = 0; - nodes[node].acktosend_head = (UINT8)hm1; - } - else if (nodes[node].firstacktosend == netbuffer->ack) - { - nodes[node].firstacktosend--; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = UINT8_MAX; - } - else - { - while (nodes[node].firstacktosend != netbuffer->ack) - { - nodes[node].acktosend_tail = (UINT8) - ((nodes[node].acktosend_tail-1+MAXACKTOSEND) % MAXACKTOSEND); - nodes[node].acktosend[nodes[node].acktosend_tail] = nodes[node].firstacktosend; - - nodes[node].firstacktosend--; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = UINT8_MAX; - } - nodes[node].firstacktosend++; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = 1; - } + nodes[node].firstacktosend--; + if (!nodes[node].firstacktosend) + nodes[node].firstacktosend = UINT8_MAX; } /** Checks if all acks have been received @@ -632,7 +454,6 @@ void Net_WaitAllAckReceived(UINT32 timeout) static void InitNode(netnode_t *node) { - node->acktosend_head = node->acktosend_tail = 0; node->firstacktosend = 0; node->nextacknum = 1; node->remotefirstack = 0; @@ -697,11 +518,12 @@ void Net_CloseConnection(INT32 node) nodes[node].flags |= NF_CLOSE; - // try to Send ack back (two army problem) - if (GetAcktosend(node)) + if (nodes[node].firstacktosend) { - Net_SendAcks(node); - Net_SendAcks(node); + doomdata_t *netbuffer = DOOMCOM_DATA(doomcom); + // send a PT_NOTHING back to acknowledge the packet + netbuffer->packettype = PT_NOTHING; + HSendPacket(node, false, 0, 0); } else { @@ -1066,15 +888,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen netbuffer->ackreturn = 0; if (reliable) { - if (I_NetCanSend && !I_NetCanSend()) - { - if (netbuffer->packettype < PT_CANFAIL) - GetFreeAcknum(&netbuffer->ack, true); - - DEBFILE("HSendPacket: Out of bandwidth\n"); - return false; - } - else if (!GetFreeAcknum(&netbuffer->ack, false)) + if (!GetFreeAcknum(&netbuffer->ack)) return false; } else @@ -1145,7 +959,6 @@ boolean HGetPacket(void) while(true) { //nodejustjoined = I_NetGet(); - int goodpacket; I_NetGet(); if (doomcom->remotenode == -1) // No packet received @@ -1191,15 +1004,8 @@ boolean HGetPacket(void) }*/ // Proceed the ack and ackreturn field - goodpacket = Processackpak(); - if (goodpacket != GPACK_OK) - { - // resend the ACK in case the previous ACK didn't reach the client. - // prevents the client's netbuffer from locking up. - if (goodpacket == GPACK_DUPLICATE) - Net_SendAcks(doomcom->remotenode); + if (!Processackpak()) continue; // discarded (duplicated) - } // measure packet loss if ((SINT8)(netbuffer->packetindex - nodes[doomcom->remotenode].recvnum) <= 0) @@ -1216,10 +1022,7 @@ boolean HGetPacket(void) // A packet with just ackreturn if (netbuffer->packettype == PT_NOTHING) - { - GotAcks(); continue; - } break; } diff --git a/src/d_net.h b/src/d_net.h index b1fa9ac7e..215538216 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -54,7 +54,6 @@ extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game extern boolean serverrunning; -INT32 Net_GetFreeAcks(boolean urgent); void Net_AckTicker(void); // If reliable return true if packet sent, 0 else