GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/sdltcpnet.cpp Lines: 0 41 0.0 %
Date: 2021-03-17 Branches: 0 12 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2013-2019  The ManaPlus Developers
4
 *  Copyright (C) 2019-2021  Andrei Karas
5
 *
6
 *  This file is part of The ManaPlus Client.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "logger.h"
23
24
#if defined __linux__ || defined __linux
25
26
#include <sys/socket.h>
27
28
#if defined(M_TCPOK) && !defined(ANDROID)
29
#include <netinet/in.h>
30
#include <netdb.h>
31
#include <linux/tcp.h>
32
#else  // defined(M_TCPOK) && !defined(ANDROID)
33
#include <netinet/in.h>
34
#include <netinet/tcp.h>
35
#include <netdb.h>
36
#include <netinet/tcp.h>
37
// Use linear timeouts for thin streams
38
#define TCP_THIN_LINEAR_TIMEOUTS 16
39
// Fast retrans. after 1 dupack
40
#define TCP_THIN_DUPACK          17
41
#endif  // defined(M_TCPOK) && !defined(ANDROID)
42
43
#endif  // defined __linux__ || defined __linux
44
45
PRAGMACLANG6GCC(GCC diagnostic push)
46
PRAGMACLANG6GCC(GCC diagnostic ignored "-Wold-style-cast")
47
#include "net/sdltcpnet.h"
48
PRAGMACLANG6GCC(GCC diagnostic pop)
49
50
#include "debug.h"
51
52
#if !defined(__native_client__) \
53
    && (defined(TCP_THIN_LINEAR_TIMEOUTS) \
54
    || defined(TCP_THIN_DUPACK))
55
// because actual struct is hidden in SDL_net we reinroducing it here
56
struct TCPsocketHack final
57
{
58
    TCPsocketHack() :
59
        ready(0),
60
        channel(0),
61
        remoteAddress(),
62
        localAddress(),
63
        sflag()
64
    { }
65
66
    A_DELETE_COPY(TCPsocketHack)
67
68
    int ready;
69
    int channel;
70
    IPaddress remoteAddress;
71
    IPaddress localAddress;
72
    int sflag;
73
};
74
#endif  // !defined(__native_client__)
75
        // && (defined(TCP_THIN_LINEAR_TIMEOUTS)
76
        // || defined(TCP_THIN_DUPACK))
77
78
void TcpNet::init()
79
{
80
    SDLNet_Init();
81
}
82
83
void TcpNet::quit()
84
{
85
    SDLNet_Quit();
86
}
87
88
void TcpNet::closeSocket(const TcpNet::Socket socket)
89
{
90
    SDLNet_TCP_Close(socket);
91
}
92
93
int TcpNet::send(const TcpNet::Socket sock, const void *const data,
94
                 const int len)
95
{
96
    return SDLNet_TCP_Send(sock, data, len);
97
}
98
99
const char *TcpNet::getError()
100
{
101
    return SDL_GetError();
102
}
103
104
int TcpNet::resolveHost(IPaddress *const address, const char *const host,
105
                        const Uint16 port)
106
{
107
    return SDLNet_ResolveHost(address, host, port);
108
}
109
110
TcpNet::Socket TcpNet::open(IPaddress *const ip)
111
{
112
    const TcpNet::Socket sock = SDLNet_TCP_Open(ip);
113
#if !defined(__native_client__) \
114
    && (defined(TCP_THIN_LINEAR_TIMEOUTS) \
115
    || defined(TCP_THIN_DUPACK))
116
    if ((sock != nullptr) && (ip != nullptr))
117
    {
118
        const TCPsocketHack *const hack
119
            = reinterpret_cast<const TCPsocketHack *>(sock);
120
        // here we using some magic to compare TCPsocket and own padding
121
        // because actual struct TCPsocket not in headers
122
        if (hack != nullptr)
123
        {
124
            const IPaddress &addr = hack->remoteAddress;
125
            if (addr.host == ip->host && addr.port == ip->port)
126
            {
127
                const int val = 1;
128
#ifdef TCP_THIN_LINEAR_TIMEOUTS
129
                if (setsockopt(hack->channel, IPPROTO_TCP,
130
                    TCP_THIN_LINEAR_TIMEOUTS, &val, sizeof(val)) != 0)
131
                {
132
                    logger->log_r("error on set TCP_THIN_LINEAR_TIMEOUTS");
133
                }
134
#endif  // TCP_THIN_LINEAR_TIMEOUTS
135
#ifdef TCP_THIN_DUPACK
136
                if (setsockopt(hack->channel, IPPROTO_TCP,
137
                    TCP_THIN_DUPACK, &val, sizeof(val)) != 0)
138
                {
139
                    logger->log_r("error on set TCP_THIN_DUPACK");
140
                }
141
#endif  // TCP_THIN_DUPACK
142
            }
143
        }
144
    }
145
#endif  // !defined(__native_client__)
146
        // && (defined(TCP_THIN_LINEAR_TIMEOUTS)
147
        // || defined(TCP_THIN_DUPACK))
148
    return sock;
149
}
150
151
TcpNet::SocketSet TcpNet::allocSocketSet(const int maxsockets)
152
{
153
    return SDLNet_AllocSocketSet(maxsockets);
154
}
155
156
int TcpNet::addSocket(const TcpNet::SocketSet set, const TcpNet::Socket sock)
157
{
158
    PRAGMACLANG6GCC(GCC diagnostic push)
159
    PRAGMACLANG6GCC(GCC diagnostic ignored "-Wold-style-cast")
160
    return SDLNet_TCP_AddSocket(set, sock);
161
    PRAGMACLANG6GCC(GCC diagnostic pop)
162
}
163
164
int TcpNet::socketReady(const TcpNet::Socket sock)
165
{
166
    PRAGMACLANG5(GCC diagnostic push)
167
    PRAGMACLANG5(GCC diagnostic ignored "-Wzero-as-null-pointer-constant")
168
    PRAGMACLANG6GCC(GCC diagnostic push)
169
    PRAGMACLANG6GCC(GCC diagnostic ignored "-Wold-style-cast")
170
    return SDLNet_SocketReady(sock);
171
    PRAGMACLANG6GCC(GCC diagnostic pop)
172
    PRAGMACLANG5(GCC diagnostic pop)
173
}
174
175
int TcpNet::checkSockets(const TcpNet::SocketSet set, const Uint32 timeout)
176
{
177
    return SDLNet_CheckSockets(set, timeout);
178
}
179
180
int TcpNet::recv(const TcpNet::Socket sock, void *const data, const int maxlen)
181
{
182
    return SDLNet_TCP_Recv(sock, data, maxlen);
183
}
184
185
int TcpNet::delSocket(const TcpNet::SocketSet set, const TcpNet::Socket sock)
186
{
187
    PRAGMACLANG6GCC(GCC diagnostic push)
188
    PRAGMACLANG6GCC(GCC diagnostic ignored "-Wold-style-cast")
189
    return SDLNet_TCP_DelSocket(set, sock);
190
    PRAGMACLANG6GCC(GCC diagnostic pop)
191
}
192
193
void TcpNet::freeSocketSet(const TcpNet::SocketSet set)
194
{
195
    SDLNet_FreeSocketSet(set);
196
}
197
198
TcpNet::Socket TcpNet::accept(const TcpNet::Socket sock)
199
{
200
    return SDLNet_TCP_Accept(sock);
201
}