Changeset 2101
- Timestamp:
- 06/16/10 15:11:16 (20 months ago)
- Location:
- Whitix/branches/netchannel/user/sdk/network/tcp
- Files:
-
- 11 modified
-
tcp.c (modified) (16 diffs)
-
tcp.h (modified) (6 diffs)
-
tcp_congestion.c (modified) (5 diffs)
-
tcp_congestion.h (modified) (2 diffs)
-
tcp_events.c (modified) (2 diffs)
-
tcp_input.c (modified) (2 diffs)
-
tcp_input.h (modified) (1 diff)
-
tcp_output.c (modified) (5 diffs)
-
tcp_states.c (modified) (3 diffs)
-
tcp_timer.c (modified) (2 diffs)
-
tcp_timer.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
Whitix/branches/netchannel/user/sdk/network/tcp/tcp.c
r2099 r2101 7 7 #include <net/ipv4.h> 8 8 #include <net/tcp.h> 9 #include <limits.h> 9 10 #include <errno.h> 10 11 #include <net/aio.h> … … 67 68 pthread_mutex_init(&tcpSock->sendUpdate, NULL); 68 69 70 /* Stats */ 71 tcpSock->stats.minWin = ULONG_MAX; 72 69 73 /* Add to list, used when writing out profiling and statistics data */ 70 74 if (!tcpHead) … … 100 104 static void TcpRecvAio(struct TcpSocket* tcpSock, char* data, int length) 101 105 { 106 Socket* socket = tcpSock->socket; 107 108 while (socket->recvAio->flags & ASYNC_ACTIVE) 109 SysYield(); 110 111 _SockEventFireList(socket, socket->recvAio, data, length); 102 112 } 103 113 … … 186 196 ulong seq = NetToHostLong(header->seqNum); 187 197 ulong ack = NetToHostLong(header->ackNum); 188 ulong dataLen = length - TcpGetHeaderSize(header) - sizeof(struct IpHeader); 198 struct IpHeader* ipHeader = (struct IpHeader*)ChanRecvBufferData(tcpSock->channel, buffer); 199 ulong dataLen = length - TcpGetHeaderSize(header) - IpGetHeaderSize(ipHeader); 189 200 ulong seqEnd = seq + dataLen; 190 201 int err = TCP_ERROR; … … 277 288 if (dataLen > 0) 278 289 { 279 ChanRecvBuffAddRead(tcpSock->channel, buffer, sizeof(struct IpHeader) + 280 TcpGetHeaderSize(header)); 290 ChanRecvBuffAddRead(tcpSock->channel, buffer, IpGetHeaderSize(ipHeader) + TcpGetHeaderSize(header)); 281 291 282 292 tcpSock->stats.totalBytesRecv += dataLen; … … 305 315 tcpSock->ackMissed++; 306 316 307 if (tcpSock->ackMissedBytes >= 3*tcpSock->mss || tcpSock->ackMissed > 0)317 // if (TcpInSlowStart(tcpSock) || tcpSock->ackMissedBytes >= 3*tcpSock->mss || tcpSock->ackMissed > 3) 308 318 { 309 319 tcpSock->ackMissed = 0; … … 318 328 319 329 if (tcpSock->socket && tcpSock->socket->recvAio) 320 TcpRecvAio(tcpSock, ChanRecvBufferData(tcpSock->channel, buffer) , dataLen);330 TcpRecvAio(tcpSock, ChanRecvBufferData(tcpSock->channel, buffer) + IpGetHeaderSize(ipHeader) + TcpGetHeaderSize(header), dataLen); 321 331 } 322 332 … … 351 361 352 362 dropPacket: 353 tcpSock->stats.droppedPackets++; 354 tcpSock->stats.droppedBytes += dataLen; 363 TcpDropPacket(tcpSock, dataLen); 355 364 return err; 356 365 } … … 695 704 { 696 705 struct TcpSocket* tcpSock = (struct TcpSocket*)(socket->priv); 706 struct HostEntry* entry; 707 708 if ((entry = HostFindEntry(TcpDestAddress(tcpSock), HOST_CLIENT))) 709 { 710 tcpSock->rto = entry->rto; 711 tcpSock->rtt = entry->rtt; 712 tcpSock->mdev = entry->mdev; 713 }else{ 714 tcpSock->rto = TCP_RTO_DEFAULT; 715 tcpSock->rtt = TCP_RTT_DEFAULT; 716 tcpSock->localThresh = 0x10000; 717 } 697 718 698 719 /* Window setup */ … … 704 725 tcpSock->localCwndBytes = tcpSock->mss; 705 726 tcpSock->prevUpRatio = 3; 706 tcpSock->localThresh = 0x10000;707 708 /* Retx */709 tcpSock->rto = TCP_RTO_DEFAULT;710 711 TCP_DEBUG(("mss (local) = %u", tcpSock->mss));712 727 713 728 if (TcpSendSyn(socket) < 0) … … 715 730 716 731 TcpSetTimer(tcpSock, TCP_SYN_TIMEOUT, TcpResendSyn); 717 718 732 TcpSocketAdd(socket); 719 733 … … 728 742 729 743 /* Set up statistics */ 744 tcpSock->stats.destAddr = NetToHostLong(TcpDestAddress(tcpSock)); 730 745 tcpSock->stats.destPort = TcpDestPort(tcpSock); 731 746 … … 738 753 ChannelOptions options; 739 754 struct TcpSocket* tcpSock = TcpInfo(socket); 755 struct Ipv4EndPoint* dest = (struct Ipv4EndPoint*)address; 740 756 741 757 chanSrc.address = 0; 742 758 chanSrc.port = 0; /* IP channel code will sort out a port. */ 743 759 744 options.flags = CHAN_KEEP_SEND_BUFFERS; 760 if (!dest->port) 761 return -1; 762 763 options.flags = CHAN_KEEP_SEND_BUFFERS | CHAN_RECORD_SEND_TIME; 745 764 options.sendBuffers = 0; 746 765 options.recvBuffers = 0; … … 769 788 chanDest.port = 0; 770 789 771 options.flags = CHAN_KEEP_SEND_BUFFERS ;790 options.flags = CHAN_KEEP_SEND_BUFFERS | CHAN_RECORD_SEND_TIME; 772 791 options.sendBuffers = 0; 773 792 options.recvBuffers = 0; … … 841 860 srcIp.port = TcpSourcePort(tcpSock); 842 861 843 options.flags = CHAN_KEEP_SEND_BUFFERS ;862 options.flags = CHAN_KEEP_SEND_BUFFERS | CHAN_RECORD_SEND_TIME; 844 863 options.sendBuffers = 0; 845 864 options.recvBuffers = 0; … … 888 907 address->port = destIp.port; 889 908 address->address = NetToHostLong(destIp.address); 909 910 childInfo->stats.destAddr = address->address; 911 childInfo->stats.destPort = address->port; 890 912 891 913 return 0; -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp.h
r2099 r2101 8 8 #include <net/ipv4.h> 9 9 #include <net/tcp.h> 10 11 #include "../stats/stats.h" 10 12 11 13 #define CHAN_TYPE_TCP 3 … … 20 22 ulong droppedPackets, droppedBytes; 21 23 ulong retxBytesSent, retxPacketsSent; 22 ulong wrongSumPackets, wrongSumBytes;24 ulong minWin, maxWin; 23 25 24 26 /* (Mainly) protocol */ … … 65 67 struct UserTimer retxTimer; 66 68 int retxTimerHnd; 67 int rto ;69 int rto, rtt, mdev; 68 70 69 71 /* Sequence numbers. */ … … 111 113 112 114 /* Events */ 113 struct AsyncCtx * remWinChanged;115 struct AsyncCtx *remWinChanged, *retxTimerOut, *localWinChanged, *droppedPkts; 114 116 }; 117 118 extern int _netDebug; 119 120 #ifndef DEBUG_TCP 121 #define DEBUG_TCP 0x1 122 #endif 115 123 116 124 //#define TCP_DEBUG_Y 117 125 118 126 #ifdef TCP_DEBUG_Y 119 #define TCP_DEBUG(args) do { printf("[TCP]: %d: %s: ", SysGetCurrentThreadId(), __func__); printf args; printf(" (%s:%d)\n", __FILE__, __LINE__);} while (0)127 #define TCP_DEBUG(args) do { if (_netDebug & DEBUG_TCP) { printf("[TCP]: %d: %s: ", SysGetCurrentThreadId(), __func__); printf args; printf(" (%s:%d)\n", __FILE__, __LINE__); } } while (0) 120 128 #else 121 129 #define TCP_DEBUG(args) … … 132 140 { 133 141 return ((struct Ipv4EndPoint*)(&socket->channel->src))->port; 142 } 143 144 static inline ulong TcpDestAddress(struct TcpSocket* socket) 145 { 146 return ((struct Ipv4EndPoint*)(&socket->channel->dest))->address; 134 147 } 135 148 … … 156 169 #define TCP_AGAIN -2 157 170 171 /* Buffer flags */ 172 #define TCP_FLAG_RETX 0x01 173 158 174 #endif -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_congestion.c
r2099 r2101 1 #include <net/socket.h> 2 #include <net/inet_raw.h> 3 1 4 #include "tcp.h" 2 5 #include "seq.h" … … 4 7 #include "../ipv4.h" 5 8 #include "tcp_congestion.h" 9 #include "tcp_timer.h" 6 10 7 11 int TcpInSlowStart(struct TcpSocket* tcpSock) … … 13 17 { 14 18 ChanSendBuffer* curr; 19 struct IpHeader* ipHeader; 20 int ret; 15 21 16 22 pthread_mutex_lock(&tcpSock->retxLock); … … 35 41 return 0; 36 42 37 TCP_DEBUG(("curr, fast retransmit!")); 38 SysExit(0); 43 ipHeader = (struct IpHeader*)(ChanSendBufferData(tcpSock->channel, curr)); 44 TCP_DEBUG(("Resending length=%u", NetToHostShort(ipHeader->totalLength))); 45 46 ChanSendBuffSetFlags(curr, TCP_FLAG_RETX); 47 48 if ((ret = ChanBufferSend(tcpSock->channel, curr, NetToHostShort(ipHeader->totalLength))) < 0) 49 { 50 TCP_DEBUG(("Could not retransmit in retransmission timeout handler, ret=%d", ret)); 51 tcpSock->retx = curr; 52 } 39 53 40 54 out: … … 112 126 void TcpRetxTimeout(void* data) 113 127 { 114 printf("TcpRetxTimeout\n"); 115 } 128 struct TcpSocket* socket = (struct TcpSocket*)data; 129 ChanSendBuffer* retx; 130 struct IpHeader* ipHeader; 131 int ret; 132 ulong oldRto = socket->rto; 133 134 pthread_mutex_lock(&socket->retxLock); 135 if ((retx = socket->retx)) 136 socket->retx = ChanSendBuffGetPriv(socket->retx); 137 pthread_mutex_unlock(&socket->retxLock); 138 139 if (retx) 140 { 141 ipHeader = (struct IpHeader*)(ChanSendBufferData(socket->channel, retx)); 142 TCP_DEBUG(("Resending length=%u", NetToHostShort(ipHeader->totalLength))); 143 144 ChanSendBuffSetFlags(retx, TCP_FLAG_RETX); 145 146 if ((ret = ChanBufferSend(socket->channel, retx, NetToHostShort(ipHeader->totalLength))) < 0) 147 { 148 TCP_DEBUG(("Could not retransmit in retransmission timeout handler, ret=%d", ret)); 149 socket->retx = retx; 150 } 151 } 152 153 socket->rto = MIN(socket->rto << 1, TCP_MSL); 154 TCP_DEBUG(("rto = %u", socket->rto)); 155 156 TcpRetxTimerStart(socket); 157 158 if (socket->socket && socket->retxTimerOut) 159 { 160 /* Let application know retransmit timed out. Supply the timing information. */ 161 struct TcpRetxInfo txInf; 162 163 txInf.rtoOld = oldRto; 164 txInf.rtoNew = socket->rto; 165 txInf.rtt = socket->rtt; 166 txInf.mdev = socket->mdev; 167 168 _SockEventFireList(socket->socket, socket->retxTimerOut, &txInf, sizeof(struct TcpRetxInfo)); 169 } 170 } 171 172 void TcpUpdateRtt(struct TcpSocket* tcpSock, ChanSendBuffer* buffer) 173 { 174 int diff = 0; 175 struct Time time, sendTime, result; 176 177 if (ChanSendBuffGetFlags(buffer) & TCP_FLAG_RETX) 178 return; 179 180 ChanSendBuffGetTime(buffer, &sendTime); 181 SysGetTime(&time); 182 TimerSub(&time, &sendTime, &result); 183 diff = result.seconds*1000; 184 185 if (diff <= 1000) 186 diff = 1000; 187 188 /* The new RTT estimate is 3/4*old + 1/4*new */ 189 diff -= (tcpSock->rtt >> 2); 190 tcpSock->rtt += diff; 191 192 if (diff < 0) 193 diff = -diff; 194 195 diff -= (tcpSock->mdev >> 2); 196 tcpSock->mdev += diff; 197 198 /* Retransmission timeout */ 199 tcpSock->rto = MIN(((tcpSock->rtt >> 2) + tcpSock->mdev) >> 1, TCP_MSL); 200 201 if (tcpSock->rto < 1000) 202 tcpSock->rto = 1000; 203 204 TCP_DEBUG(("rto = %u\n", tcpSock->rto)); 205 } -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_congestion.h
r2099 r2101 2 2 #define TCP_CONGESTION_H 3 3 4 #include <net/channels.h> 4 5 #include <types.h> 5 6 … … 10 11 void TcpCongestion(struct TcpSocket* tcpSock); 11 12 void TcpRetxTimeout(void* data); 13 void TcpUpdateRtt(struct TcpSocket* tcpSock, ChanRecvBuffer* buffer); 12 14 13 15 #endif -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_events.c
r2099 r2101 29 29 int TcpRetxTimerOutRegister(Socket* socket, struct TcpEventCtx* ctx) 30 30 { 31 /* 1. Verify socket is TCP */32 /* 2. Use internal buffer when posting events. Have general TCP state structure */31 struct TcpSocket* tcpSock = TcpInfo(socket); 32 ctx->ctx.socket = socket; 33 33 34 return 0;34 return SocketAsyncAdd(&tcpSock->retxTimerOut, &ctx->ctx); 35 35 } 36 36 37 int TcpDroppedPktsRegister(Socket* socket, struct TcpEventCtx* ctx , int flags)37 int TcpDroppedPktsRegister(Socket* socket, struct TcpEventCtx* ctx) 38 38 { 39 /* 1. Verify socket is TCP */ 40 /* 2. flags could be CHECKSUM, DUP, etc. */ 41 return 0; 39 struct TcpSocket* tcpSock = TcpInfo(socket); 40 ctx->ctx.socket = socket; 41 42 return SocketAsyncAdd(&tcpSock->droppedPkts, &ctx->ctx); 42 43 } 43 44 44 45 int TcpLocalWinRegister(Socket* socket, struct TcpEventCtx* ctx) 45 46 { 46 return 0; 47 struct TcpSocket* tcpSock = TcpInfo(socket); 48 ctx->ctx.socket = socket; 49 50 return SocketAsyncAdd(&tcpSock->localWinChanged, &ctx->ctx); 47 51 } 48 52 … … 54 58 return SocketAsyncAdd(&tcpSock->remWinChanged, &ctx->ctx); 55 59 } 56 57 int TcpStateUpdateRegister(Socket* socket, struct TcpEventCtx* ctx, int seconds)58 {59 return 0;60 }61 62 int TcpSetTransfer(Socket* socket, int length, int blockSize)63 {64 return 0;65 } -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_input.c
r2100 r2101 24 24 } 25 25 26 void TcpDropPacket(struct TcpSocket* tcp, int length) 27 { 28 tcp->stats.droppedPackets++; 29 tcp->stats.droppedBytes += length; 30 31 if (tcp->socket && tcp->droppedPkts) 32 { 33 _SockEventFireList(tcp->socket, tcp->droppedPkts, NULL, 0); 34 } 35 } 36 26 37 struct TcpHeader* TcpReadPacket(struct TcpSocket* tcpSock, ChanRecvBuffer** buffer, int* 27 38 length) … … 45 56 if (tcpHeader->checkSum != TcpCalcChecksum(ipHeader, tcpHeader, *length)) 46 57 { 47 tcpSock->stats.wrongSumPackets++; 48 tcpSock->stats.wrongSumBytes += *length - sizeof(struct IpHeader); 58 TcpDropPacket(tcpSock, *length - sizeof(struct IpHeader)); 49 59 goto error; 50 60 } -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_input.h
r2100 r2101 5 5 length); 6 6 int TcpSocketRecv(Socket* socket, void* buffer, unsigned long length, int flags); 7 void TcpDropPacket(struct TcpSocket* tcpSock, int length); 7 8 8 9 #endif -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_output.c
r2099 r2101 302 302 { 303 303 TcpAddToTxQueue(tcpSock, buffer, length); 304 }else{ 305 // if (TcpInSlowStart(tcpSock) || (length + TCP_HEADER_MAX_SIZE + sizeof (struct IpHeader)) >= tcpSock->mss) 306 // { 307 ret = TcpTryToSend(tcpSock, buffer, length); 308 // }else{ 309 // printf("SMALL\n"); 310 // SysExit(0); 311 // } 312 } 304 }else 305 ret = TcpTryToSend(tcpSock, buffer, length); 313 306 314 307 if (ret == TCP_AGAIN || ret >= 0) … … 349 342 tcpSock->bytesInFlight -= (endSeq-seq); 350 343 351 // TCP_DEBUG(("%d, %d bytes", tcpSock->pktsInFlight, tcpSock->bytesInFlight));352 353 if (tcpSock->pktsInFlight == 0)354 {355 TCP_DEBUG(("queue = %#X (%d)\n", tcpSock->tx, tcpSock->stats.totalBytesSent));356 }357 358 344 tcpSock->dupAckSeq = tcpSock->lastRetx = seq; 345 346 /* Update round-trip time estimate */ 347 TcpUpdateRtt(tcpSock, buffer); 359 348 360 349 ChanSendBuffSetPriv(buffer, NULL); … … 384 373 } 385 374 375 386 376 int TcpSendPacket(struct TcpSocket* socket, struct TcpHeader* header, const void* buffer, unsigned long length, int flags, ChanSendBuffer** chanBuff) 387 377 { … … 403 393 if (buffer) 404 394 memcpy(data + sizeof(struct IpHeader) + tcpHeaderSize, buffer, length); 405 406 395 pthread_mutex_lock(&socket->sendUpdate); 407 396 … … 424 413 pthread_mutex_unlock(&socket->sendUpdate); 425 414 return (ret < 0) ? ret : length; 415 426 416 } 427 417 -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_states.c
r2099 r2101 34 34 } 35 35 36 if (states[tcpSock->state] != NULL )36 if (states[tcpSock->state] != NULL /*&& (TcpGetTs() & 1)*/) 37 37 ret = states[tcpSock->state](tcpSock, header, buffer, length); 38 39 #if 0 40 else 41 printf("Dropped! (%u, %d)\n", length, tcpSock->state); 42 #endif 38 43 39 44 if (ret == TCP_ERROR) … … 61 66 ChanRecvBuffFree(tcpSock->channel, buffer); 62 67 63 /* Event handling */68 /* Event handling and general statistical update */ 64 69 if (!ret && tcpSock->socket) 65 70 { … … 70 75 } 71 76 77 if (tcpSock->remoteWindow < tcpSock->stats.minWin) 78 tcpSock->stats.minWin = tcpSock->remoteWindow; 79 80 if (tcpSock->remoteWindow > tcpSock->stats.maxWin) 81 tcpSock->stats.maxWin = tcpSock->remoteWindow; 82 72 83 return 0; 73 84 } -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_timer.c
r2099 r2101 37 37 void TcpTimeWaitClose(struct TcpSocket* tcpSock) 38 38 { 39 printf("TIME-WAIT: CLOSE\n");40 41 39 TcpChangeState(tcpSock, TCP_CLOSED); 42 40 } … … 69 67 spec.seconds = tcpSock->rto/1000; 70 68 spec.useconds = tcpSock->rto % 1000; 71 69 72 70 SysTimerModify(tcpSock->retxTimerHnd, &spec, NULL); 73 71 } -
Whitix/branches/netchannel/user/sdk/network/tcp/tcp_timer.h
r2100 r2101 5 5 #define TCP_MSL 2*60 /* minutes */ 6 6 #define TCP_RTO_DEFAULT 3*1000 7 #define TCP_RTT_DEFAULT 1*1000 7 8 8 9 int TcpTimerInit(struct TcpSocket* tcpSock);
