|
@@ -988,18 +988,61 @@ public:
|
|
break;
|
|
break;
|
|
|
|
|
|
case ZT_PHY_SOCKET_UDP:
|
|
case ZT_PHY_SOCKET_UDP:
|
|
- if (FD_ISSET(s->sock,&rfds)) {
|
|
|
|
- for(int k=0;k<1024;++k) {
|
|
|
|
- memset(&ss,0,sizeof(ss));
|
|
|
|
|
|
+ if (FD_ISSET(s->sock, &rfds)) {
|
|
|
|
+#if (defined(__linux__) || defined(linux) || defined(__linux)) && defined(MSG_WAITFORONE)
|
|
|
|
+#define RECVMMSG_WINDOW_SIZE 128
|
|
|
|
+#define RECVMMSG_BUF_SIZE 1500
|
|
|
|
+ iovec iovs[RECVMMSG_WINDOW_SIZE];
|
|
|
|
+ uint8_t bufs[RECVMMSG_WINDOW_SIZE][RECVMMSG_BUF_SIZE];
|
|
|
|
+ sockaddr_storage addrs[RECVMMSG_WINDOW_SIZE];
|
|
|
|
+ memset(addrs, 0, sizeof(addrs));
|
|
|
|
+ mmsghdr mm[RECVMMSG_WINDOW_SIZE];
|
|
|
|
+ memset(mm, 0, sizeof(mm));
|
|
|
|
+ for (int i = 0; i < RECVMMSG_WINDOW_SIZE; ++i) {
|
|
|
|
+ iovs[i].iov_base = (void*)bufs[i];
|
|
|
|
+ iovs[i].iov_len = RECVMMSG_BUF_SIZE;
|
|
|
|
+ mm[i].msg_hdr.msg_name = (void*)&(addrs[i]);
|
|
|
|
+ mm[i].msg_hdr.msg_iov = &(iovs[i]);
|
|
|
|
+ mm[i].msg_hdr.msg_iovlen = 1;
|
|
|
|
+ }
|
|
|
|
+ for (int k = 0; k < 1024; ++k) {
|
|
|
|
+ for (int i = 0; i < RECVMMSG_WINDOW_SIZE; ++i) {
|
|
|
|
+ mm[i].msg_hdr.msg_namelen = sizeof(sockaddr_storage);
|
|
|
|
+ mm[i].msg_len = 0;
|
|
|
|
+ }
|
|
|
|
+ int received_count = recvmmsg(s->sock, mm, RECVMMSG_WINDOW_SIZE, MSG_WAITFORONE, nullptr);
|
|
|
|
+ if (received_count > 0) {
|
|
|
|
+ for (int i = 0; i < received_count; ++i) {
|
|
|
|
+ long n = (long)mm[i].msg_len;
|
|
|
|
+ if (n > 0) {
|
|
|
|
+ try {
|
|
|
|
+ _handler->phyOnDatagram((PhySocket*)&(*s), &(s->uptr), (const struct sockaddr*)&(s->saddr), (const struct sockaddr*)&(addrs[i]), bufs[i], (unsigned long)n);
|
|
|
|
+ }
|
|
|
|
+ catch (...) {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#else
|
|
|
|
+ for (int k = 0; k < 1024; ++k) {
|
|
|
|
+ memset(&ss, 0, sizeof(ss));
|
|
socklen_t slen = sizeof(ss);
|
|
socklen_t slen = sizeof(ss);
|
|
- long n = (long)::recvfrom(s->sock,buf,sizeof(buf),0,(struct sockaddr *)&ss,&slen);
|
|
|
|
|
|
+ long n = (long)::recvfrom(s->sock, buf, sizeof(buf), 0, (struct sockaddr*)&ss, &slen);
|
|
if (n > 0) {
|
|
if (n > 0) {
|
|
try {
|
|
try {
|
|
- _handler->phyOnDatagram((PhySocket *)&(*s),&(s->uptr),(const struct sockaddr *)&(s->saddr),(const struct sockaddr *)&ss,(void *)buf,(unsigned long)n);
|
|
|
|
- } catch ( ... ) {}
|
|
|
|
- } else if (n < 0)
|
|
|
|
|
|
+ _handler->phyOnDatagram((PhySocket*)&(*s), &(s->uptr), (const struct sockaddr*)&(s->saddr), (const struct sockaddr*)&ss, (void*)buf, (unsigned long)n);
|
|
|
|
+ }
|
|
|
|
+ catch (...) {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (n < 0)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
|