Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/miniupnpc/src/receivedata.c
9904 views
1
/* $Id: receivedata.c,v 1.11 2025/05/25 21:56:49 nanard Exp $ */
2
/* Project : miniupnp
3
* Website : http://miniupnp.free.fr/
4
* Author : Thomas Bernard
5
* Copyright (c) 2011-2025 Thomas Bernard
6
* This software is subject to the conditions detailed in the
7
* LICENCE file provided in this distribution. */
8
9
#include <stdio.h>
10
#include <string.h>
11
#ifdef _WIN32
12
#define WIN32_LEAN_AND_MEAN
13
#include <winsock2.h>
14
#include <ws2tcpip.h>
15
#else /* _WIN32 */
16
#include <unistd.h>
17
#if defined(__amigaos__) && !defined(__amigaos4__)
18
#define socklen_t int
19
#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
20
#include <sys/select.h>
21
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
22
#include <sys/socket.h>
23
#include <netinet/in.h>
24
#if !defined(__amigaos__) && !defined(__amigaos4__)
25
#include <poll.h>
26
#endif /* !defined(__amigaos__) && !defined(__amigaos4__) */
27
#include <errno.h>
28
#define MINIUPNPC_IGNORE_EINTR
29
#endif /* _WIN32 */
30
31
#include "receivedata.h"
32
33
int
34
receivedata(SOCKET socket,
35
char * data, int length,
36
int timeout, unsigned int * scope_id)
37
{
38
#ifdef MINIUPNPC_GET_SRC_ADDR
39
struct sockaddr_storage src_addr;
40
socklen_t src_addr_len = sizeof(src_addr);
41
#endif /* MINIUPNPC_GET_SRC_ADDR */
42
int n;
43
#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
44
/* using poll */
45
struct pollfd fds[1]; /* for the poll */
46
#ifdef MINIUPNPC_IGNORE_EINTR
47
do {
48
#endif /* MINIUPNPC_IGNORE_EINTR */
49
fds[0].fd = socket;
50
fds[0].events = POLLIN;
51
n = poll(fds, 1, timeout);
52
#ifdef MINIUPNPC_IGNORE_EINTR
53
} while(n < 0 && errno == EINTR);
54
#endif /* MINIUPNPC_IGNORE_EINTR */
55
if(n < 0) {
56
PRINT_SOCKET_ERROR("poll");
57
return -1;
58
} else if(n == 0) {
59
/* timeout */
60
return 0;
61
}
62
#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
63
/* using select under _WIN32 and amigaos */
64
fd_set socketSet;
65
TIMEVAL timeval;
66
FD_ZERO(&socketSet);
67
FD_SET(socket, &socketSet);
68
timeval.tv_sec = timeout / 1000;
69
timeval.tv_usec = (timeout % 1000) * 1000;
70
n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
71
if(n < 0) {
72
PRINT_SOCKET_ERROR("select");
73
return -1;
74
} else if(n == 0) {
75
return 0;
76
}
77
#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
78
#ifdef MINIUPNPC_GET_SRC_ADDR
79
memset(&src_addr, 0, sizeof(src_addr));
80
n = recvfrom(socket, data, length, 0,
81
(struct sockaddr *)&src_addr, &src_addr_len);
82
#else /* MINIUPNPC_GET_SRC_ADDR */
83
n = recv(socket, data, length, 0);
84
#endif /* MINIUPNPC_GET_SRC_ADDR */
85
if(n<0) {
86
PRINT_SOCKET_ERROR("recv");
87
}
88
#ifdef MINIUPNPC_GET_SRC_ADDR
89
if (src_addr.ss_family == AF_INET6) {
90
const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr;
91
#ifdef DEBUG
92
printf("scope_id=%u\n", src_addr6->sin6_scope_id);
93
#endif /* DEBUG */
94
if(scope_id)
95
*scope_id = src_addr6->sin6_scope_id;
96
} else {
97
if(scope_id)
98
*scope_id = 0;
99
}
100
#else /* MINIUPNPC_GET_SRC_ADDR */
101
if(scope_id)
102
*scope_id = 0;
103
#endif /* MINIUPNPC_GET_SRC_ADDR */
104
return n;
105
}
106
107
108