mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
New try at recvmmsg with some improvements
This commit is contained in:
parent
a3b07dbf9c
commit
9febf58f37
|
@ -1522,29 +1522,80 @@ int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size
|
|||
#endif /* FUZZING */
|
||||
}
|
||||
|
||||
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize)
|
||||
void net_init_mmsgs(MMSGS* m)
|
||||
{
|
||||
#if defined(CONF_PLATFORM_LINUX)
|
||||
m->pos = 0;
|
||||
m->size = 0;
|
||||
mem_zero(m->msgs, sizeof(m->msgs));
|
||||
mem_zero(m->iovecs, sizeof(m->iovecs));
|
||||
mem_zero(m->sockaddrs, sizeof(m->sockaddrs));
|
||||
for(int i = 0; i < VLEN; ++i)
|
||||
{
|
||||
m->iovecs[i].iov_base = m->bufs[i];
|
||||
m->iovecs[i].iov_len = PACKETSIZE;
|
||||
m->msgs[i].msg_hdr.msg_iov = &m->iovecs[i];
|
||||
m->msgs[i].msg_hdr.msg_iovlen = 1;
|
||||
m->msgs[i].msg_hdr.msg_name = &m->sockaddrs[i];
|
||||
m->msgs[i].msg_hdr.msg_namelen = sizeof(&m->sockaddrs[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize, MMSGS* m)
|
||||
{
|
||||
#ifndef FUZZING
|
||||
char sockaddrbuf[128];
|
||||
socklen_t fromlen;// = sizeof(sockaddrbuf);
|
||||
int bytes = 0;
|
||||
|
||||
#if defined(CONF_PLATFORM_LINUX)
|
||||
if(sock.ipv4sock >= 0)
|
||||
{
|
||||
if(m->pos >= m->size)
|
||||
{
|
||||
m->size = recvmmsg(sock.ipv4sock, m->msgs, VLEN, 0, NULL);
|
||||
m->pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(sock.ipv6sock >= 0)
|
||||
{
|
||||
if(m->pos >= m->size)
|
||||
{
|
||||
m->size = recvmmsg(sock.ipv6sock, m->msgs, VLEN, 0, NULL);
|
||||
m->pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(m->pos < m->size)
|
||||
{
|
||||
sockaddr_to_netaddr((struct sockaddr *)&(m->sockaddrs[m->pos]), addr);
|
||||
// TODO: network_stats
|
||||
//network_stats.recv_bytes += bytes;
|
||||
//network_stats.recv_packets++;
|
||||
bytes = m->msgs[m->pos].msg_len;
|
||||
mem_copy(data, m->bufs[m->pos], bytes);
|
||||
m->pos++;
|
||||
return bytes;
|
||||
}
|
||||
#else
|
||||
if(bytes == 0 && sock.ipv4sock >= 0)
|
||||
{
|
||||
fromlen = sizeof(struct sockaddr_in);
|
||||
int fromlen = sizeof(struct sockaddr_in);
|
||||
bytes = recvfrom(sock.ipv4sock, (char*)data, maxsize, 0, (struct sockaddr *)&sockaddrbuf, &fromlen);
|
||||
}
|
||||
|
||||
if(bytes <= 0 && sock.ipv6sock >= 0)
|
||||
{
|
||||
fromlen = sizeof(struct sockaddr_in6);
|
||||
int fromlen = sizeof(struct sockaddr_in6);
|
||||
bytes = recvfrom(sock.ipv6sock, (char*)data, maxsize, 0, (struct sockaddr *)&sockaddrbuf, &fromlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONF_WEBSOCKETS)
|
||||
if(bytes <= 0 && sock.web_ipv4sock >= 0)
|
||||
{
|
||||
fromlen = sizeof(struct sockaddr);
|
||||
int fromlen = sizeof(struct sockaddr);
|
||||
bytes = websocket_recv(sock.web_ipv4sock, data, maxsize, (struct sockaddr_in *)&sockaddrbuf, fromlen);
|
||||
((struct sockaddr_in *)&sockaddrbuf)->sin_family = AF_WEBSOCKET_INET;
|
||||
}
|
||||
|
@ -1560,7 +1611,7 @@ int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize)
|
|||
else if(bytes == 0)
|
||||
return 0;
|
||||
return -1; /* error */
|
||||
#else
|
||||
#else /* ifdef FUZZING */
|
||||
addr->type = NETTYPE_IPV4;
|
||||
addr->port = 11111;
|
||||
addr->ip[0] = 127;
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
#define BASE_SYSTEM_H
|
||||
|
||||
#include "detect.h"
|
||||
|
||||
#ifndef __USE_GNU
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
@ -17,6 +22,10 @@
|
|||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONF_PLATFORM_LINUX
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -747,6 +756,22 @@ NETSOCKET net_udp_create(NETADDR bindaddr);
|
|||
*/
|
||||
int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size);
|
||||
|
||||
#define VLEN 128
|
||||
#define PACKETSIZE 1400
|
||||
typedef struct
|
||||
{
|
||||
#ifdef CONF_PLATFORM_LINUX
|
||||
int pos;
|
||||
int size;
|
||||
struct mmsghdr msgs[VLEN];
|
||||
struct iovec iovecs[VLEN];
|
||||
char bufs[VLEN][PACKETSIZE];
|
||||
char sockaddrs[VLEN][128];
|
||||
#endif
|
||||
} MMSGS;
|
||||
|
||||
void net_init_mmsgs(MMSGS* m);
|
||||
|
||||
/*
|
||||
Function: net_udp_recv
|
||||
Receives a packet over an UDP socket.
|
||||
|
@ -761,7 +786,7 @@ int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size
|
|||
On success it returns the number of bytes received. Returns -1
|
||||
on error.
|
||||
*/
|
||||
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize);
|
||||
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize, MMSGS* m);
|
||||
|
||||
/*
|
||||
Function: net_udp_close
|
||||
|
|
|
@ -2031,6 +2031,13 @@ int CServer::Run()
|
|||
int64 t = time_get();
|
||||
int x = (TickStartTime(m_CurrentGameTick+1) - t) * 1000000 / time_freq() + 1;
|
||||
|
||||
if(x > 3000)
|
||||
{
|
||||
// at least sleep 3 ms, reduce number of syscalls in stress situations
|
||||
thread_sleep(3);
|
||||
x = (TickStartTime(m_CurrentGameTick+1) - t) * 1000000 / time_freq() + 1;
|
||||
}
|
||||
|
||||
if(x > 0)
|
||||
{
|
||||
net_socket_read_wait(m_NetServer.Socket(), x);
|
||||
|
|
|
@ -301,6 +301,7 @@ class CNetServer
|
|||
};
|
||||
|
||||
NETSOCKET m_Socket;
|
||||
MMSGS m_MMSGS;
|
||||
class CNetBan *m_pNetBan;
|
||||
CSlot m_aSlots[NET_MAX_CLIENTS];
|
||||
int m_MaxClients;
|
||||
|
@ -423,6 +424,7 @@ class CNetClient
|
|||
CNetRecvUnpacker m_RecvUnpacker;
|
||||
public:
|
||||
NETSOCKET m_Socket;
|
||||
MMSGS m_MMSGS;
|
||||
// openness
|
||||
bool Open(NETADDR BindAddr, int Flags);
|
||||
int Close();
|
||||
|
|
|
@ -17,6 +17,8 @@ bool CNetClient::Open(NETADDR BindAddr, int Flags)
|
|||
// init
|
||||
m_Socket = Socket;
|
||||
m_Connection.Init(m_Socket, false);
|
||||
net_init_mmsgs(&m_MMSGS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -64,7 +66,7 @@ int CNetClient::Recv(CNetChunk *pChunk)
|
|||
|
||||
// TODO: empty the recvinfo
|
||||
NETADDR Addr;
|
||||
int Bytes = net_udp_recv(m_Socket, &Addr, m_RecvUnpacker.m_aBuffer, NET_MAX_PACKETSIZE);
|
||||
int Bytes = net_udp_recv(m_Socket, &Addr, m_RecvUnpacker.m_aBuffer, NET_MAX_PACKETSIZE, &m_MMSGS);
|
||||
|
||||
// no more packets for now
|
||||
if(Bytes <= 0)
|
||||
|
|
|
@ -80,6 +80,8 @@ bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int Ma
|
|||
for(int i = 0; i < NET_MAX_CLIENTS; i++)
|
||||
m_aSlots[i].m_Connection.Init(m_Socket, true);
|
||||
|
||||
net_init_mmsgs(&m_MMSGS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -598,7 +600,7 @@ int CNetServer::Recv(CNetChunk *pChunk)
|
|||
return 1;
|
||||
|
||||
// TODO: empty the recvinfo
|
||||
int Bytes = net_udp_recv(m_Socket, &Addr, m_RecvUnpacker.m_aBuffer, NET_MAX_PACKETSIZE);
|
||||
int Bytes = net_udp_recv(m_Socket, &Addr, m_RecvUnpacker.m_aBuffer, NET_MAX_PACKETSIZE, &m_MMSGS);
|
||||
|
||||
// no more packets for now
|
||||
if(Bytes <= 0)
|
||||
|
|
Loading…
Reference in a new issue