📄 tcpip.c
字号:
} else if(mode == IP_MODE_UDP) { socket->state = IP_UDP; ptrSend[IP_PROTOCOL] = 0x11; //UDP ptrRcv[IP_PROTOCOL] = 0x11; } else if(mode == IP_MODE_PING) { socket->state = IP_PING; ptrSend[IP_PROTOCOL] = 0x01; //PING memset(ptrSend+PING_TYPE, 0, 8); ptrSend[PING_TYPE] = 8; //SEND } //Add socket to linked list OS_MutexPend(IPMutex); socket->next = SocketHead; socket->prev = NULL; if(SocketHead) SocketHead->prev = socket; SocketHead = socket; OS_MutexPost(IPMutex); if(mode == IP_MODE_TCP && ipAddress) { //Send TCP SYN socket->seq = 0x01234567; frame = IPFrameGet(0); if(frame) { frame->packet[TCP_FLAGS] = TCP_FLAGS_SYN; frame->packet[TCP_DATA] = 2; //maximum segment size = 536 frame->packet[TCP_DATA+1] = 4; frame->packet[TCP_DATA+2] = 2; frame->packet[TCP_DATA+3] = 24; TCPSendPacket(socket, frame, TCP_DATA+4); ++socket->seq; } } return socket;}void IPWriteFlush(IPSocket *socket){ uint8 *packetOut; if(socket->frameSend && socket->state != IP_UDP && socket->state != IP_PING) { packetOut = socket->frameSend->packet; packetOut[TCP_FLAGS] = TCP_FLAGS_ACK; TCPSendPacket(socket, socket->frameSend, TCP_DATA + socket->sendOffset); socket->seq += socket->sendOffset; socket->frameSend = NULL; socket->sendOffset = 0; }}uint32 IPWrite(IPSocket *socket, const uint8 *buf, uint32 length){ IPFrame *frameOut; uint8 *packetOut; uint32 bytes, count=0, tries=0; int offset; OS_Thread_t *self; //printf("IPWrite(0x%x, %d)", Socket, Length); self = OS_ThreadSelf(); while(length) { //Rate limit output if(socket->seq - socket->seqReceived >= 5120) { if(self == IPThread || ++tries > 200) break; else { OS_ThreadSleep(1); continue; } } tries = 0; while(socket->frameSend == NULL) { socket->frameSend = IPFrameGet(FRAME_COUNT_SEND); socket->sendOffset = 0; if(socket->frameSend == NULL) { if(self == IPThread || ++tries > 200) break; else OS_ThreadSleep(1); } } frameOut = socket->frameSend; offset = socket->sendOffset; if(frameOut == NULL) break; packetOut = frameOut->packet; if(socket->state == IP_PING) { bytes = length; memcpy(packetOut, socket->headerSend, PING_DATA); memcpy(packetOut+PING_DATA, buf, bytes); IPSendPacket(socket, socket->frameSend, PING_DATA + bytes); socket->frameSend = NULL; } else if(socket->state != IP_UDP) { bytes = 512 - offset; if(bytes > length) bytes = length; socket->sendOffset += bytes; memcpy(packetOut+TCP_DATA+offset, buf, bytes); if(socket->sendOffset >= 512) IPWriteFlush(socket); //if(Socket->seq - Socket->seqReceived > Socket->seqWindow) //{ // printf("W"); // OS_ThreadSleep(10); //} } else //UDP { bytes = length; memcpy(packetOut+UDP_DATA+offset, buf, bytes); memcpy(packetOut, socket->headerSend, UDP_LENGTH); IPSendPacket(socket, socket->frameSend, UDP_DATA + bytes); socket->frameSend = NULL; } count += bytes; buf += bytes; length -= bytes; } return count;}uint32 IPRead(IPSocket *socket, uint8 *buf, uint32 length){ IPFrame *frame, *frame2; int count=0, bytes, offset; if(socket->state == IP_TCP) offset = TCP_DATA; else offset = UDP_DATA; OS_MutexPend(IPMutex); for(frame = socket->frameReadTail; length && frame; ) { bytes = frame->length - offset - socket->readOffset; if(bytes > (int)length) bytes = length; memcpy(buf, frame->packet + offset + socket->readOffset, bytes); buf += bytes; socket->readOffset += bytes; length -= bytes; count += bytes; //Check if done with packet frame2 = frame; frame = frame->prev; if(socket->readOffset == frame2->length - offset) { //Remove packet from socket linked list socket->readOffset = 0; FrameRemove(&socket->frameReadHead, &socket->frameReadTail, frame2); FrameFree(frame2); } } OS_MutexPost(IPMutex); return count;}static void IPClose2(IPSocket *socket){ IPFrame *frame, *framePrev; OS_MutexPend(IPMutex); //Mark packets as don't retransmit for(frame = FrameSendHead; frame; frame = frame->next) { if(frame->socket == socket) frame->socket = NULL; } //Remove packets from retransmision list for(frame = FrameResendHead; frame; ) { framePrev = frame; frame = frame->next; if(framePrev->socket == socket) { FrameRemove(&FrameResendHead, &FrameResendTail, framePrev); FrameFree(framePrev); } } //Remove packets from socket read linked list for(frame = socket->frameReadHead; frame; ) { framePrev = frame; frame = frame->next; FrameRemove(&socket->frameReadHead, &socket->frameReadTail, framePrev); FrameFree(framePrev); } //Remove socket if(socket->prev == NULL) SocketHead = socket->next; else socket->prev->next = socket->next; if(socket->next) socket->next->prev = socket->prev; free(socket); OS_MutexPost(IPMutex);}void IPClose(IPSocket *socket){ IPFrame *frameOut; IPWriteFlush(socket); if(socket->state <= IP_UDP) { IPClose2(socket); return; } frameOut = IPFrameGet(0); if(frameOut == 0) return; frameOut->packet[TCP_FLAGS] = TCP_FLAGS_FIN | TCP_FLAGS_ACK; TCPSendPacket(socket, frameOut, TCP_DATA); ++socket->seq; if(socket->state == IP_FIN_CLIENT) IPClose2(socket); else socket->state = IP_FIN_SERVER;}void IPPrintf(IPSocket *socket, char *message){ IPWrite(socket, (uint8*)message, (int)strlen(message)); IPWriteFlush(socket);}void IPTick(void){ IPFrame *frame, *frame2; IPSocket *socket, *socket2; if(IPVerbose && (Seconds % 60) == 0) { if(FrameFreeCount == FRAME_COUNT) printf("T"); else printf("T(%d)", FrameFreeCount); } ++Seconds; if(--DhcpRetrySeconds <= 0) IPDhcp(NULL, 400, 1); //DHCP request //if(Seconds == 10) // IPResolve("plasmacpu.no-ip.org", ShowIP); OS_MutexPend(IPMutex); //Retransmit timeout packets for(frame = FrameResendHead; frame; ) { frame2 = frame; frame = frame->next; if(--frame2->timeout == 0) { if(IPVerbose) printf("r"); FrameRemove(&FrameResendHead, &FrameResendTail, frame2); IPSendFrame(frame2); } } //Close timed out sockets for(socket = SocketHead; socket; ) { socket2 = socket; socket = socket->next; if(socket2->timeout && --socket2->timeout == 0) { socket2->timeout = 10; if(IPVerbose) printf("t(%d,%d)", socket2->state, FrameFreeCount); if(socket2->state == IP_TCP) IPClose(socket2); else if(socket2->state == IP_FIN_CLIENT) IPClose(socket2); else IPClose2(socket2); } } OS_MutexPost(IPMutex);}static void DnsCallback(IPSocket *socket){ uint8 buf[200], *ptr; uint32 ipAddress; int bytes; memset(buf, 0, sizeof(buf)); bytes = IPRead(socket, buf, sizeof(buf)); if(buf[DNS_NUM_ANSWERS_RR+1]) { for(ptr = buf + DNS_QUESTIONS; ptr + 14 <= buf + bytes; ++ptr) { if(ptr[0] == 0 && ptr[1] == 1 && ptr[2] == 0 && ptr[3] == 1 && ptr[8] == 0 && ptr[9] == 4) { ipAddress = (ptr[10] << 24) | (ptr[11] << 16) | (ptr[12] << 8) | ptr[13]; printf("ipAddress = %d.%d.%d.%d\n", ptr[10], ptr[11], ptr[12], ptr[13]); socket->userData = ipAddress; if(socket->userFunc) { socket->userFunc(socket, ipAddress, socket->userPtr); } break; } } } if(FrameSendFunc) IPClose(socket);}uint32 IPResolve(char *name, IPFuncPtr resolvedFunc, void *arg){ uint8 buf[200], *ptr; int length, i; IPSocket *socket; uint32 ipAddress=0; socket = IPOpen(IP_MODE_UDP, ipAddressDns, DNS_PORT, DnsCallback); memset(buf, 0, sizeof(buf)); buf[DNS_ID+1] = 1; buf[DNS_FLAGS] = 1; buf[DNS_NUM_QUESTIONS+1] = 1; //Setup name ptr = buf + DNS_QUESTIONS; strncpy((char*)ptr+1, name, 100); ptr[0] = 1; while(ptr[0]) { for(i = 0; i < 100; ++i) { if(ptr[i+1] == '.' || ptr[i+1] == 0) { ptr[0] = (uint8)i; ptr += i+1; break; } } } ++ptr; ptr[1] = DNS_QUERY_TYPE_IP; ptr[3] = DNS_QUERY_CLASS; length = (int)(ptr - buf) + 4; if(length < 60) length = 60; socket->userFunc = (IPFuncPtr)resolvedFunc; socket->userPtr = arg; socket->userData = 0; IPWrite(socket, buf, length); if(FrameSendFunc == NULL) { for(i = 0; i < 1000 && socket->userData == 0; ++i) OS_ThreadSleep(1); ipAddress = socket->userData; IPClose(socket); } return ipAddress;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -