File: NetHandler.h

package info (click to toggle)
bzflag 2.0.13.20080902-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 27,564 kB
  • ctags: 34,716
  • sloc: cpp: 139,842; ansic: 14,510; sh: 10,715; makefile: 2,454; perl: 477; php: 428; python: 345; objc: 243; xml: 24
file content (231 lines) | stat: -rw-r--r-- 6,434 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
/* bzflag
 * Copyright (c) 1993 - 2008 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 LICENSE 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 <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);
  /** 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();
  void		getPlayerList(char *list);
  const char*	getTargetIP();
  int		sizeOfIP();
  void*		packAdminInfo(void *buf);
  static int	whoIsAtIP(const std::string& IP);
  in_addr	getIPAddress();
  const char*	getHostname();
  bool	  reverseDNSDone();

  int getPlayerID ( void ){ return playerIndex;}

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

private:
  int  send(const void *buffer, size_t length);
  void udpSend(const void *b, size_t l);
  int  bufferedSend(const void *buffer, size_t length);
  bool isMyUdpAddrPort(struct sockaddr_in uaddr);
  RxStatus    receive(size_t length);
#ifdef NETWORK_STATS
  void	countMessage(uint16_t code, int len, int direction);
  void	dumpMessageStats();
#endif
  AresHandler	   ares;

  /// On win32, a socket is typedef UINT_PTR SOCKET;
  /// Hopefully int will be ok
  static int		udpSocket;
  static NetHandler*	netPlayer[maxHandlers];
  PlayerInfo*		info;
  struct sockaddr_in	uaddr;
  int			playerIndex;
  /// socket file descriptor
  int			fd;

  /// 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;
  static bool pendingUDP;

  /// 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;

  // 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: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8