File: NetHandler.h

package info (click to toggle)
bzflag 2.4.30-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 26,488 kB
  • sloc: cpp: 150,376; ansic: 3,463; sh: 2,535; makefile: 2,194; perl: 486; python: 260; objc: 246; php: 206
file content (279 lines) | stat: -rw-r--r-- 7,713 bytes parent folder | download
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/* bzflag
 * Copyright (c) 1993-2025 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef __NETHANDLER_H__
#define __NETHANDLER_H__

/* common header */
#include "common.h"

/* system headers */
#include <memory>
#include <string>
#include <map>

/* common interface headers */
#include "PlayerInfo.h"
#include "Address.h"
#include "AresHandler.h"

enum RxStatus
{
    ReadAll,
    ReadPart,
    ReadHuge,
    ReadReset,
    ReadError,
    ReadDiscon
};

class NetworkDataLogCallback
{
public:
    virtual ~NetworkDataLogCallback() {};

    virtual void networkDataLog ( bool send, bool udp, const unsigned char *data, unsigned int size,
                                  void* param = NULL ) = 0;
};

void addNetworkLogCallback(NetworkDataLogCallback * cb );
void removeNetworkLogCallback(NetworkDataLogCallback * cb );

const int maxHandlers = LastRealPlayer;

#ifdef DEBUG
#define NETWORK_STATS
#endif
#ifdef NETWORK_STATS
struct MessageCount
{
    uint32_t count;
    uint16_t maxSize;
};
#endif

/** This class is a client that connects to a BZFlag client and has
    functions for sending and receiving messages.
*/
class NetHandler
{
public:
    /** A default constructor.
        It needs a pointer to the Player basic Info,
        a socket address to address subsequent message at user,
        a player Index, a unique pointer to a player
        the file descriptor for the TCP connection with the user.
    */
    NetHandler(PlayerInfo *_info, const struct sockaddr_in &_clientAddr,
               int _playerIndex, int _fd);

    NetHandler(const struct sockaddr_in &_clientAddr, int _fd);

    /** The default destructor
        free all internal resources, and close the tcp connection
    */
    ~NetHandler();

    /** Class-Wide initialization and destruction
        Should be called before any other operation on any clas instance
        InitHandlers needs the addr structure filled to point to the local port
        needed for udp communications
    */
    static bool   initHandlers(struct sockaddr_in addr);
    static void   destroyHandlers();

    /// General function to support the select statement
    static void   setFd(fd_set *read_set, fd_set *write_set, int &maxFile);
    static bool   isUdpFdSet(fd_set *read_set);
    bool      isFdSet(fd_set *set);

    /// Supporting DNS Asynchronous resolver
    static void   checkDNS(fd_set *read_set, fd_set *write_set);

    /// return the opened socket, usable from all other network internal client
    static int    getUdpSocket();


    /**
        udpReceive will try to get the next udp message received

        return the playerIndex if found, -1 when no player had an open udp
        connection or -2 when a Ping Code Request has been detected.

        buffer is the received message

        uaddr is the identifier of the remote address

        udpLinkRequest report if the received message is a valid udpLinkRequest
    */
    static int    udpReceive(char *buffer, struct sockaddr_in *uaddr,
                             bool &udpLinkRequest);

    /**
       tcpReceive try to get a message from the tcp connection
       the message can be accessed by using the getTcpBuffer methods
       result value indicates:
       ReadAll    : was successfully received a full message
       ReadPart   : only part of a message has been retrieved
       ReadHuge   : length of the message is too long
       ReadReset  : a reset of the connection has been detected
       ReadError  : Error detected on the tcp connection
       ReadDiscon : Peer has closed the connection
    */
    RxStatus  tcpReceive();
    void      *getTcpBuffer();

    /// Request if there is any buffered udp messages waiting to be sent
    static bool   anyUDPPending()
    {
        return pendingUDP;
    };

    /// Send all buffered UDP messages, if any
    void      flushUDP();
    static void   flushAllUDP();

    int       pwrite(const void *b, int l);
    int       pflush(fd_set *set);
    std::string   reasonToKick();
    const std::string getPlayerHostInfo();
    const char*   getTargetIP();
    int       sizeOfIP();
    void*     packAdminInfo(void *buf);
    static int    whoIsAtIP(const std::string& IP);
    in_addr   getIPAddress();
    const char*   getHostname();
    bool      reverseDNSDone();

    size_t    getTcpReadSize ()
    {
        return tcplen;
    }
    bool      hasTcpOutbound()
    {
        return outmsgSize > 0;
    }

    void      setPlayer ( PlayerInfo* p, int index );

    int       getPlayerID ( void )
    {
        return playerIndex;
    }

    int       getFD ( void )
    {
        return fd;
    }
    struct sockaddr_in    getUADDR ( void )
    {
        return uaddr;
    }

    // Returns the time that the connection was accepted
    TimeKeeper    getTimeAccepted( void ) const
    {
        return time;
    }

    /// Notify that the channel is going to be close.
    /// In the meantime any pwrite call will do nothing.
    /// Cannot be undone.
    void      closing();

    RxStatus  receive(size_t length, bool* retry = NULL);
    void      flushData ( void )
    {
        tcplen = 0;
    }
    int       bufferedSend(const void *buffer, size_t length);

    void      SetAllowUDP(bool set);
private:
    int       send(const void *buffer, size_t length);
    void      udpSend(const void *b, size_t l);
    bool      isMyUdpAddrPort(struct sockaddr_in uaddr);
#ifdef NETWORK_STATS
    void      countMessage(uint16_t code, int len, int direction);
    void      dumpMessageStats();
#endif
    /// On win32, a socket is typedef UINT_PTR SOCKET;
    /// Hopefully int will be ok
    static int    udpSocket;
    static NetHandler*    netPlayer[maxHandlers];
    static bool   pendingUDP;

    AresHandler   *ares;

    PlayerInfo*   info;
    struct sockaddr_in    uaddr;
    int       playerIndex;
    int       fd; // socket file descriptor

    /// peer's network address
    Address   peer;
    /* peer->getDotNotation returns a temp variable that is not safe
     * to pass around.  This variable lets us keep a copy in allocated
     * memory for as long as we need to */
    std::string   dotNotation;

    /// input buffers
    /// current TCP msg
    char      tcpmsg[MaxPacketLen];
    /// bytes read in current msg
    int       tcplen;

    /// Closing flag
    bool      closed;

    /// output buffer
    int       outmsgOffset;
    int       outmsgSize;
    int       outmsgCapacity;
    char*     outmsg;

    char      udpOutputBuffer[MaxPacketLen];
    int       udpOutputLen;

    /// UDP connection
    bool      udpin; // udp inbound up, player is sending us udp
    bool      udpout; // udp outbound up, we can send udp

    bool      toBeKicked;
    std::string   toBeKickedReason;

    bool      acceptUDP;
    // time accepted
    TimeKeeper    time;
#ifdef NETWORK_STATS
    // message stats bloat
    TimeKeeper    perSecondTime[2];
    uint32_t  perSecondCurrentBytes[2];
    uint32_t  perSecondMaxBytes[2];
    uint32_t  perSecondCurrentMsg[2];
    uint32_t  perSecondMaxMsg[2];
    uint32_t  msgBytes[2];

    typedef   std::map<const uint16_t, struct MessageCount> MessageCountMap;
    MessageCountMap   msg[2];
#endif
};

#endif

// Local Variables: ***
// mode: C++ ***
// tab-width: 4 ***
// c-basic-offset: 4 ***
// indent-tabs-mode: nil ***
// End: ***
// ex: shiftwidth=4 tabstop=4