/******************************************************************************
(c) 2000-2002 Patrick Caulfield patrick@debian.org
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.
******************************************************************************/
// Singleton server object
#define MAX_INTERFACES 255
#include "interfaces.h"
class LATServer
{
typedef enum {INACTIVE=0, LAT_SOCKET, LATCP_RENDEZVOUS, LLOGIN_RENDEZVOUS,
LATCP_SOCKET, LLOGIN_SOCKET, LOCAL_PTY, DISABLED_PTY} fd_type;
public:
static LATServer *Instance()
{
if (!instance)
return (instance = new LATServer());
else
return instance;
}
void init(bool _static_rating, int _rating,
char *_service, char *_greeting, char **_interfaces,
int _verbosity, int _timer);
void run();
void shutdown();
void add_fd(int fd, fd_type type);
void remove_fd(int fd);
void add_pty(LocalPort *port, int fd);
void set_fd_state(int fd, bool disabled);
int send_message(unsigned char *buf, int len, int interface, unsigned char *macaddr);
void delete_session(int, unsigned char, int);
void delete_connection(int);
unsigned char *get_local_node();
int get_circuit_timer() { return circuit_timer; }
int get_retransmit_limit() { return retransmit_limit; }
void set_retransmit_limit(int r) { retransmit_limit=r; }
int get_keepalive_timer() { return keepalive_timer; }
void set_keepalive_timer(int k) { keepalive_timer=k; }
void send_connect_error(int reason, LAT_Header *msg, int interface, unsigned char *macaddr);
bool is_local_service(char *);
int get_service_info(char *name, std::string &cmd, int &maxcon, int &curcon, uid_t &uid, gid_t &gid);
gid_t get_lat_group() { return lat_group; }
LATConnection **get_connection(int id) { return &connections[id]; }
const unsigned char *get_user_groups() { return user_groups; }
int find_connection_by_node(const char *node);
void send_enq(const char *);
void add_slave_node(const char *);
static unsigned char greeting[255];
private:
LATServer():
circuit_timer(8),
multicast_timer(60),
retransmit_limit(20),
keepalive_timer(20),
responder(false),
static_rating(false),
rating(12),
alarm_mode(0),
num_interfaces(0),
multicast_incarnation(0),
verbosity(0),
latcp_socket(-1),
llogin_socket(-1),
do_shutdown(false),
locked(true),
next_connection(1),
lat_group(0),
groups_set(false),
iface(0)
{}; // Private constructor to force singleton
static LATServer *instance; // Singleton instance
// These two are defaults for new services added
bool static_rating;
int rating;
int alarm_mode; // For slave solicit .. PJC investigate
unsigned char local_name[256]; // Node name
int interface_num[MAX_INTERFACES];
int interface_errs[MAX_INTERFACES];
int num_interfaces;
unsigned char multicast_incarnation;
int verbosity;
int latcp_socket;
int llogin_socket;
bool do_shutdown;
bool locked;
int next_connection;
gid_t lat_group;
void read_lat(int sock);
double get_loadavg();
void reply_to_enq(unsigned char *inbuf, int len, int interface,
unsigned char *remote_mac);
void process_command_msg(unsigned char *inbuf, int len, int interface,
unsigned char *remote_mac);
void forward_status_messages(unsigned char *inbuf, int len);
void send_service_announcement(int sig);
void send_solicit_messages(int sig);
int make_new_connection(unsigned char *buf, int len, int interface,
LAT_Header *header, unsigned char *macaddr);
int get_next_connection_number();
void add_services(unsigned char *, int, int, unsigned char *);
void got_enqreply(unsigned char *, int, int, unsigned char *);
void accept_latcp(int);
void accept_llogin(int);
void read_latcp(int);
void read_llogin(int);
void print_bitmap(std::ostringstream &, bool, unsigned char *bitmap);
void tidy_dev_directory();
int make_connection(int fd, const char *, const char *, const char *, const char *, const char *, bool);
static void alarm_signal(int sig);
class fdinfo
{
public:
fdinfo(int _fd, LocalPort *_port, fd_type _type):
fd(_fd),
localport(_port),
type(_type)
{}
int get_fd(){return fd;}
LocalPort *get_localport(){return localport;}
fd_type get_type(){return type;}
void set_disabled(bool d)
{
if (d)
type = DISABLED_PTY;
else
type = LOCAL_PTY;
}
bool active()
{
return (!(type == INACTIVE || type == DISABLED_PTY));
}
bool operator==(int _fd)
{
return (type != INACTIVE && fd == _fd);
}
bool operator==(const fdinfo &fdi)
{
return (fd == fdi.fd);
}
bool operator!=(const fdinfo &fdi)
{
return (fd != fdi.fd);
}
bool operator!=(int _fd)
{
return (type == INACTIVE || fd != _fd);
}
private:
int fd;
LocalPort *localport;
fd_type type;
};
class deleted_session
{
private:
fd_type type;
int connection;
unsigned char local_id;
int fd;
public:
deleted_session(fd_type t, int c, unsigned char i, int f):
type(t),
connection(c),
local_id(i),
fd(f)
{}
int get_conn(){return connection;}
unsigned char get_id() {return local_id;}
int get_fd() {return fd;}
fd_type get_type(){return type;}
};
// Class that defines a local (server) service
class serviceinfo
{
public:
serviceinfo(std::string n, int r, bool s, std::string i = std::string(""), int mc=0, char* comm="",
uid_t uid=0, gid_t gid=0):
name(n),
id(i),
command(std::string(comm)),
rating(r),
max_connections(mc),
cur_connections(0),
static_rating(s),
cmd_uid(uid),
cmd_gid(gid)
{
if (command == std::string(""))
command = std::string(LOGIN_BIN);
}
const std::string &get_name() {return name;}
const std::string &get_id() {return id;}
const std::string &get_command() {return command;}
int get_max_connections() {return max_connections;}
int get_cur_connections() {return cur_connections;}
uid_t get_uid() {return cmd_uid;}
gid_t get_gid() {return cmd_gid;}
int get_rating() {return rating;}
bool get_static() {return static_rating;}
void set_rating(int _new_rating, bool _static)
{ rating = _new_rating; static_rating = _static; }
void set_ident(char *_ident)
{ id = std::string(_ident);}
void inc_connections() {cur_connections++;}
void dec_connections() {cur_connections--;}
const bool operator==(serviceinfo &si) { return (si == name);}
const bool operator==(const std::string &nm) { return (nm == name);}
const bool operator!=(serviceinfo &si) { return (si != name);}
const bool operator!=(const std::string &nm) { return (nm != name);}
private:
std::string name;
std::string id;
std::string command;
int rating;
int max_connections;
int cur_connections;
bool static_rating;
uid_t cmd_uid;
gid_t cmd_gid;
};
void process_data(fdinfo &);
void delete_entry(deleted_session &);
void interface_error(int, int);
// Constants
static const int MAX_CONNECTIONS = 255;
// Collections
std::list<fdinfo> fdlist;
std::list<deleted_session> dead_session_list;
std::list<int> dead_connection_list;
std::list<serviceinfo> servicelist;
std::list<LocalPort> portlist;
// Slave Nodes or Dummy Nodes. Well, no-self-advertised nodes
std::list<std::string> slave_nodes;
std::list<std::string> known_slave_nodes;
// Connections indexed by ID
LATConnection *connections[MAX_CONNECTIONS];
// LATCP connections
std::map<int, Circuit*> latcp_circuits;
// LATCP configurable parameters
int circuit_timer; // Default 8 (=80 ms)
unsigned int multicast_timer; // Default 60 (seconds)
int retransmit_limit;// Default 20
int keepalive_timer; // Default 20 (seconds)
bool responder; // Be a service responder (false);
unsigned char groups[32]; // Bitmap of groups
bool groups_set; // Have the server groups been set ?
unsigned char user_groups[32]; // Bitmap of user groups..always in use
LATinterfaces *iface;
// LATCP Circuit callins
public:
void SetResponder(bool onoff) { responder = onoff;}
void Shutdown();
bool add_service(char *name, char *ident, char *command,
int maxcon, uid_t uid, gid_t gid, int _rating, bool _static_rating);
bool set_rating(char *name, int _rating, bool _static_rating);
bool set_ident(char *name, char *ident);
bool remove_service(char *name);
bool remove_port(char *name);
void set_multicast(int newtime);
void set_nodename(unsigned char *);
void unlock();
bool show_characteristics(bool verbose, std::ostringstream &output);
bool show_nodes(bool verbose, std::ostringstream &output);
int create_local_port(unsigned char *, unsigned char *,
unsigned char *, unsigned char *, bool, bool,
unsigned char *);
int make_llogin_connection(int fd, const char *, const char *, const char *, const char *, const char *, bool);
int make_port_connection(int fd, LocalPort *, const char *, const char *, const char *,
const char *, const char *, bool);
int set_servergroups(unsigned char *bitmap);
int unset_servergroups(unsigned char *bitmap);
int set_usergroups(unsigned char *bitmap);
int unset_usergroups(unsigned char *bitmap);
};
syntax highlighted by Code2HTML, v. 0.9.1