int NET_GetPacket(netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { #ifndef DEDICATED_ONLY if (NET_GetLoopPacket (sock, net_from, net_message)) return 1; #endif int net_socket = ip_sockets[sock]; if (!net_socket) return 0; // TODO: failed packets? uint16_t packetSize = fuzzReadUint16(); uint16_t port = fuzzReadUint16(); uint32_t ip4 = fuzzReadUint32(); packetSize = std::min(packetSize, static_cast<uint16_t>(net_message->maxsize)); net_from->type = NA_IP; net_from->port = port; net_from->ip[0] = ((ip4 ) & 0xFF); net_from->ip[1] = ((ip4 >> 8) & 0xFF); net_from->ip[2] = ((ip4 >> 16) & 0xFF); net_from->ip[3] = ((ip4 >> 24) & 0xFF); fuzzRead(reinterpret_cast<char *>(net_message->data), packetSize); net_message->cursize = packetSize; return 1; }
qboolean NET_GetPacket(struct qw_connection *qwc, enum netsrc sock, struct sizebuf_s *message, struct netaddr *from) { int ret; struct SysSocket *net_socket; if (NET_GetLoopPacket(qwc, sock, message, from)) return true; net_socket = qwc->netdata->sockets[sock]; if (net_socket == 0) return false; ret = Sys_Net_Receive(qwc->netdata->sysnetdata, net_socket, message->data, message->maxsize, from); if (ret <= 0) { if (ret < 0) Com_Printf("%s: Network error.\n", __func__); return false; } message->cursize = ret; return true; }
qbool NET_GetPacketEx (netsrc_t netsrc, qbool delay) { #ifndef SERVERONLY if (delay) return NET_PacketQueueRemove(&delay_queue_get, &net_message, &net_from); #endif #ifndef SERVERONLY if (NET_GetLoopPacket(netsrc, &net_from, &net_message)) return true; #endif if (NET_GetUDPPacket(netsrc, &net_from, &net_message)) return true; // TCPCONNECT --> #ifndef SERVERONLY if (netsrc == NS_CLIENT && cls.sockettcp != INVALID_SOCKET && NET_GetTCPPacket_CL(netsrc, &net_from, &net_message)) return true; #endif #ifndef CLIENTONLY if (netsrc == NS_SERVER && svs.tcpstreams && NET_GetTCPPacket_SV(netsrc, &net_from, &net_message)) return true; #endif // <--TCPCONNECT return false; }
qboolean NET_GetPacket (netsrc_t sock) { int ret; struct sockaddr_in from; int fromlen; int net_socket; if (NET_GetLoopPacket (sock)) return true; net_socket = ip_sockets[sock]; if (net_socket == -1) return false; fromlen = sizeof(from); ret = recvfrom (net_socket, net_message_buffer, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen); if (ret == -1) { if (errno == EWOULDBLOCK) return false; if (errno == ECONNREFUSED) return false; Sys_Printf ("NET_GetPacket: %s\n", strerror(errno)); return false; } net_message.cursize = ret; SockadrToNetadr (&from, &net_from); return ret; }
qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret; struct sockaddr_storage from; socklen_t fromlen; int net_socket; int protocol; int err; if (NET_GetLoopPacket (sock, net_from, net_message)) return true; for (protocol = 0 ; protocol < 3 ; protocol++) { if (protocol == 0) net_socket = ip_sockets[sock]; else if (protocol == 1) net_socket = ip6_sockets[sock]; else net_socket = ipx_sockets[sock]; if (!net_socket) continue; fromlen = sizeof(from); ret = recvfrom (net_socket, net_message->data, net_message->maxsize, 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr (&from, net_from); if (ret == -1) { err = errno; if (err == EWOULDBLOCK || err == ECONNREFUSED) continue; Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); continue; } if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from)); continue; } net_message->cursize = ret; return true; } return false; }
/* <d40a2> ../engine/net_ws.c:1391 */ qboolean NET_GetPacket_internal(netsrc_t sock) { net_messages_t *pmsg; // 1393 qboolean bret; // 1396 NET_AdjustLag(); NET_ThreadLock(); if (NET_GetLoopPacket(sock, &in_from, &in_message)) { bret = NET_LagPacket(1, sock, &in_from, &in_message); } else { if (!use_thread) { bret = NET_QueuePacket(sock); if (!bret) bret = NET_LagPacket(0, sock, 0, 0); } else { bret = NET_LagPacket(0, sock, 0, 0); } } if (bret) { Q_memcpy(net_message.data, in_message.data, in_message.cursize); net_message.cursize = in_message.cursize; Q_memcpy(&net_from, &in_from, 0x14u); NET_ThreadUnlock(); return bret; } pmsg = messages[sock]; if (pmsg) { net_message.cursize = pmsg->buffersize; messages[sock] = pmsg->next; Q_memcpy(net_message.data, pmsg->buffer, net_message.cursize); net_from = pmsg->from; msg_readcount = 0; NET_FreeMsg(pmsg); bret = 1; } NET_ThreadUnlock(); return bret; }
/* ================== NET_GetPacket ================== */ bool NET_GetPacket (netSrc_t sock, netAdr_t *from, msg_t *msg){ struct sockaddr adr; int adrLen = sizeof(adr); int result, error; if (NET_GetLoopPacket(sock, from, msg)) return true; if (net.sockets[sock] == INVALID_SOCKET) return false; result = recvfrom(net.sockets[sock], (char *)msg->data, msg->maxSize, 0, (struct sockaddr *)&adr, &adrLen); NET_SockAdrToNetAdr(&adr, from); if (result == SOCKET_ERROR){ error = WSAGetLastError(); // WSAEWOULDBLOCK and WSAECONNRESET are silent if (error == WSAEWOULDBLOCK || error == WSAECONNRESET) return false; Com_Printf(S_COLOR_RED "NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AddressToString(*from)); return false; } if (result == msg->maxSize){ Com_Printf(S_COLOR_RED "NET_GetPacket: oversize packet from %s\n", NET_AddressToString(*from)); return false; } msg->curSize = result; net.packetsReceived[sock]++; net.bytesReceived[sock] += result; return true; }
int NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { if (NET_GetLoopPacket (sock, net_from, net_message)) return 1; if (!wsState) { // not initialized yet return 0; } if (wsState->pendingData.empty()) { #ifdef EMSCRIPTEN return 0; #else // EMSCRIPTEN libwebsocket_service(wsState->websocketContext, 0); #endif // EMSCRIPTEN } // don't iterate via reference, recvPacket will alter the data structure for (auto conn : wsState->pendingData) { if (conn->recvPacket(net_message)) { *net_from = conn->addr; net_packets_in++; net_total_in += net_message->cursize; return 1; } // not enough data for a complete packet, try next connection } return 0; }
/* ================= Com_EventLoop Returns last event time ================= */ int Com_EventLoop( void ) { sysEvent_t ev; netadr_t evFrom; byte bufData[MAX_MSGLEN]; msg_t buf; MSG_Init( &buf, bufData, sizeof( bufData ) ); while ( 1 ) { ev = Com_GetEvent(); // if no more events are available if ( ev.evType == SE_NONE ) { // manually send packet events for the loopback channel while ( NET_GetLoopPacket( NS_CLIENT, &evFrom, &buf ) ) { CL_PacketEvent( evFrom, &buf ); } while ( NET_GetLoopPacket( NS_SERVER, &evFrom, &buf ) ) { // if the server just shut down, flush the events if ( com_sv_running->integer ) { Com_RunAndTimeServerPacket( &evFrom, &buf ); } } return ev.evTime; } switch ( ev.evType ) { default: Com_Error( ERR_FATAL, "Com_EventLoop: bad event type %i", ev.evType ); break; case SE_NONE: break; case SE_KEY: CL_KeyEvent( ev.evValue, ev.evValue2, ev.evTime ); break; case SE_CHAR: CL_CharEvent( ev.evValue ); break; case SE_MOUSE: CL_MouseEvent( ev.evValue, ev.evValue2, ev.evTime ); break; case SE_JOYSTICK_AXIS: CL_JoystickEvent( ev.evValue, ev.evValue2, ev.evTime ); break; case SE_CONSOLE: Cbuf_AddText( (char *)ev.evPtr ); Cbuf_AddText( "\n" ); break; case SE_PACKET: evFrom = *(netadr_t *)ev.evPtr; buf.cursize = ev.evPtrLength - sizeof( evFrom ); // we must copy the contents of the message out, because // the event buffers are only large enough to hold the // exact payload, but channel messages need to be large // enough to hold fragment reassembly if ( (unsigned)buf.cursize > (unsigned)buf.maxsize ) { Com_Printf("Com_EventLoop: oversize packet\n"); continue; } memcpy( buf.data, (byte *)((netadr_t *)ev.evPtr + 1), buf.cursize ); if ( com_sv_running->integer ) { Com_RunAndTimeServerPacket( &evFrom, &buf ); } else { CL_PacketEvent( evFrom, &buf ); } break; } // free any block data if ( ev.evPtr ) { Z_Free( ev.evPtr ); } } }
/* ============= NET_GetPacket ============= */ int NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret, err; socklen_t fromlen; struct sockaddr from; if (NET_GetLoopPacket (sock, net_from, net_message)) return 1; if (ip_sockets[sock] == INVALID_SOCKET) return 0; fromlen = sizeof(from); ret = recvfrom (ip_sockets[sock], (char *)net_message->data, net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr (&from, net_from); if (ret == SOCKET_ERROR) { #ifdef _WIN32 err = WSAGetLastError(); switch( err ) { case WSAEWOULDBLOCK: // wouldblock is silent break; case WSAECONNRESET: if( !net_ignore_icmp->integer ) { return -1; } break; case WSAEMSGSIZE: Com_Printf ("NET_GetPacket: Oversize packet from %s\n", NET_AdrToString(net_from)); break; default: Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(net_from)); break; } #else err = errno; switch( err ) { case EWOULDBLOCK: // wouldblock is silent break; case ECONNREFUSED: if( !net_ignore_icmp->integer ) { return -1; } break; default: Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(net_from)); break; } #endif return 0; } if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", NET_AdrToString (net_from)); return 0; } net_message->cursize = ret; return 1; }
qboolean NET_GetPacket(netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret; struct sockaddr_storage from; socklen_t fromlen; int net_socket; int protocol; int err; if (NET_GetLoopPacket(sock, net_from, net_message)) { return true; } for (protocol = 0; protocol < 3; protocol++) { if (protocol == 0) { net_socket = ip_sockets[sock]; } else if (protocol == 1) { net_socket = ip6_sockets[sock]; } else { net_socket = ipx_sockets[sock]; } if (!net_socket) { continue; } fromlen = sizeof(from); ret = recvfrom(net_socket, (char *)net_message->data, net_message->maxsize, 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr(&from, net_from); if (ret == -1) { err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { continue; } if (err == WSAEMSGSIZE) { Com_Printf("Warning: Oversize packet from %s\n", NET_AdrToString(*net_from)); continue; } if (dedicated->value) /* let dedicated servers continue after errors */ { Com_Printf("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); } else { Com_Printf("NET_GetPacket: %s from %s", NET_ErrorString(), NET_AdrToString(*net_from)); } continue; } if (ret == net_message->maxsize) { Com_Printf("Oversize packet from %s\n", NET_AdrToString(*net_from)); continue; } net_message->cursize = ret; return true; } return false; }
int NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { if (NET_GetLoopPacket (sock, net_from, net_message)) return 1; int net_socket = ip_sockets[sock]; if (!net_socket) return 0; struct sockaddr_in from; uint32 fromlen = sizeof(from); int ret = recvfrom (net_socket, net_message->data, net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen); if (ret == -1) { //linux makes this needlessly complex, couldn't just return the source of the error in from, oh no... struct probehdr rcvbuf; struct iovec iov; struct msghdr msg; struct cmsghdr *cmsg; char cbuf[1024]; #ifdef SOCK_EXTENDED_ERR struct sock_extended_err *e; #endif // SOCK_EXTENDED_ERR int err = errno; memset (&rcvbuf, 0, sizeof(rcvbuf)); iov.iov_base = &rcvbuf; iov.iov_len = sizeof (rcvbuf); memset (&from, 0, sizeof(from)); msg.msg_name = (void *)&from; msg.msg_namelen = sizeof (from); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_flags = 0; msg.msg_control = cbuf; msg.msg_controllen = sizeof (cbuf); for (;;) { ret = recvmsg (net_socket, &msg, MSG_ERRQUEUE); if (ret == -1) { if (errno == EWOULDBLOCK || errno == EAGAIN) { if (err == EWOULDBLOCK || err == EAGAIN) { return 0; } else { errno = err; Com_Printf ("NET_GetPacket: %s\n", LOG_NET, NET_ErrorString()); return 0; } } else { Com_DPrintf ("NET_GetPacket: recvmsg(): %s\n", NET_ErrorString()); return 0; } } else if (!ret) { Com_DPrintf ("NET_GetPacket: recvmsg(): EOF\n"); return 0; } errno = err; Com_DPrintf ("NET_GetPacket: Called recvmsg() for extended error details for %s\n", NET_ErrorString()); //linux 2.2 (maybe others) fails to properly fill in the msg_name structure. Com_DPrintf ("(msgname) family %d, host: %s, port: %d, flags: %d\n", from.sin_family, inet_ntoa (from.sin_addr), from.sin_port, msg.msg_flags); #ifdef SOCK_EXTENDED_ERR e = NULL; for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg)) { if (cmsg->cmsg_level == SOL_IP) { if (cmsg->cmsg_type == IP_RECVERR) { e = (struct sock_extended_err *) CMSG_DATA (cmsg); } else Com_DPrintf ("cmsg type = %d\n", cmsg->cmsg_type); } } if (!e) { Com_DPrintf ("NET_GetPacket: recvmsg(): no extended info available\n"); continue; } if (e->ee_origin == SO_EE_ORIGIN_ICMP) { //for some unknown reason, the kernel zeroes out the port in SO_EE_OFFENDER, so this is pretty much useless struct sockaddr_in *sin = (struct sockaddr_in *)SO_EE_OFFENDER(e); Com_DPrintf ("(ICMP) family %d, host: %s, port: %d\n", sin->sin_family, inet_ntoa (sin->sin_addr), sin->sin_port); //but better than nothing if using buggy kernel? if (from.sin_family == AF_UNSPEC) { memcpy (&from, sin, sizeof(from)); //can't trust port, may be buggy kernel (again) from.sin_port = 0; } } else { Com_DPrintf ("NET_GetPacket: recvmsg(): error origin is %d\n", e->ee_origin); continue; } SockadrToNetadr (&from, net_from); switch (e->ee_errno) { case ECONNREFUSED: case EHOSTUNREACH: case ENETUNREACH: Com_Printf ("NET_GetPacket: %s from %s\n", LOG_NET, strerror(e->ee_errno), NET_AdrToString (net_from)); if (net_ignore_icmp->intvalue) return 0; else return -1; default: Com_Printf ("NET_GetPacket: %s from %s\n", LOG_NET, strerror(e->ee_errno), NET_AdrToString (net_from)); continue; } #endif // SOCK_EXTENDED_ERR } //errno = err; //Com_Printf ("NET_GetPacket: %s\n", LOG_NET, NET_ErrorString()); return 0; } net_packets_in++; net_total_in += ret; SockadrToNetadr (&from, net_from); if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", LOG_NET, NET_AdrToString (net_from)); return 0; } net_message->cursize = ret; return 1; }
int NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret; struct sockaddr from; int fromlen; int err; #ifndef DEDICATED_ONLY if (NET_GetLoopPacket (sock, net_from, net_message)) return 1; #endif if (!ip_sockets[sock]) return 0; fromlen = sizeof(from); ret = recvfrom (ip_sockets[sock], (char *)net_message->data, net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen); if (ret == -1) { err = WSAGetLastError(); if (err == WSAEWOULDBLOCK)// || (err == WSAECONNRESET && Com_ServerState())) return 0; if (err == WSAECONNRESET) { if (net_ignore_icmp->intvalue) { return -2; } else { SockadrToNetadr (&from, net_from); return -1; } } #ifndef NO_SERVER if (dedicated->intvalue) // let dedicated servers continue after errors Com_Printf ("NET_GetPacket: %s\n", LOG_NET, NET_ErrorString()); else #endif //r1: WSAEMSGSIZE can be caused by someone UDP packeting a client. //FIXME: somehow get the current clients connected server address // here and if any packets that didn't originate from the server // cause errors, silently ignore them. if (err != WSAEMSGSIZE) Com_Printf ("WARNING! NET_GetPacket: %s\n", LOG_NET, NET_ErrorString()); return 0; } net_packets_in++; net_total_in += ret; SockadrToNetadr (&from, net_from); if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", LOG_NET, NET_AdrToString (net_from)); return 0; } net_message->cursize = ret; return 1; }
qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret; struct sockaddr_in from; int fromlen; int net_socket; int protocol; int err; if (NET_GetLoopPacket (sock, net_from, net_message)) return true; for (protocol = 0 ; protocol < 2 ; protocol++) { if (protocol == 0) net_socket = ip_sockets[sock]; else net_socket = ipx_sockets[sock]; if (!net_socket) continue; fromlen = sizeof(from); // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Switching to the equivalent function (and data structures) in the platform: //ret = recvfrom (net_socket, net_message->data, net_message->maxsize // , 0, (struct sockaddr *)&from, &fromlen); //if (ret == -1) ret = net_recvfrom (net_socket, net_message->data, net_message->maxsize > 4096 ? 4096 : net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen); if (ret < 0) // <<< FIX { // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Switching to the equivalent data structures in the platform: //err = errno; //if (err == EWOULDBLOCK || err == ECONNREFUSED) if (ret == -EWOULDBLOCK || ret == -ECONNREFUSED) // <<< FIX continue; Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); continue; } // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Adjusting for previous fixes: //if (ret == net_message->maxsize) if((ret == net_message->maxsize)||(ret >= 4096)) // <<< FIX { Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from)); continue; } net_message->cursize = ret; SockadrToNetadr (&from, net_from); return true; } return false; }
qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret; struct sockaddr from; int fromlen; int net_socket; int protocol; int err; if (NET_GetLoopPacket (sock, net_from, net_message)) return true; for (protocol = 0 ; protocol < 2 ; protocol++) { if (protocol == 0) net_socket = ip_sockets[sock]; else net_socket = ipx_sockets[sock]; if (!net_socket) continue; fromlen = sizeof(from); ret = recvfrom (net_socket, net_message->data, net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr (&from, net_from); if (ret == -1) { err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) continue; if (err == WSAEMSGSIZE) { Com_Printf (S_COLOR_YELLOW"Warning: Oversize packet from %s\n", NET_AdrToString(*net_from)); continue; } // Knightmare- added Jitspoe's fix for WSAECONNRESET bomb-out if (err == WSAECONNRESET) { Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); // drop this client to not flood the console with above message SV_DropClientFromAdr (*net_from); continue; } //if (dedicated->value) // let dedicated servers continue after errors // let servers continue after errors Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); //else // Com_Error (ERR_DROP, "NET_GetPacket: %s from %s", // NET_ErrorString(), NET_AdrToString(*net_from)); continue; } if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from)); continue; } net_message->cursize = ret; return true; } return false; }