1 /******************************************************************************
2 (c) 2000-2009 Christine Caulfield christine.caulfield@googlemail.com
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 ******************************************************************************/
14
15 #include <stdio.h>
16 #include <sys/time.h>
17 #include <netinet/in.h>
18 #include <string.h>
19 #include <list>
20 #include <map>
21 #include <queue>
22 #include <string>
23 #include <sstream>
24 #include <iterator>
25
26
27 #include "lat.h"
28 #include "utils.h"
29 #include "session.h"
30 #include "serversession.h"
31 #include "reversesession.h"
32 #include "clientsession.h"
33 #include "lloginsession.h"
34 #include "localportsession.h"
35 #include "queuedsession.h"
36 #include "localport.h"
37 #include "connection.h"
38 #include "circuit.h"
39 #include "latcpcircuit.h"
40 #include "server.h"
41 #include "services.h"
42 #include "lat_messages.h"
43 #include "dn_endian.h"
44
45
46 // Create a server connection
LATConnection(int _num,unsigned char * buf,int len,int _interface,unsigned char _seq,unsigned char _ack,unsigned char * _macaddr)47 LATConnection::LATConnection(int _num, unsigned char *buf, int len,
48 int _interface,
49 unsigned char _seq,
50 unsigned char _ack,
51 unsigned char *_macaddr):
52 num(_num),
53 interface(_interface),
54 keepalive_timer(0),
55 last_sent_seq(0xff),
56 last_sent_ack(0),
57 last_recv_seq(_seq),
58 last_recv_ack(_ack),
59 last_time(0L),
60 need_ack(false),
61 queued(false),
62 eightbitclean(false),
63 connected(false),
64 delete_pending(false),
65 request_id(0),
66 last_msg_type(0),
67 last_msg_retries(0),
68 role(SERVER),
69 send_ack(false)
70 {
71 memcpy(macaddr, (char *)_macaddr, 6);
72 int ptr = sizeof(LAT_Start);
73 LAT_Start *msg = (LAT_Start *)buf;
74
75 debuglog(("New connection: (s: %x, a: %x)\n",
76 last_recv_seq, last_recv_ack));
77
78 get_string(buf, &ptr, servicename); // This is actually local nodename
79 get_string(buf, &ptr, remnode);
80
81 debuglog(("Connect from %s (LAT %d.%d) for %s, window size: %d\n",
82 remnode, msg->latver, msg->latver_eco, servicename, msg->exqueued));
83
84 remote_connid = msg->header.local_connid;
85 next_session = 1;
86 highest_session = 1;
87 max_window_size = msg->exqueued+1;
88 max_window_size = 1; // All we can manage
89 window_size = 0;
90 lat_eco = msg->latver_eco;
91 max_slots_per_packet = 4;
92
93 memset(sessions, 0, sizeof(sessions));
94 }
95
96 // Create a client connection
LATConnection(int _num,const char * _service,const char * _portname,const char * _lta,const char * _remnode,bool queued,bool clean)97 LATConnection::LATConnection(int _num, const char *_service,
98 const char *_portname, const char *_lta,
99 const char *_remnode, bool queued, bool clean):
100 num(_num),
101 keepalive_timer(0),
102 last_sent_seq(0xff),
103 last_sent_ack(0),
104 last_recv_seq(0),
105 last_recv_ack(0xff),
106 last_time(0L),
107 need_ack(false),
108 queued(queued),
109 eightbitclean(clean),
110 connected(false),
111 connecting(false),
112 delete_pending(false),
113 request_id(0),
114 last_msg_type(0),
115 last_msg_retries(0),
116 role(CLIENT),
117 send_ack(false)
118 {
119 debuglog(("New client connection for %s created\n", _remnode));
120 memset(sessions, 0, sizeof(sessions));
121 strcpy((char *)servicename, _service);
122 strcpy((char *)portname, _portname);
123 strcpy((char *)remnode, _remnode);
124 strcpy(lta_name, _lta);
125
126 max_slots_per_packet = 4;
127 max_window_size = 1; // Gets overridden later on.
128 window_size = 0;
129 next_session = 1;
130 highest_session = 1;
131 }
132
133
process_session_cmd(unsigned char * buf,int len,unsigned char * macaddr)134 bool LATConnection::process_session_cmd(unsigned char *buf, int len,
135 unsigned char *macaddr)
136 {
137 int msglen;
138 unsigned int command;
139 int i;
140 int newsessionnum;
141 int ptr = sizeof(LAT_Header);
142 LATSession *newsession;
143 LAT_SessionCmd *msg = (LAT_SessionCmd *)buf;
144 int num_replies = 0;
145 LAT_SlotCmd *reply[MAX_REPLIES];
146 char replybuf[MAX_REPLIES][256];
147 bool replyhere = false;
148
149 debuglog(("process_session_cmd: %d slots, %d bytes\n",
150 msg->header.num_slots, len));
151
152 /* Clear out the reply slots and initialise pointers */
153 memset(replybuf, 0, sizeof(replybuf));
154 for (unsigned int ri=0; ri<MAX_REPLIES; ri++)
155 reply[ri] = (LAT_SlotCmd *)replybuf[ri];
156
157 #ifdef REALLY_VERBOSE_DEBUGLOG
158 debuglog(("MSG: seq: %d, ack: %d (last sent seq = %d)\n",
159 msg->header.sequence_number, msg->header.ack_number, last_sent_seq));
160
161 debuglog(("PREV:last seq: %d, last ack: %d\n",
162 last_recv_seq, last_recv_ack));
163 #endif
164
165 // Is this a duplicate?
166 // Check the previous ack number too as we could be one packet out
167 if (msg->header.sequence_number == last_recv_seq ||
168 msg->header.sequence_number == last_recv_seq-1)
169 {
170 if (msg->header.ack_number == last_recv_ack)
171 {
172 debuglog(("Duplicate packet received...resending ACK\n"));
173
174 // But still send an ACK as it could be the ACK that went missing
175 last_ack_message.send(interface, last_recv_seq, macaddr);
176
177 // If the last DATA message wasn't seen either then resend that too
178 if (last_message.get_seq() > msg->header.ack_number ||
179 (last_message.get_seq() == 0 && msg->header.ack_number == 0xff))
180
181 {
182 debuglog(("Also sending last DATA message (%d)\n", last_message.get_seq()));
183 last_message.send(interface, last_recv_seq, macaddr);
184 }
185 }
186 return false;
187 }
188
189 // If we got an old message then process that.
190 if (msg->header.ack_number != last_sent_seq)
191 {
192 debuglog(("Got ack for old message, resending ACK\n"));
193 last_ack_message.send(interface, last_recv_seq, macaddr);
194
195 // If the last DATA message wasn't seen either then resend that too
196 if (last_message.get_seq() > msg->header.ack_number ||
197 (last_message.get_seq() == 0 && msg->header.ack_number == 0xff))
198 {
199 debuglog(("Also sending last DATA message (%d)\n", last_message.get_seq()));
200 last_message.send(interface, last_recv_seq, macaddr);
201 }
202 }
203
204 window_size--;
205 if (window_size < 0) window_size = 0;
206
207 need_ack = false;
208 last_recv_ack = msg->header.ack_number;
209 last_recv_seq = msg->header.sequence_number;
210
211 // No blocks? just ACK it (if we're a server)
212 if (msg->header.num_slots == 0)
213 {
214 if (role == SERVER)
215 {
216 reply[0]->remote_session = msg->slot.local_session;
217 reply[0]->local_session = msg->slot.remote_session;
218 reply[0]->length = 0;
219 reply[0]->cmd = 0;
220 replyhere = true;
221 }
222
223 LAT_SlotCmd *slotcmd = (LAT_SlotCmd *)(buf+ptr);
224 unsigned char credits = slotcmd->cmd & 0x0F;
225
226 debuglog(("No data: cmd: %d, credit: %d\n", msg->header.cmd, credits));
227
228 LATSession *session = sessions[slotcmd->local_session];
229 if (credits)
230 {
231 if (session) session->add_credit(credits);
232 }
233 if (replyhere && session && session->get_remote_credit() <= 2)
234 {
235 reply[0]->cmd |= 15; // Add credit
236 session->inc_remote_credit(15);
237 }
238 }
239 else
240 {
241 replyhere = true;
242 for (i=0; i<msg->header.num_slots && ptr<len; i++)
243 {
244 LAT_SlotCmd *slotcmd = (LAT_SlotCmd *)(buf+ptr);
245 msglen = slotcmd->length;
246 command = slotcmd->cmd & 0xF0;
247 unsigned char credits = slotcmd->cmd & 0x0F;
248
249 debuglog(("process_slot_cmd(%d:%x). command: %x, credit: %d, len: %d\n",
250 i, ptr, command, credits, msglen));
251
252 ptr += sizeof(LAT_SlotCmd);
253
254 // Process the data.
255 LATSession *session = sessions[slotcmd->local_session];
256 if (session && credits) session->add_credit(credits);
257
258 switch (command)
259 {
260 case 0x00:
261 {
262 if (session)
263 {
264 if (session->send_data_to_process(buf+ptr, msglen))
265 {
266 // No echo.
267 if (role == SERVER)
268 {
269 replyhere = true;
270 }
271 }
272 // We are expecting an echo - don't send anything now
273 // but still increment the remote credit if the other end
274 // has run out.
275 debuglog(("Remote credit is %d\n", session->get_remote_credit()));
276 if (session->get_remote_credit() <= 2)
277 {
278 reply[num_replies]->remote_session = slotcmd->local_session;
279 reply[num_replies]->local_session = slotcmd->remote_session;
280 reply[num_replies]->length = 0;
281 reply[num_replies]->cmd = 15; // Just credit
282 num_replies++;
283 session->inc_remote_credit(15);
284 }
285 }
286 else
287 {
288 // An error - send a disconnect.
289 reply[num_replies]->remote_session = slotcmd->local_session;
290 reply[num_replies]->local_session = slotcmd->remote_session;
291 reply[num_replies]->length = 0;
292 reply[num_replies]->cmd = 0xD3; // Invalid slot recvd
293 num_replies++;
294 }
295 }
296 break;
297
298 case 0x90:
299 if (role == SERVER)
300 {
301 int queued_connection;
302 if (is_queued_reconnect(buf, len, &queued_connection))
303 {
304 LATConnection **master_conn = LATServer::Instance()->get_connection(queued_connection);
305 if (!(*master_conn))
306 {
307 debuglog(("Got queued reconnect for non-existant request ID\n"));
308
309 // Not us mate...
310 reply[num_replies]->remote_session = slotcmd->local_session;
311 reply[num_replies]->local_session = slotcmd->remote_session;
312 reply[num_replies]->length = 0;
313 reply[num_replies]->cmd = 0xD7; // No such service
314 num_replies++;
315 }
316 else
317 {
318 last_msg_type = 0;
319 (*master_conn)->last_msg_type = 0;
320
321 last_msg_retries= 0;
322 (*master_conn)->last_msg_retries = 0;
323
324 // Connect a new port session to it
325 ClientSession *cs = (ClientSession *)(*master_conn)->sessions[1];
326
327 newsessionnum = next_session_number();
328 newsession = new QueuedSession(*this,
329 (LAT_SessionStartCmd *)buf,
330 cs,
331 slotcmd->remote_session,
332 newsessionnum,
333 (*master_conn)->eightbitclean);
334 if (newsession->new_session(remnode, (char*)"", (char*)"",
335 credits) == -1)
336 {
337 newsession->send_disabled_message();
338 delete newsession;
339 }
340 else
341 {
342 sessions[newsessionnum] = newsession;
343 newsession->set_master_conn(master_conn);
344
345 // If we were pending a delete, we aren't now
346 delete_pending = false;
347 }
348 }
349 }
350 else
351 {
352 // Check service name is one we recognise.
353 ptr = sizeof(LAT_SessionStartCmd);
354 unsigned char name[256];
355 get_string(buf, &ptr, name);
356
357 // Do parameters -- look for a 5 (remote port name)
358 while (ptr < len)
359 {
360 int param_type = buf[ptr++];
361 if (param_type == 5)
362 {
363 get_string(buf, &ptr, portname);
364 }
365 else
366 {
367 ptr += buf[ptr]+1; // Skip over it
368 }
369 }
370
371 if (!LATServer::Instance()->is_local_service((char *)name))
372 {
373 reply[num_replies]->remote_session = slotcmd->local_session;
374 reply[num_replies]->local_session = slotcmd->remote_session;
375 reply[num_replies]->length = 0;
376 reply[num_replies]->cmd = 0xD7; // No such service
377 num_replies++;
378 }
379 else
380 {
381 std::string cmd;
382 int maxcon;
383 uid_t uid;
384 gid_t gid;
385 int curcon;
386 LATServer::Instance()->get_service_info((char *)name, cmd, maxcon, curcon, uid, gid);
387 strcpy((char *)servicename, (char *)name);
388
389 newsessionnum = next_session_number();
390 newsession = new ServerSession(*this,
391 (LAT_SessionStartCmd *)buf,
392 cmd, uid, gid,
393 slotcmd->remote_session,
394 newsessionnum, false);
395 if (newsession->new_session(remnode, (char*)"", (char *)portname,
396 credits) == -1)
397 {
398 newsession->send_disabled_message();
399 delete newsession;
400 }
401 else
402 {
403 sessions[newsessionnum] = newsession;
404 // If we were pending a delete, we aren't now
405 delete_pending = false;
406 }
407 }
408 }
409 }
410 else // CLIENT
411 {
412 if (session)
413 ((LATSession *)session)->got_connection(slotcmd->remote_session);
414 }
415 break;
416
417 case 0xa0:
418 // Data_b message - port information
419 if (session)
420 session->set_port((unsigned char *)slotcmd);
421 break;
422
423 case 0xb0:
424 // Attention. Force XON, Abort etc.
425 break;
426
427
428 case 0xc0: // Reject - we will get disconnected
429 debuglog(("Reject code %d: %s\n", credits,
430 lat_messages::session_disconnect_msg(credits)));
431 // Deliberate fall-through.
432
433 case 0xd0: // Disconnect
434 if (session) session->disconnect_session(credits);
435
436 // If we have no sessions left then disconnect
437 if (num_clients() == 0)
438 {
439 reply[num_replies]->remote_session = slotcmd->local_session;
440 reply[num_replies]->local_session = slotcmd->remote_session;
441 reply[num_replies]->length = 0;
442 reply[num_replies]->cmd = 0xD1;/* No more slots on circuit */
443 num_replies++;
444 }
445 break;
446
447 default:
448 debuglog(("Unknown slot command %x found. length: %d\n",
449 command, msglen));
450 replyhere=true;
451 break;
452 }
453 ptr += msglen;
454 if (ptr%2) ptr++; // Word-aligned
455 }
456 }
457
458 // If "Response Requested" set, then make sure we send one.
459 if (msg->header.cmd & 1 && !replyhere)
460 {
461 debuglog(("Sending response because we were told to (%x)\n", msg->header.cmd));
462 replyhere = true;
463 }
464
465 // If the reply is just an ack then just set a flag
466 // Then in circuit_timer, we send an ACK only if there is no DATA to send.
467 if (replyhere && num_replies == 0)
468 send_ack = true;
469
470 // Send any replies
471 if (replyhere && num_replies)
472 {
473 debuglog(("Sending %d slots in reply\n", num_replies));
474 unsigned char replybuf[1600];
475
476 memset(replybuf, 0, sizeof(replybuf));
477 LAT_Header *header = (LAT_Header *)replybuf;
478 ptr = sizeof(LAT_Header);
479
480 header->cmd = LAT_CCMD_SREPLY;
481 header->num_slots = num_replies;
482 if (role == CLIENT) header->cmd |= 2; // To Host
483
484 for (int i=0; i < num_replies; i++)
485 {
486 memcpy(replybuf + ptr, reply[i], sizeof(LAT_SlotCmd));
487 ptr += sizeof(LAT_SlotCmd); // Already word-aligned
488 }
489
490 header->local_connid = num;
491 header->remote_connid = remote_connid;
492
493 pending_data.push(pending_msg(replybuf, ptr, false));
494
495 return true;
496 }
497
498 return false;
499 }
500
501
send_connect_ack()502 void LATConnection::send_connect_ack()
503 {
504 unsigned char reply[1600];
505 int ptr;
506 LAT_StartResponse *response = (LAT_StartResponse *)reply;
507 LATServer *server = LATServer::Instance();
508
509 // Send response...
510 response->header.cmd = LAT_CCMD_CONACK;
511 response->header.num_slots = 0;
512 response->maxsize = dn_htons(1500);
513 response->latver = LAT_VERSION;
514 response->latver_eco = LAT_VERSION_ECO;
515 response->maxsessions = 254;
516 response->exqueued = 0;
517 response->circtimer = LATServer::Instance()->get_circuit_timer();
518 response->keepalive = LATServer::Instance()->get_keepalive_timer();
519 response->facility = dn_htons(0);
520 response->prodtype = 3; // Wot do we use here???
521 response->prodver = 3; // and here ???
522
523 ptr = sizeof(LAT_StartResponse);
524 add_string(reply, &ptr, server->get_local_node());
525 add_string(reply, &ptr, remnode);
526 add_string(reply, &ptr, (unsigned char*)LATServer::greeting);
527 reply[ptr++] = '\0';
528
529 queue_message(reply, ptr);
530 }
531
532 // Send a message on this connection NOW
send_message(unsigned char * buf,int len,send_type type)533 int LATConnection::send_message(unsigned char *buf, int len, send_type type)
534 {
535 LAT_Header *response = (LAT_Header *)buf;
536
537 response->local_connid = num;
538 response->remote_connid = remote_connid;
539 response->sequence_number = ++last_sent_seq;
540 response->ack_number = last_recv_seq;
541
542 retransmit_count = 0;
543 last_sent_ack = last_recv_seq;
544
545 debuglog(("Sending message for connid %d (seq: %d, ack: %d) window=%d\n",
546 num, last_sent_seq, last_sent_ack, window_size ));
547
548 keepalive_timer = 0;
549
550 if (type == DATA)
551 {
552 need_ack = true;
553 last_message = pending_msg(buf, len, true);
554 window_size++;
555 }
556 else
557 {
558 need_ack = false;
559 last_ack_message = pending_msg(buf, len, false);
560 }
561
562 return LATServer::Instance()->send_message(buf, len, interface, macaddr);
563 }
564
565 // Queue up a reply message
queue_message(unsigned char * buf,int len)566 int LATConnection::queue_message(unsigned char *buf, int len)
567 {
568 LAT_Header *response = (LAT_Header *)buf;
569
570 response->local_connid = num;
571 response->remote_connid = remote_connid;
572 // SEQ and ACK filled in when we send it
573
574 debuglog(("Queued data messsge for connid %d\n", num));
575
576 pending_data.push(pending_msg(buf, len, true));
577 return 0;
578 }
579
580
581 // Enque a slot message on this connection
send_slot_message(unsigned char * buf,int len)582 void LATConnection::send_slot_message(unsigned char *buf, int len)
583 {
584 slots_pending.push(slot_cmd(buf,len));
585 }
586
~LATConnection()587 LATConnection::~LATConnection()
588 {
589 debuglog(("LATConnection dtor: %d\n", num));
590
591 // Delete server sessions
592 for (unsigned int i=1; i<=highest_session; i++)
593 {
594 if (sessions[i])
595 {
596 LATConnection *master = sessions[i]->get_master_conn();
597 if (master)
598 {
599 ClientSession *cs = (ClientSession *)master->sessions[1];
600 if (cs) cs->restart_pty();
601 }
602 delete sessions[i];
603 sessions[i] = NULL;
604 }
605 }
606 // Send a "shutting down" message to the other end
607
608 }
609
610 // Generate the next session ID
next_session_number()611 int LATConnection::next_session_number()
612 {
613 unsigned int i;
614 for (i=next_session; i < MAX_SESSIONS; i++)
615 {
616 if (!sessions[i])
617 {
618 next_session = i+1;
619 highest_session = i;
620 return i;
621 }
622 }
623
624 // Didn't find a slot here - try from the start
625 for (i=1; i < next_session; i++)
626 {
627 if (!sessions[i])
628 {
629 next_session = i+1;
630 return i;
631 }
632 }
633 return -1;
634 }
635
636
637 //
638 // Send queued packets
639 //
circuit_timer(void)640 void LATConnection::circuit_timer(void)
641 {
642 // Did we get an ACK for our last message?
643 if (need_ack && last_sent_seq != last_recv_ack)
644 {
645 if (++retransmit_count > LATServer::Instance()->get_retransmit_limit())
646 {
647 debuglog(("hit retransmit limit on connection %d\n", num));
648
649 unsigned char buf[1600];
650 LAT_Header *header = (LAT_Header *)buf;
651 int ptr = sizeof(LAT_Header);
652
653 header->cmd = LAT_CCMD_CONREF;
654 if (role == CLIENT)
655 header->cmd |= 2;
656 header->num_slots = 0;
657 header->local_connid = num;
658 header->remote_connid = remote_connid;
659 header->sequence_number = ++last_sent_seq;
660 header->ack_number = last_recv_seq;
661 buf[ptr++] = 0x06; // Retransmission limit reached.
662 LATServer::Instance()->send_message(buf, ptr, interface, macaddr);
663
664 // Set this connection pending deletion
665 LATServer::Instance()->delete_connection(num);
666
667 // Mark this node as unavailable in the service list
668 LATServices::Instance()->remove_node(std::string((char *)remnode));
669 return;
670 }
671 debuglog(("Last message not ACKed: RESEND\n"));
672 last_message.send(interface, last_recv_seq, macaddr);
673 return;
674 }
675
676 // If we're waiting for a non-flow-control message then
677 // check for timeout.
678 if (last_msg_type)
679 {
680 time_t tt;
681 tt = time(NULL);
682
683 if (tt - last_msg_time > 5)
684 {
685 last_msg_time = tt;
686
687 // Too many retries ??
688 if (++last_msg_retries >= 3)
689 {
690 LATServer::Instance()->delete_connection(num);
691 last_msg_type = 0;
692 return;
693 }
694 switch (last_msg_type)
695 {
696 // Connect
697 case LAT_CCMD_CONNECT:
698 {
699 // Send another connect command
700 int ptr;
701 unsigned char buf[1600];
702 LAT_Start *msg = (LAT_Start *)buf;
703 ptr = sizeof(LAT_Start);
704
705 debuglog(("Resending connect to service on interface %d\n", interface));
706
707 msg->header.cmd = LAT_CCMD_CONNECT;
708 msg->header.num_slots = 0;
709 msg->header.local_connid = num;
710
711 msg->maxsize = dn_htons(1500);
712 msg->latver = LAT_VERSION;
713 msg->latver_eco = LAT_VERSION_ECO;
714 msg->maxsessions = 254;
715 msg->exqueued = 0;
716 msg->circtimer = LATServer::Instance()->get_circuit_timer();
717 msg->keepalive = LATServer::Instance()->get_keepalive_timer();
718 msg->facility = dn_htons(0); // Eh?
719 msg->prodtype = 3; // Wot do we use here???
720 msg->prodver = 3; // and here ???
721
722 add_string(buf, &ptr, remnode);
723 add_string(buf, &ptr, LATServer::Instance()->get_local_node());
724 add_string(buf, &ptr, (unsigned char *)LATServer::greeting);
725 send_message(buf, ptr, DATA);
726 return;
727 }
728 break;
729
730 // Request for queued connect
731 case LAT_CCMD_COMMAND:
732 {
733 int ptr;
734 unsigned char buf[1600];
735 LAT_Command *msg = (LAT_Command *)buf;
736 ptr = sizeof(LAT_Command);
737
738 debuglog(("Resending queued connect to service on interface %d\n", interface));
739
740 msg->cmd = LAT_CCMD_COMMAND;
741 msg->format = 0;
742 msg->hiver = LAT_VERSION;
743 msg->lover = LAT_VERSION;
744 msg->latver = LAT_VERSION;
745 msg->latver_eco = LAT_VERSION_ECO;
746 msg->maxsize = dn_htons(1500);
747 msg->request_id = num;
748 msg->entry_id = 0;
749 msg->opcode = 2; // Request Queued connection
750 msg->modifier = 1; // Send status periodically
751
752 add_string(buf, &ptr, remnode);
753
754 buf[ptr++] = 32; // Groups length
755 memcpy(buf + ptr, LATServer::Instance()->get_user_groups(), 32);
756 ptr += 32;
757
758 add_string(buf, &ptr, LATServer::Instance()->get_local_node());
759 buf[ptr++] = 0; // ASCIC source port
760 buf[ptr++] = 0; // add_string(buf, &ptr, (unsigned char *)LATServer::greeting);
761 add_string(buf, &ptr, servicename);
762 add_string(buf, &ptr, portname);
763
764 // Send it raw.
765 LATServer::Instance()->send_message(buf, ptr, interface, macaddr);
766 return;
767 }
768 break;
769
770 default:
771 break;
772 }
773 }
774 return;
775 }
776
777 retransmit_count = 0;
778
779
780 // Poll our sessions
781 for (unsigned int i=0; i<=highest_session; i++)
782 {
783 if (sessions[i] && sessions[i]->isConnected())
784 sessions[i]->read_pty();
785 }
786
787 // Coalesce pending messages and queue them
788 while (!slots_pending.empty())
789 {
790 debuglog(("circuit Timer:: slots pending = %d\n", slots_pending.size()));
791 unsigned char buf[1600];
792 LAT_Header *header = (LAT_Header *)buf;
793 int len = sizeof(LAT_Header);
794
795 if (role == SERVER)
796 header->cmd = LAT_CCMD_SDATA;
797 else
798 header->cmd = LAT_CCMD_SESSION;
799 header->num_slots = 0;
800
801 // Send as many slot data messages as we can
802 while ( (header->num_slots < max_slots_per_packet && !slots_pending.empty()))
803 {
804 slot_cmd &cmd(slots_pending.front());
805
806 // make sure it fits
807 // do we really need max_slots_per_packet ?
808 if ((len + cmd.get_len()) > 1500)
809 break;
810 header->num_slots++;
811
812 memcpy(buf+len, cmd.get_buf(), cmd.get_len());
813 len += cmd.get_len();
814 if (len%2) len++; // Keep it on even boundary
815
816 slots_pending.pop();
817 }
818
819 if (header->num_slots)
820 {
821 debuglog(("Collected %d slots on circuit timer\n", header->num_slots));
822 header->local_connid = num;
823 header->remote_connid = remote_connid;
824 pending_data.push(pending_msg(buf, len, true));
825 }
826 }
827
828 // Send a reply if there are no data messages and the remote
829 // end needs an ACK.
830 if (send_ack &&
831 (pending_data.empty() || window_size >= max_window_size))
832 {
833 debuglog(("Sending ACK reply\n"));
834 unsigned char replybuf[1600];
835
836 memset(replybuf, 0, sizeof(replybuf));
837 LAT_Header *header = (LAT_Header *)replybuf;
838 int len = sizeof(LAT_Header);
839
840 header->cmd = LAT_CCMD_SREPLY;
841 header->num_slots = 0;
842 if (role == CLIENT) header->cmd |= 2; // To Host
843
844 header->local_connid = num;
845 header->remote_connid = remote_connid;
846
847 header->sequence_number = last_sent_seq;
848 header->ack_number = last_recv_seq;
849
850 send_message(replybuf, len, REPLY);
851 }
852 send_ack = false;
853
854 // Send a pending data message (if we can)
855 if (!pending_data.empty() && window_size <= max_window_size)
856 {
857 // Send the top message
858 pending_msg &msg(pending_data.front());
859
860 retransmit_count = 0;
861 need_ack = msg.needs_ack();
862 window_size++;
863
864 LAT_Header *header = msg.get_header();
865
866 header->local_connid = num;
867 header->remote_connid = remote_connid;
868 header->sequence_number = ++last_sent_seq;
869 header->ack_number = last_recv_seq;
870
871 debuglog(("Sending data message on circuit timer: seq: %d, ack: %d\n",
872 last_sent_seq, last_recv_seq));
873
874 msg.send(interface, macaddr);
875 last_message = msg; // Save it in case it gets lost on the wire;
876 pending_data.pop();
877 keepalive_timer = 0;
878 }
879
880 // Increment keepalive timer and trigger it if we are getting too close.
881 // Keepalive timer is held in milli-seconds.
882
883 // Of course, we needn't send keepalive messages when we are a
884 // disconnected client.
885 if (role == SERVER ||
886 (role == CLIENT && connected))
887 {
888 struct timeval tv;
889 long time_in_msec;
890
891 // Initialise last_time for the first time
892 if (last_time == 0)
893 {
894 gettimeofday(&tv, NULL);
895 last_time = tv.tv_sec*1000 + tv.tv_usec/1000;
896 }
897
898 gettimeofday(&tv, NULL);
899 time_in_msec = tv.tv_sec*1000 + tv.tv_usec/1000;
900
901 keepalive_timer += time_in_msec - last_time;
902 last_time = time_in_msec;
903
904 if (keepalive_timer > (LATServer::Instance()->get_keepalive_timer()-3)*1000 )
905 {
906 // Send an empty message that needs an ACK.
907 // If we don't get a response to this then we abort the circuit.
908 debuglog(("keepalive timer expired: %d: limit: %d\n", keepalive_timer,
909 LATServer::Instance()->get_keepalive_timer()*1000));
910
911 // If we get into this block then there is no chance that there is
912 // an outstanding ack (or if there is then it's all gone horribly wrong anyway)
913 // so it's safe to just send a NULL message out.
914 // If we do exqueued properly this may need revisiting.
915 send_ack = true;
916 return;
917 }
918 }
919 // Delete us if delete_pending is set and no more data to send
920 if (delete_pending && pending_data.empty() &&
921 slots_pending.empty())
922 {
923 LAT_Header msg;
924
925 debuglog(("Deleting pending connection\n"));
926 msg.local_connid = remote_connid;
927 msg.remote_connid = num;
928 msg.sequence_number = ++last_sent_seq;
929 msg.ack_number = last_recv_ack;
930 LATServer::Instance()->send_connect_error(1, &msg, interface, macaddr);
931 LATServer::Instance()->delete_connection(num);
932 }
933
934 }
935
936 // Add as many data slots as we can to a reply.
add_data_slots(int start_slot,LAT_SlotCmd * slots[4])937 int LATConnection::add_data_slots(int start_slot, LAT_SlotCmd *slots[4])
938 {
939 int slot_num = start_slot;
940
941 // Poll our sessions
942 for (unsigned int i=0; i<=highest_session; i++)
943 {
944 if (sessions[i] && sessions[i]->isConnected())
945 sessions[i]->read_pty();
946 }
947
948 // Overwrite any empty slot at the start
949 LAT_SlotCmd *slot_header = (LAT_SlotCmd *)slots[0];
950 if (start_slot == 1 &&
951 slot_header->length == 0 &&
952 !slots_pending.empty())
953 {
954 slot_num--;
955 }
956
957 while (slot_num < max_slots_per_packet && !slots_pending.empty())
958 {
959 slot_cmd &cmd(slots_pending.front());
960
961 memcpy((char*)slots[slot_num], cmd.get_buf(), cmd.get_len());
962
963 slots_pending.pop();
964 slot_num++;
965 }
966 return slot_num;
967 }
968
remove_session(unsigned char id)969 void LATConnection::remove_session(unsigned char id)
970 {
971 debuglog(("Deleting session %d\n", id));
972 if (sessions[id])
973 {
974 delete sessions[id];
975 sessions[id] = NULL;
976 }
977
978 // Disconnect & remove connection if no sessions active...
979 // and no messages pending on circuit timer....
980 if (num_clients() == 0)
981 {
982
983 if (pending_data.empty() && slots_pending.empty())
984 {
985 LAT_Header msg;
986
987 msg.local_connid = remote_connid;
988 msg.remote_connid = num;
989 msg.sequence_number = ++last_sent_seq;
990 msg.ack_number = last_recv_ack;
991 LATServer::Instance()->send_connect_error(1, &msg, interface, macaddr);
992 LATServer::Instance()->delete_connection(num);
993 }
994 else
995 {
996 // Otherwise just delete us when it's all calmed down.
997 delete_pending = true;
998 }
999 }
1000 }
1001
1002 // Initiate a client connection
connect(LATSession * session)1003 int LATConnection::connect(LATSession *session)
1004 {
1005 // Look up the service name.
1006 std::string node;
1007 int this_int=0;
1008
1009 // Are we in the middle of actually connecting ?
1010 if (connecting) return 0;
1011
1012 // Only connect if we are the first session,
1013 // else just initiate slot connect.
1014 if (!connected)
1015 {
1016 // If no node was specified then just use the highest rated one
1017 if (remnode[0] == '\0')
1018 {
1019 if (!LATServices::Instance()->get_highest(std::string((char*)servicename),
1020 node, macaddr, &this_int))
1021 {
1022 debuglog(("Can't find service %s\n", servicename));
1023 // Tell the user
1024 session->disconnect_session(7);
1025 return -2; // Never eard of it!
1026 }
1027 strcpy((char *)remnode, node.c_str());
1028 }
1029 else
1030 {
1031 // Try to find the node
1032 if (!LATServices::Instance()->get_node(std::string((char*)servicename),
1033 std::string((char*)remnode), macaddr, &this_int))
1034 {
1035 debuglog(("Can't find node %s in service\n", remnode, servicename));
1036
1037 // Tell the user
1038 session->disconnect_session(7);
1039 return -2; // Never eard of it!
1040 }
1041 }
1042
1043 // Reset the sequence & ack numbers
1044 last_recv_seq = 0xff;
1045 last_recv_ack = 0;
1046 last_sent_seq = 0xff;
1047 last_sent_ack = 0;
1048 remote_connid = 0;
1049 interface = this_int;
1050 connecting = true;
1051
1052 // Queued connection or normal?
1053 if (queued)
1054 {
1055 debuglog(("Requesting connect to queued service\n"));
1056
1057 int ptr;
1058 unsigned char buf[1600];
1059 LAT_Command *msg = (LAT_Command *)buf;
1060 ptr = sizeof(LAT_Command);
1061
1062 msg->cmd = LAT_CCMD_COMMAND;
1063 msg->format = 0;
1064 msg->hiver = LAT_VERSION;
1065 msg->lover = LAT_VERSION;
1066 msg->latver = LAT_VERSION;
1067 msg->latver_eco = LAT_VERSION_ECO;
1068 msg->maxsize = dn_htons(1500);
1069 msg->request_id = num;
1070 msg->entry_id = 0;
1071 msg->opcode = 2; // Request Queued connection
1072 msg->modifier = 1; // Send status periodically
1073
1074 add_string(buf, &ptr, remnode);
1075
1076 buf[ptr++] = 32; // Groups length
1077 memcpy(buf + ptr, LATServer::Instance()->get_user_groups(), 32);
1078 ptr += 32;
1079
1080 add_string(buf, &ptr, LATServer::Instance()->get_local_node());
1081 buf[ptr++] = 0; // ASCIC source port
1082 buf[ptr++] = 0; // add_string(buf, &ptr, (unsigned char *)LATServer::greeting);
1083 add_string(buf, &ptr, servicename);
1084 add_string(buf, &ptr, portname);
1085
1086 // Save the time we sent the connect so we
1087 // know if we got a response.
1088 last_msg_time = time(NULL);
1089 last_msg_type = msg->cmd;
1090 last_msg_retries = 0;
1091
1092 // Send it raw.
1093 return LATServer::Instance()->send_message(buf, ptr, interface, macaddr);
1094 }
1095 else
1096 {
1097 int ptr;
1098 unsigned char buf[1600];
1099 LAT_Start *msg = (LAT_Start *)buf;
1100 ptr = sizeof(LAT_Start);
1101
1102 debuglog(("Requesting connect to service on interface %d\n", interface));
1103
1104 msg->header.cmd = LAT_CCMD_CONNECT;
1105 msg->header.num_slots = 0;
1106 msg->header.local_connid = num;
1107
1108 msg->maxsize = dn_htons(1500);
1109 msg->latver = LAT_VERSION;
1110 msg->latver_eco = LAT_VERSION_ECO;
1111 msg->maxsessions = 254;
1112 msg->exqueued = 0;
1113 msg->circtimer = LATServer::Instance()->get_circuit_timer();
1114 msg->keepalive = LATServer::Instance()->get_keepalive_timer();
1115 msg->facility = dn_htons(0); // Eh?
1116 msg->prodtype = 3; // Wot do we use here???
1117 msg->prodver = 3; // and here ???
1118
1119 add_string(buf, &ptr, remnode);
1120 add_string(buf, &ptr, LATServer::Instance()->get_local_node());
1121 add_string(buf, &ptr, (unsigned char *)LATServer::greeting);
1122
1123 // Save the time we sent the connect so we
1124 // know if we got a response.
1125 last_msg_time = time(NULL);
1126 last_msg_type = msg->header.cmd;
1127 last_msg_retries = 0;
1128
1129 return send_message(buf, ptr, DATA);
1130 }
1131 }
1132 else
1133 {
1134 // Just do a session connect.
1135 session->connect();
1136 }
1137 return 0;
1138 }
1139
1140 // Initiate a reverse-LAT connection
rev_connect()1141 int LATConnection::rev_connect()
1142 {
1143 // Reset the sequence & ack numbers
1144 last_recv_seq = 0xff;
1145 last_recv_ack = 0;
1146 last_sent_seq = 0xff;
1147 last_sent_ack = 0;
1148 remote_connid = 0;
1149 connecting = true;
1150
1151 int ptr;
1152 unsigned char buf[1600];
1153 LAT_Start *msg = (LAT_Start *)buf;
1154 ptr = sizeof(LAT_Start);
1155
1156 debuglog(("REVLAT: Requesting connect to service on interface %d, request id = %d\n", interface, request_id));
1157
1158 msg->header.cmd = LAT_CCMD_CONNECT;
1159 msg->header.num_slots = 0;
1160 msg->header.local_connid = num;
1161
1162 msg->maxsize = dn_htons(1500);
1163 msg->latver = LAT_VERSION;
1164 msg->latver_eco = LAT_VERSION_ECO;
1165 msg->maxsessions = 254;
1166 msg->exqueued = 0;
1167 msg->circtimer = LATServer::Instance()->get_circuit_timer();
1168 msg->keepalive = LATServer::Instance()->get_keepalive_timer();
1169 msg->facility = dn_htons(0); // Eh?
1170 msg->prodtype = 3; // Wot do we use here???
1171 msg->prodver = 3; // and here ???
1172
1173 add_string(buf, &ptr, remnode);
1174 add_string(buf, &ptr, LATServer::Instance()->get_local_node());
1175
1176 // Save the time we sent the connect so we
1177 // know if we got a response.
1178 last_msg_time = time(NULL);
1179 last_msg_type = msg->header.cmd;
1180 last_msg_retries = 0;
1181
1182 return send_message(buf, ptr, DATA);
1183 }
1184
got_status(unsigned char * node,LAT_StatusEntry * entry)1185 void LATConnection::got_status(unsigned char *node, LAT_StatusEntry *entry)
1186 {
1187 debuglog(("Got status %d from node %s, queue pos = %d,%d. session: %d\n",
1188 entry->status, node, entry->max_que_pos, entry->min_que_pos,
1189 entry->session_id));
1190
1191 // Check this is OK - status session ID seems to be rubbish
1192 if (role == CLIENT && sessions[1])
1193 {
1194 last_msg_type = 0;
1195 last_msg_retries = 0;
1196 ClientSession *s = (ClientSession *)sessions[1];
1197 s->show_status(node, entry);
1198 }
1199
1200 // TODO: mark this session (connection?) as waiting for connect so
1201 // that, if the user quits, we can tell the server. (TODODO: what message ??)
1202 }
1203
create_llogin_session(int fd,const char * service,const char * port,const char * localport,const char * password)1204 int LATConnection::create_llogin_session(int fd, const char *service, const char *port, const char *localport,
1205 const char *password)
1206 {
1207 // Create an lloginSession
1208 int newsessionnum = next_session_number();
1209 if (newsessionnum == -1)
1210 return -1;
1211
1212 lloginSession *newsession = new lloginSession(*this, 0, newsessionnum,
1213 (char *)localport, fd);
1214 if (newsession->new_session((unsigned char *)remnode, (char *)service, (char *)port, (char *)password, 0) == -1)
1215 {
1216 delete newsession;
1217 return -1;
1218 }
1219 sessions[newsessionnum] = newsession;
1220 return 0;
1221 }
1222
create_localport_session(int fd,LocalPort * lport,const char * service,const char * port,const char * localport,const char * password)1223 int LATConnection::create_localport_session(int fd, LocalPort *lport,
1224 const char *service, const char *port,
1225 const char *localport, const char *password)
1226 {
1227 // Create a localportSession for a /dev/lat port
1228 int newsessionnum = next_session_number();
1229
1230 localportSession *newsession = new localportSession(*this, lport, 0, newsessionnum,
1231 (char *)localport, fd);
1232 if (newsession->new_session((unsigned char *)remnode, (char *)service, (char *)port, (char *)password, 0) == -1)
1233 {
1234 delete newsession;
1235 return -1;
1236 }
1237 sessions[newsessionnum] = newsession;
1238 return 0;
1239 }
1240
1241 // Create a server session for an incoming reverse-LAT connection
create_reverse_session(const char * service,const char * cmdbuf,int reqid,int ifn,unsigned char * mac)1242 int LATConnection::create_reverse_session(const char *service,
1243 const char *cmdbuf,
1244 int reqid,
1245 int ifn,
1246 unsigned char *mac)
1247 {
1248 std::string cmd;
1249 int maxcon;
1250 uid_t uid;
1251 gid_t gid;
1252 int curcon;
1253
1254 debuglog(("Create reverse session for %s\n", service));
1255
1256 if (LATServer::Instance()->get_service_info((char *)service, cmd, maxcon, curcon, uid, gid) == -1)
1257 {
1258 debuglog(("Service not known\n"));
1259 return -1;
1260 }
1261
1262 int newsessionnum = next_session_number();
1263
1264 request_id = reqid;
1265 interface = ifn;
1266 memcpy(macaddr, mac, 6);
1267
1268 debuglog(("service %s, cmd = %s\n", service, cmd.c_str()));
1269
1270 ReverseSession *newsession = new ReverseSession(*this,
1271 (LAT_SessionStartCmd *)cmdbuf,
1272 cmd,
1273 uid,gid,
1274 0,newsessionnum,
1275 true);
1276
1277 if (newsession->new_session((unsigned char *)remnode, (char *)remnode, (char *)"", 0) == -1)
1278 {
1279 delete newsession;
1280 return -1;
1281 }
1282 sessions[newsessionnum] = newsession;
1283 newsession->set_request_id(reqid);
1284
1285 // Start it connecting.
1286 if (!connected && !connecting)
1287 rev_connect();
1288
1289 if (connected)
1290 newsession->connect();
1291 return 0;
1292 }
1293
got_connect_ack(unsigned char * buf)1294 int LATConnection::got_connect_ack(unsigned char *buf)
1295 {
1296 LAT_StartResponse *reply = (LAT_StartResponse *)buf;
1297 remote_connid = reply->header.local_connid;
1298
1299 last_recv_ack = reply->header.ack_number;
1300 last_recv_seq = reply->header.sequence_number;
1301
1302 connected = true;
1303 connecting = false;
1304
1305 max_window_size = reply->exqueued+1;
1306 max_window_size = 1; // All we can manage
1307 window_size = 0;
1308 // need_ack = false;
1309
1310 last_msg_type = 0; // Not waiting anymore
1311 last_msg_retries = 0;
1312
1313 debuglog(("got connect ack. seq: %d, ack: %d\n",
1314 last_recv_seq, last_recv_ack));
1315
1316 // Start clientsessions
1317 for (unsigned int i=1; i<=highest_session; i++)
1318 {
1319 ClientSession *cs = (ClientSession *)sessions[i];
1320 if (cs && cs->waiting_start())
1321 {
1322 cs->connect();
1323 }
1324 }
1325 return 0;
1326 }
1327
1328 // Called when the client needs disconnecting
disconnect_client()1329 int LATConnection::disconnect_client()
1330 {
1331 // Reset all clients - remote end has disconnected the connection
1332 for (unsigned int i=0; i<=highest_session; i++)
1333 {
1334 ClientSession *cs = (ClientSession *)sessions[i];
1335 if (cs)
1336 {
1337 cs->restart_pty();
1338 }
1339 }
1340 return 0;
1341 }
1342
1343
1344 // Extract "parameter 2" from the packet. If there is one then
1345 // it means this is a connection from the terminal server for
1346 // a queued *client* port so we...
1347 // do "something clever..."
is_queued_reconnect(unsigned char * buf,int len,int * conn)1348 bool LATConnection::is_queued_reconnect(unsigned char *buf, int len, int *conn)
1349 {
1350 int ptr = sizeof(LAT_SessionCmd)+3;
1351
1352 ptr += buf[ptr]+1; // Skip over destination service
1353 if (ptr >= len) return false;
1354
1355 ptr += buf[ptr]+1; // Skip over source service
1356 if (ptr >= len) return false;
1357
1358 // Do parameters -- look for a 2
1359 while (ptr < len)
1360 {
1361 int param_type = buf[ptr++];
1362 if (param_type == 2)
1363 {
1364 ptr++; //Skip over parameter length (it's 2)
1365 unsigned short param = dn_ntohs(*(unsigned short *)(buf+ptr));
1366
1367 debuglog(("found Parameter 2: request ID is %d\n", param));
1368 *conn = param;
1369 ptr +=2;
1370 return true;
1371 }
1372 else
1373 {
1374 ptr += buf[ptr]+1; // Skip over it
1375 }
1376 }
1377 return false;
1378 }
1379
send(int interface,unsigned char * macaddr)1380 int LATConnection::pending_msg::send(int interface, unsigned char *macaddr)
1381 {
1382 return LATServer::Instance()->send_message(buf, len, interface, macaddr);
1383 }
1384
num_clients()1385 unsigned int LATConnection::num_clients()
1386 {
1387 unsigned int i;
1388 unsigned int num = 0;
1389
1390 for (i=1; i<=highest_session; i++)
1391 if (sessions[i])
1392 num++;
1393
1394 return num;
1395 }
1396