This file is indexed.

/usr/include/gnelib/PingPacket.h is in libgnelib-dev 0.75+svn20091130-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
#ifndef _PINGPACKET_H_
#define _PINGPACKET_H_

/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001-2006 Jason Winnebeck 
 * Project website: http://www.gillius.org/gne/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <gnelib/Packet.h>
#include <gnelib/Mutex.h>
#include <gnelib/Time.h>
#include <map>

namespace GNE {

/**
 * @ingroup midlevel
 *
 * Information returned by GNE::PingPacket::getPingInformation.
 */
struct PingInformation {
  PingInformation() : pingTime(0, 0), clockOffset(0, 0) {}
  
  /**
   * Round-trip ping time.
   */
  Time pingTime;

  /**
   * Clock offset.
   */
  Time clockOffset;
};

/**
 * @ingroup midlevel
 *
 * Using the PingPacket is one way to measure ping and clock offsets from a
 * remote machine.  Measuring ping and clock offset are very similar operations
 * in how they work, and because the extra overhead of measuring clock offset
 * is small, that functionality was added into PingPacket.  The effectiveness
 * of the clock synchronization is discussed in the GNE Protocol specification,
 * available on the GNE web site. Ping capability was not integrated into the
 * Connection class to give you the largest flexibility on how to measure
 * latency and ping in your games.
 *
 * A choice had to be made between synchronizing actual real clock times, or
 * synchronizing on an arbitrary server clock. Due to the fact that absolute
 * time clocks have less resolution in some platforms (ie Windows), and
 * because of possible difficulties surrounding differing timezones and
 * GMT-UTC differences, the clock synchronization will be based on an
 * arbitrary clock on the server. This allows the server to use the clock with
 * the highest resolution, and perhaps more importantly, the server can use
 * the same clock for synchronizing and for timing the game logic. The
 * important part to know from this is that the clock offsets may be extreme
 * (as GMT is used in Linux, and seconds since CPU powerup in Windows), and
 * thus may not fit into a 32-bit integer with microsecond accuracy.
 *
 * Since the PingPackets will be placed into the queue and received as
 * normal, this will be measuring effective ping rather than the actual time
 * it takes for the packet to travel there and back, giving a more realistic
 * view of lag.
 *
 * The way to use PingPackets:
 * <ul>
 *   <li>Create a new PingPacket.  The constructor will make a ping request
 *       with the proper unique request ID.</li>
 *   <li>Send the packet to whoever you want, any way you want.</li>
 *   <li>When reading the incoming packet stream, check for PingPackets.<br>
 *       Discover if they are requests or replies by calling isRequest.<br>
 *       If they are requests, call makeReply and send it back.<br>
 *       If they are replies, call getPing to measure the round trip time.</li>
 *   <li>If you send packets over an unreliable connection, call
 *       recoverLostRequests to declare late packets as "lost" and recover any
 *       used memory in the request table.</li>
 * </ul>
 *
 * Check out the exping example for an example and more explanation on how
 * to use PingPacket.
 */
class PingPacket : public Packet {
public: //typedefs
  typedef SmartPtr<PingPacket> sptr;
  typedef WeakPtr<PingPacket> wptr;

public:
  /**
   * Creates a PingPacket with a preassigned request ID which is pulled from
   * an internal source.  Only ping requests are made using the constructor --
   * you should use getReply when you get a ping request to make the ping
   * response packet.
   *
   * The PingPacket::create function passes in false to get an uninitialized
   * PingPacket for reading.  You will probably only ever use the default
   * form of the constructor.  If you pass false, the state of this object is
   * undefined after creation and is suitable only to use readPacket on.
   */
  PingPacket(bool makeReq = true);

  virtual ~PingPacket();

  /**
   * The ID for this type of packet.
   */
  static const int ID;

  /**
   * Is this PingPacket a ping request?
   */
  bool isRequest() const;

  /**
   * Changes this PingPacket from a ping request to a ping reply.  If the
   * PingPacket is already a reply, this function has no net effect.
   */
  void makeReply();

  /**
   * If this packet is a ping reply that is from one of our requests, this
   * finds the round-trip time and clock offset.  Calling this function will
   * remove the request ID from the request table, so this function will only
   * work once for each reply.  If the request ID was not found, then times
   * of 0 will be returned.
   */
  PingInformation getPingInformation();

  /**
   * Every time you create a packet, the request ID is placed into a request
   * table so that the time difference can be measured later.  This takes up
   * some memory.  It is possible that a ping reply is never received,
   * especially if sending PingPackets over an unreliable connection.  This
   * function will remove any packets that have been pending for longer than
   * the time specified.  It will return the number of packets that were
   * considered lost based on the specified pending time limit and remove
   * these requests from the table.  If a reply for one of these lost
   * requests comes back, getPing will be unable to find them and return an
   * elapsed time of 0.
   *
   * When GNE is shutdown the request table will be cleared out so you don't
   * have to ever call this function unless you want to find out how many
   * more packets have been lost, or if you want to free some memory.
   */
  static int recoverLostRequests(Time limit);

  /**
   * Returns the number of pending requests.  This number increases by 1
   * every time a request is made, and goes down by one with a successful
   * call to getPing.  The number will also decrease if recoverLostReqests
   * is called and finds late requests.
   */
  static int reqsPending();

  /**
   * Returns the current size of this packet in bytes.
   */
  virtual int getSize() const;

  /**
   * Writes the packet to the given Buffer. 
   */
  virtual void writePacket(Buffer& raw) const;

  /**
   * Reads this packet from the given Buffer.
   */
  virtual void readPacket(Buffer& raw);

  /**
   * Returns a new instance of this class using the constructor to pass in
   * false, so this returns an object in an uninitialized state and suitable
   * only to call readPacket on.
   */
  static Packet* create();

private:
  guint32 reqId;

  /**
   * This is the time the remote end received the packet.
   */
  Time T2;

  /**
   * This is the time the remote end sent the reply.
   */
  Time T3;

  //Provides synchronization for nextReqId and requests
  static Mutex sync;

  static guint32 nextReqId;

  static std::map<guint32, Time> requests;
};

}
#endif