1 /******************************************************************************
2     (c) 2000-2008 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 // Singleton server object
15 #define MAX_INTERFACES 255
16 #include "interfaces.h"
17 class LATServer
18 {
19     typedef enum {INACTIVE=0, LAT_SOCKET, LATCP_RENDEZVOUS, LLOGIN_RENDEZVOUS,
20 		  LATCP_SOCKET, LLOGIN_SOCKET, LOCAL_PTY, DISABLED_PTY} fd_type;
21 
22  public:
Instance()23     static LATServer *Instance()
24 	{
25 	    if (!instance)
26 		return (instance = new LATServer());
27 	    else
28 		return instance;
29 	}
30 
31     void init(bool _static_rating, int _rating,
32 	      char *_service, char *_greeting, char **_interfaces,
33 	      int _verbosity, int _timer);
34     void run();
35     void shutdown();
36     void add_fd(int fd, fd_type type);
37     void remove_fd(int fd);
38     void add_pty(LocalPort *port, int fd);
39     void set_fd_state(int fd, bool disabled);
40     int  send_message(unsigned char *buf, int len, int interface, unsigned char *macaddr);
41     void delete_session(int, unsigned char, int);
42     void delete_connection(int);
43     unsigned char *get_local_node();
get_circuit_timer()44     int   get_circuit_timer()         { return circuit_timer; }
get_retransmit_limit()45     int   get_retransmit_limit()      { return retransmit_limit; }
set_retransmit_limit(int r)46     void  set_retransmit_limit(int r) { retransmit_limit=r; }
get_keepalive_timer()47     int   get_keepalive_timer()       { return keepalive_timer; }
set_keepalive_timer(int k)48     void  set_keepalive_timer(int k)  { keepalive_timer=k; }
49     void  send_connect_error(int reason, LAT_Header *msg, int interface, unsigned char *macaddr);
50     bool  is_local_service(char *);
51     int   get_service_info(char *name, std::string &cmd, int &maxcon, int &curcon, uid_t &uid, gid_t &gid);
get_lat_group()52     gid_t get_lat_group() { return lat_group; }
get_connection(int id)53     LATConnection **get_connection(int id) { return &connections[id]; }
get_user_groups()54     const unsigned char *get_user_groups() { return user_groups; }
55     int   find_connection_by_node(const char *node);
56     void  send_enq(const char *);
57     void  add_slave_node(const char *);
58 
59     static unsigned char greeting[255];
60 
61  private:
LATServer()62     LATServer():
63 	circuit_timer(8),
64 	multicast_timer(60),
65 	retransmit_limit(20),
66 	keepalive_timer(20),
67 	responder(false),
68         static_rating(false),
69         rating(12),
70 	alarm_mode(0),
71         num_interfaces(0),
72         multicast_incarnation(0),
73         verbosity(0),
74         latcp_socket(-1),
75         llogin_socket(-1),
76         do_shutdown(false),
77         locked(true),
78         next_connection(1),
79         lat_group(0),
80         groups_set(false),
81         iface(0)
82       {};                       // Private constructor to force singleton
83     static LATServer *instance; // Singleton instance
84 
85     // These two are defaults for new services added
86     bool static_rating;
87     int  rating;
88 
89     int alarm_mode; // For slave solicit .. CC investigate
90 
91     unsigned char local_name[256]; //  Node name
92     int  interface_num[MAX_INTERFACES];
93     int  interface_errs[MAX_INTERFACES];
94     int  num_interfaces;
95     unsigned char multicast_incarnation;
96     int  verbosity;
97     int  latcp_socket;
98     int  llogin_socket;
99     bool do_shutdown;
100     bool locked;
101     int  next_connection;
102     gid_t lat_group;
103 
104     void  read_lat(int sock);
105     double get_loadavg();
106     void  reply_to_enq(unsigned char *inbuf, int len, int interface,
107 		      unsigned char *remote_mac);
108     void  process_command_msg(unsigned char *inbuf, int len, int interface,
109 			      unsigned char *remote_mac);
110     void  forward_status_messages(unsigned char *inbuf, int len);
111     void  send_service_announcement(int sig);
112     void  send_solicit_messages(int sig);
113     int   make_new_connection(unsigned char *buf, int len, int interface,
114 			      LAT_Header *header, unsigned char *macaddr);
115     int   get_next_connection_number();
116 
117     void  add_services(unsigned char *, int, int, unsigned char *);
118     void  got_enqreply(unsigned char *, int, int, unsigned char *);
119     void  accept_latcp(int);
120     void  accept_llogin(int);
121     void  read_latcp(int);
122     void  read_llogin(int);
123     void  print_bitmap(std::ostringstream &, bool, unsigned char *bitmap);
124     void  tidy_dev_directory();
125     int   make_connection(int fd, const char *, const char *, const char *, const char *, const char *, bool);
126 
127     static void alarm_signal(int sig);
128 
129     class fdinfo
130     {
131     public:
fdinfo(int _fd,LocalPort * _port,fd_type _type)132 	fdinfo(int _fd, LocalPort *_port, fd_type _type):
133 	    fd(_fd),
134 	    localport(_port),
135 	    type(_type)
136 	    {}
137 
get_fd()138 	int get_fd(){return fd;}
get_localport()139 	LocalPort *get_localport(){return localport;}
get_type()140 	fd_type get_type(){return type;}
set_disabled(bool d)141 	void set_disabled(bool d)
142 	    {
143 		if (d)
144 		    type = DISABLED_PTY;
145 		else
146 		    type = LOCAL_PTY;
147 
148 	    }
149 
active()150 	bool active()
151 	{
152 	  return (!(type == INACTIVE || type == DISABLED_PTY));
153 	}
154 
155 	bool operator==(int _fd) const
156 	{
157 	    return (type != INACTIVE && fd == _fd);
158 	}
159 
160 	bool operator==(const fdinfo &fdi) const
161 	{
162 	    return (fd == fdi.fd);
163 	}
164 
165 	bool operator!=(const fdinfo &fdi) const
166 	{
167 	    return (fd != fdi.fd);
168 	}
169 
170 	bool operator!=(int _fd) const
171 	{
172 	    return (type == INACTIVE || fd != _fd);
173 	}
174 
175     private:
176 	int  fd;
177 	LocalPort *localport;
178 	fd_type type;
179     };
180 
181     class deleted_session
182     {
183       private:
184 	fd_type type;
185         int connection;
186 	unsigned char local_id;
187 	int fd;
188 
189       public:
deleted_session(fd_type t,int c,unsigned char i,int f)190 	deleted_session(fd_type t, int c, unsigned char i, int f):
191           type(t),
192 	  connection(c),
193 	  local_id(i),
194 	  fd(f)
195 	  {}
get_conn()196 	int            get_conn(){return connection;}
get_id()197 	unsigned char  get_id()  {return local_id;}
get_fd()198 	int            get_fd()  {return fd;}
get_type()199 	fd_type        get_type(){return type;}
200     };
201 
202     // Class that defines a local (server) service
203     class serviceinfo
204     {
205     public:
206             serviceinfo(std::string n, int r, bool s, std::string i = std::string((char*)""), int mc=0, char* comm="",
207 			uid_t uid=0, gid_t gid=0):
name(n)208 	    name(n),
209 	    id(i),
210 	    command(std::string(comm)),
211 	    rating(r),
212 	    max_connections(mc),
213 	    cur_connections(0),
214 	    static_rating(s),
215 	    cmd_uid(uid),
216 	    cmd_gid(gid)
217 	    {
218 		if (command == std::string(""))
219 		    command = std::string(LOGIN_BIN);
220 	    }
get_name()221 	const std::string &get_name() {return name;}
get_id()222 	const std::string &get_id() {return id;}
get_command()223 	const std::string &get_command() {return command;}
get_max_connections()224 	int           get_max_connections() {return max_connections;}
get_cur_connections()225 	int           get_cur_connections() {return cur_connections;}
get_uid()226 	uid_t         get_uid() {return cmd_uid;}
get_gid()227 	gid_t         get_gid() {return cmd_gid;}
get_rating()228 	int           get_rating() {return rating;}
get_static()229 	bool          get_static() {return static_rating;}
set_rating(int _new_rating,bool _static)230 	void          set_rating(int _new_rating, bool _static)
231 	    { rating = _new_rating; static_rating = _static; }
set_ident(char * _ident)232 	void          set_ident(char *_ident)
233 	    { id = std::string(_ident);}
inc_connections()234 	void inc_connections() {cur_connections++;}
dec_connections()235 	void dec_connections() {cur_connections--;}
236 
237 	bool operator==(serviceinfo &si)  { return (si == name);}
238 	bool operator==(const std::string &nm) { return (nm == name);}
239 	bool operator!=(serviceinfo &si)  { return (si != name);}
240 	bool operator!=(const std::string &nm) { return (nm != name);}
241 
242     private:
243 	std::string name;
244 	std::string id;
245 	std::string command;
246 	int rating;
247 	int max_connections;
248 	int cur_connections;
249 	bool static_rating;
250 	uid_t cmd_uid;
251 	gid_t cmd_gid;
252     };
253 
254     void process_data(fdinfo &);
255     void delete_entry(deleted_session &);
256     void interface_error(int, int);
257 
258     // Constants
259     static const int MAX_CONNECTIONS = 255;
260 
261     // Collections
262     std::list<fdinfo>          fdlist;
263     std::list<deleted_session> dead_session_list;
264     std::list<int>             dead_connection_list;
265     std::list<serviceinfo>     servicelist;
266     std::list<LocalPort>       portlist;
267 
268     // Slave Nodes or Dummy Nodes. Well, no-self-advertised nodes
269     std::list<std::string>   slave_nodes;
270     std::list<std::string>   known_slave_nodes;
271 
272     // Connections indexed by ID
273     LATConnection *connections[MAX_CONNECTIONS];
274 
275     // LATCP connections
276     std::map<int, Circuit*> latcp_circuits;
277 
278     // LATCP configurable parameters
279     int           circuit_timer;   // Default 8 (=80 ms)
280     unsigned int  multicast_timer; // Default 60 (seconds)
281     int           retransmit_limit;// Default 20
282     int           keepalive_timer; // Default 20 (seconds)
283     bool          responder;       // Be a service responder (false);
284     unsigned char groups[32];      // Bitmap of groups
285     bool          groups_set;      // Have the server groups been set ?
286     unsigned char user_groups[32]; // Bitmap of user groups..always in use
287     LATinterfaces *iface;
288 
289     // LATCP Circuit callins
290  public:
SetResponder(bool onoff)291     void SetResponder(bool onoff) { responder = onoff;}
292     void Shutdown();
293     bool add_service(char *name, char *ident, char *command,
294 		     int maxcon, uid_t uid, gid_t gid, int _rating, bool _static_rating);
295     bool set_rating(char *name, int _rating, bool _static_rating);
296     bool set_ident(char *name, char *ident);
297     bool remove_service(char *name);
298     bool remove_port(char *name);
299     void set_multicast(int newtime);
300     void set_nodename(unsigned char *);
301     void unlock();
302     bool show_characteristics(bool verbose, std::ostringstream &output);
303     bool show_nodes(bool verbose, std::ostringstream &output);
304     int  create_local_port(unsigned char *, unsigned char *,
305 			   unsigned char *, unsigned char *, bool, bool,
306 			   unsigned char *);
307     int  make_llogin_connection(int fd, const char *, const char *, const char *, const char *, const char *, bool);
308     int  make_port_connection(int fd, LocalPort *, const char *, const char *, const char *,
309 			      const char *, const char *, bool);
310     int  set_servergroups(unsigned char *bitmap);
311     int  unset_servergroups(unsigned char *bitmap);
312     int  set_usergroups(unsigned char *bitmap);
313     int  unset_usergroups(unsigned char *bitmap);
314 };
315