summaryrefslogtreecommitdiff
path: root/src/net/sdltcpnet.cpp
blob: 6ad35000210691a526f6c2a7fc3b4a9b40826278 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 *  The ManaPlus Client
 *  Copyright (C) 2013  The ManaPlus Developers
 *
 *  This file is part of The ManaPlus Client.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "net/sdltcpnet.h"

#if defined __linux__ || defined __linux
#include <sys/socket.h>
#include <linux/tcp.h>
#include <netdb.h>
#endif

#include "debug.h"

// because actual struct is hidden in SDL_net we reinroducing it here
struct TCPsocketHack {
    int ready;
    int channel;
    IPaddress remoteAddress;
    IPaddress localAddress;
    int sflag;
};

void TcpNet::init()
{
    SDLNet_Init();
}

void TcpNet::quit()
{
    SDLNet_Quit();
}

void TcpNet::closeSocket(TcpNet::Socket socket)
{
    SDLNet_TCP_Close(socket);
}

int TcpNet::send(TcpNet::Socket sock, const void *data, int len)
{
    return SDLNet_TCP_Send(sock, data, len);
}

char *TcpNet::getError()
{
    return SDLNet_GetError();
}

int TcpNet::resolveHost(IPaddress *address, const char *host, Uint16 port)
{
    return SDLNet_ResolveHost(address, host, port);
}

#include "logger.h"

TcpNet::Socket TcpNet::open(IPaddress *ip)
{
    TcpNet::Socket sock = SDLNet_TCP_Open(ip);
    if (sock && ip)
    {
        TCPsocketHack *hack = reinterpret_cast<TCPsocketHack *>(sock);
        // here we using some magic to compare TCPsocket and own padding
        // because actual struct TCPsocket not in headers
        if (hack)
        {
            const IPaddress &addr = hack->remoteAddress;
            if (addr.host == ip->host && addr.port == ip->port)
            {
                const int val = 1;
#ifdef TCP_THIN_LINEAR_TIMEOUTS
                if (setsockopt(hack->channel, IPPROTO_TCP,
                    TCP_THIN_LINEAR_TIMEOUTS, &val, sizeof(val)))
                {
                    logger->log1("error on set TCP_THIN_LINEAR_TIMEOUTS");
                }
#endif
#ifdef TCP_THIN_DUPACK
                if (setsockopt(hack->channel, IPPROTO_TCP,
                    TCP_THIN_DUPACK, &val, sizeof(val)))
                {
                    logger->log1("error on set TCP_THIN_DUPACK");
                }
#endif
            }
        }
    }
    return sock;
}

TcpNet::SocketSet TcpNet::allocSocketSet(int maxsockets)
{
    return SDLNet_AllocSocketSet(maxsockets);
}

int TcpNet::addSocket(TcpNet::SocketSet set, TcpNet::Socket sock)
{
    return SDLNet_TCP_AddSocket(set, sock);
}

int TcpNet::checkSockets(TcpNet::SocketSet set, Uint32 timeout)
{
    return SDLNet_CheckSockets(set, timeout);
}

int TcpNet::recv(TcpNet::Socket sock, void *data, int maxlen)
{
    return SDLNet_TCP_Recv(sock, data, maxlen);
}

int TcpNet::delSocket(TcpNet::SocketSet set, TcpNet::Socket sock)
{
    return SDLNet_TCP_DelSocket(set, sock);
}

void TcpNet::freeSocketSet(TcpNet::SocketSet set)
{
    SDLNet_FreeSocketSet(set);
}