GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/sdltcpnet.cpp Lines: 0 41 0.0 %
Date: 2017-11-29 Branches: 0 16 0.0 %

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