Skip to content
Permalink
Browse files
Add os_dns, a way to control your DNS zone via services
  • Loading branch information
Adam- committed Oct 22, 2012
1 parent d5b2f9c commit 0b9db15efc322336ddb08671ce68a3d45fb22520
Showing 12 changed files with 777 additions and 76 deletions.
@@ -281,6 +281,13 @@ networkinfo
*/
options
{
/*
* On Linux/UNIX systems Anope can setuid and setgid to this user and group
* after starting up. This is useful if Anope has to bind to privileged ports
*/
#user = "anope"
#group = "anope"

/*
* The case mapping used by services. This must be set to a valid locale name
* installed on your machine. Services use this case map to compare, with
@@ -1047,6 +1054,15 @@ dns
* How long to wait in seconds before a DNS query has timed out
*/
timeout = 5

/*
* The port services use to listen for DNS queries.
* Note that ports less than 1024 are privileged on UNIX/Linux systems, and
* require Anope to be started as root. If you do this, it is recommended you
* set options:user and options:group so Anope can change users after binding
* to this port.
*/
port = 53
}

/*
@@ -355,15 +355,61 @@ defcon
}

/*
* os_list
* os_dns
*
* Provides the commands operserv/chanlist and operserv/userlist.
* Provides the command operserv/dns.
*
* Used to list and search the channels and users currently on the network.
* This module allows controlling a DNS zone. This is useful for
* controlling what servers users are placed on for load balancing,
* and to automatically remove split servers.
*
* To use this module you must set a nameserver record for services
* so that DNS queries go to services.
*
* We recommend you use something similar to BIND's query forwarding
* ability to hide service's IP, provide query caching, and provide
* better fault tolerance. To do this, configure BIND similar to:
*
* options {
* dnssec-enable no;
* dnssec-validation no;
* };
* zone "irc.example.com" IN {
* type forward;
* forward first;
* forwarders { 10.0.0.1 port 5353; }; # Where this is the IP and dns:port of services
* };
*
* And then set a NS record for irc.example.com. to BIND.
*/
module { name = "os_list" }
command { service = "OperServ"; name = "CHANLIST"; command = "operserv/chanlist"; }
command { service = "OperServ"; name = "USERLIST"; command = "operserv/userlist"; }
#module { name = "os_dns" }
#command { service = "OperServ"; name = "DNS"; command = "operserv/dns"; permission = "operserv/dns"; }
os_dns
{
/* TTL for records. This should be very low if your records change often. */
ttl = 1m

/* If a server drops this many users the server is automatically removed from the DNS zone.
* This directive is optional.
*/
user_drop_mark = 50

/* The time used for user_drop_mark */
user_drop_time = 1m

/* When a server is removed from the zone for dropping users, it is readded after this time.
* This directive is optional.
*/
user_drop_readd_time = 5m

/* If set, if a server splits it is automatically removed from the zone */
remove_split_servers = yes

/* If set, when a server connects to the network it will be automatically added to
* the zone if it is a known server.
*/
readd_connected_servers = no
}

/*
* os_config
@@ -425,6 +471,17 @@ command { service = "OperServ"; name = "KICK"; command = "operserv/kick"; permis
module { name = "os_kill" }
command { service = "OperServ"; name = "KILL"; command = "operserv/kill"; permission = "operserv/kill"; }

/*
* os_list
*
* Provides the commands operserv/chanlist and operserv/userlist.
*
* Used to list and search the channels and users currently on the network.
*/
module { name = "os_list" }
command { service = "OperServ"; name = "CHANLIST"; command = "operserv/chanlist"; }
command { service = "OperServ"; name = "USERLIST"; command = "operserv/userlist"; }

/*
* os_login
*
@@ -394,6 +394,10 @@ class CoreExport ServerConfig
/* Max length of channel names */
unsigned ChanLen;

/* User and group to run as */
Anope::string User;
Anope::string Group;

/* Casemapping to use */
Anope::string CaseMap;

@@ -494,8 +498,10 @@ class CoreExport ServerConfig

/* Nameserver to use for resolving hostnames */
Anope::string NameServer;
/* TIme before a DNS query is considered dead */
/* Time before a DNS query is considered dead */
time_t DNSTimeout;
/* The port DNS queries come in on */
int DNSPort;

/* Prefix of guest nicks when a user gets forced off of a nick */
Anope::string NSGuestNickPrefix;
@@ -95,7 +95,6 @@ struct CoreExport DNSQuery

DNSQuery();
DNSQuery(const Question &q);
DNSQuery(const DNSPacket &p);
};

/** The request
@@ -124,7 +123,7 @@ class CoreExport DNSRequest : public Timer, public Question
void Tick(time_t) anope_override;
};

/** A full packet sent or recieved to/from the nameserver, may contain multiple queries
/** A full packet sent or recieved to/from the nameserver
*/
class DNSPacket : public DNSQuery
{
@@ -139,12 +138,14 @@ class DNSPacket : public DNSQuery
public:
static const int HEADER_LENGTH = 12;

/* Our 16-bit id for this header */
/* Source or destination of the packet */
sockaddrs addr;
/* ID for this packet */
unsigned short id;
/* Flags on the query */
/* Flags on the packet */
unsigned short flags;

DNSPacket();
DNSPacket(const sockaddrs &a);
void Fill(const unsigned char *input, const unsigned short len);
unsigned short Pack(unsigned char *output, unsigned short output_size);
};
@@ -155,20 +156,19 @@ class CoreExport DNSManager : public Timer, public Socket
{
typedef std::multimap<Anope::string, ResourceRecord, ci::less> cache_map;
cache_map cache;
sockaddrs addrs;
public:

std::deque<DNSPacket *> packets;
public:
sockaddrs addrs;
std::map<unsigned short, DNSRequest *> requests;

static const int DNSPort = 53;

DNSManager(const Anope::string &nameserver, int port);

~DNSManager();

bool ProcessRead();
bool ProcessRead() anope_override;

bool ProcessWrite();
bool ProcessWrite() anope_override;

/** Add a record to the dns cache
* @param r The record
@@ -189,6 +189,15 @@ class CoreExport DNSManager : public Timer, public Socket
*/
void Cleanup(Module *mod);

/** Get the list of packets pending to be sent
*/
std::deque<DNSPacket *>& GetPackets();

/** Queues a packet for sending
* @param p The packet
*/
void SendPacket(DNSPacket *p);

/** Does a BLOCKING DNS query and returns the first IP.
* Only use this if you know what you are doing. Unless you specifically
* need a blocking query use the DNSRequest system
@@ -917,6 +917,11 @@ class CoreExport Module : public Extensible
*/
virtual void OnLog(Log *l) { }

/** Called when a DNS request (question) is recieved.
* @param req The dns request
*/
virtual void OnDnsRequest(DNSPacket &req) { }

/** Called when a channels modes are being checked to see if they are allowed,
* mostly to ensure mlock/+r are set.
* @param c The channel
@@ -995,7 +1000,7 @@ enum Implementation
I_OnServerQuit, I_OnTopicUpdated,
I_OnEncrypt, I_OnDecrypt,
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnLog,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnLog, I_OnDnsRequest,

I_OnSerializeCheck, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate,
I_END
@@ -63,6 +63,9 @@ class CoreExport Server : public Flags<ServerFlag>
~Server();

public:
/* Number of users on the server */
unsigned Users;

/** Delete this server with a reason
* @param reason The reason
*/

0 comments on commit 0b9db15

Please sign in to comment.