File: connection.h

package info (click to toggle)
latd 1.34
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,904 kB
  • ctags: 1,090
  • sloc: cpp: 8,485; sh: 879; makefile: 89
file content (196 lines) | stat: -rw-r--r-- 6,336 bytes parent folder | download | duplicates (4)
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
/******************************************************************************
    (c) 2000-2009 Christine Caulfield                 christine.caulfield@googlemail.com

    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.
******************************************************************************/


class LATConnection
{
 public:

    typedef enum {REPLY, DATA, CONTINUATION} send_type;
    static const unsigned int MAX_SESSIONS = 254;
    static const unsigned int MAX_REPLIES = 254;

    LATConnection(int _num, unsigned char *buf, int len,
		  int _interface,
		  unsigned char _seq,
		  unsigned char _ack,
		  unsigned char *_macaddr);
    ~LATConnection();
    bool process_session_cmd(unsigned char *, int, unsigned char *);
    void send_connect_ack();
    int  send_message(unsigned char *, int, send_type);
    int  queue_message(unsigned char *, int);
    int  add_data_slots(int start_slot, LAT_SlotCmd *slots[4]);
    void send_slot_message(unsigned char *, int);
    void circuit_timer();
    void remove_session(unsigned char);


    // Client session routines
    LATConnection(int _num,
		  const char *_service, const char *_portname,
		  const char *_lta, const char *remnode,
		  bool queued, bool clean);
    int connect(class LATSession *);
    int rev_connect();
    int create_llogin_session(int, const char *service, const char *port, const char *localport, const char *password);
    int create_reverse_session(const char *, const char *, int, int,
			      unsigned char *);
    int create_localport_session(int, class LocalPort *, const char *service,
				 const char *port, const char *localport,
				 const char *password);
    int disconnect_client();              // From LATServer
    int got_connect_ack(unsigned char *); // Callback from LATServer
    bool isClient() { return role==CLIENT;}
    const char *getLocalPortName() { return lta_name; }
    int get_connection_id() { return num;}
    void got_status(unsigned char *node, LAT_StatusEntry *entry);
    bool node_is(const char *node) { return strcmp(node, (char *)remnode)==0;}
    unsigned int  num_clients();
    const char *get_servicename() { return (const char *)servicename; }

 private:
    int            num;           // Local connection ID
    int            interface;     // Ethernet i/f we are using
    int            remote_connid; // Remote Connection ID
    int            keepalive_timer; // Counting up.
    unsigned char  last_sent_seq;
    unsigned char  last_sent_ack;
    unsigned char  last_recv_seq;
    unsigned char  last_recv_ack;
    unsigned int   next_session;
    unsigned int   highest_session;
    unsigned char  macaddr[6];
    unsigned char  servicename[255];
    unsigned char  portname[255];
    unsigned char  remnode[255];
    unsigned long  last_time;
    LATSession    *sessions[256];

    bool           need_ack;           // The message we last sent requires an ACK
    bool           queued;             // Client for queued connection.
    bool           eightbitclean;
    bool           connected;
    bool           connecting;
    bool           delete_pending;
    unsigned short request_id;         // For incoming reverse-LATs

    // Keep track of non-flow-controlled messages
    time_t         last_msg_time;
    int            last_msg_type;
    int            last_msg_retries;

    int next_session_number();
    bool is_queued_reconnect(unsigned char *buf, int len, int *conn);

    enum {CLIENT, SERVER} role;

    // A class for keeping pending messages.
    class pending_msg
    {
    public:
      pending_msg() {}
      pending_msg(unsigned char *_buf, int _len, bool _need_ack):
	  len(_len),
	  need_ack(_need_ack)
	{
	    memcpy(buf, _buf, len);
	}
      pending_msg(const pending_msg &msg):
	  len(msg.len),
	  need_ack(msg.need_ack)
      {
	  memcpy(buf, msg.buf, len);
      }
      ~pending_msg()
       {
       }

      pending_msg &operator=(const pending_msg &a)
      {
	  if (&a != this)
	  {
	      len = a.len;
	      need_ack = a.need_ack;
	      memcpy(buf, a.buf, len);
	  }
	  return *this;
      }

      int send(int interface, unsigned char *macaddr);
      int send(int interface, unsigned char ack, unsigned char *macaddr)
      {
	  LAT_Header *header = (LAT_Header *)buf;
	  header->ack_number = ack;
	  return send(interface, macaddr);
      }
      LAT_Header *get_header() { return (LAT_Header *)buf;}
      bool needs_ack() { return need_ack;}
      unsigned char get_seq() { LAT_Header *h=(LAT_Header *)buf; return h->sequence_number;}

    private:
      unsigned char buf[1600];
      int   len;
      bool  need_ack;
    };

    // Queue of pending DATA messages
    std::queue<pending_msg> pending_data;

    // This class & queue is for the slot messages. we coalesce these
    // into a "real" message when the crcuit timer triggers.
    class slot_cmd
    {
    public:
      slot_cmd(unsigned char *_buf, int _len):
	len(_len)
	{
	    memcpy(buf, _buf, len);
	}
      slot_cmd(const slot_cmd &cmd)
	{
	    len = cmd.len;
	    memcpy(buf, cmd.buf, len);
	}

      ~slot_cmd()
	{
	}

      int   get_len(){return len;}
      unsigned char *get_buf(){return buf;}
      LAT_SlotCmd   *get_cmd(){return (LAT_SlotCmd *)buf;}

    private:
        unsigned char  buf[300];
        int            len;
    };

    std::queue<slot_cmd> slots_pending;

    int max_window_size;  // As set by the client.
    int window_size;      // Current window size
    int lat_eco;          // Remote end's LAT ECO version
    int max_slots_per_packet;
    pending_msg last_message; // In case we need to resend it.
    pending_msg last_ack_message; // In case we need to resend it.
    int retransmit_count;

    // name of client device to create
    char lta_name[255];

    // Whether we need to send an ACK if there are no data messages
    // available at the next circuit timer tick
    bool send_ack;
};