Server:dunes.p.mojavenet.xyz

From pisswiki
Revision as of 06:00, 13 July 2021 by Clrx (talk | contribs) (→‎Modules)
dunes.p.mojavenet.xyz
Name dunes.p.mojavenet.xyz
Location San Jose, CA
Hosting Provider Oracle
Owner clrx
SID 8SL
Type Leaf
Status Active

ports: 6667, 6697 (SSL) IPv4 & IPv6!


Cool features:

Create a new #channel, get a free +q!

File:Larry.png






Modules

/src/modules/third/certificate-refresh.c

automatically reload your SSL/TLS certificates when they are changed on the filesystem, no need for a cron job.

/* License: GPLv2
*  Author: clrx
*/
#include "unrealircd.h"

ModuleHeader MOD_HEADER
= {
        "third/certificate-refresh", /* name */
        "1.0.0", /* version */
        "Certificate Refresh: Automatically checks SSL/TLS certificates for changes, and reloads SSL/TLS if the certificate has been updated.", /* description */
        "clrx", /* author */
        "unrealircd-5", /* do not change this, it indicates module API version */
};

/*** <<<MODULE MANAGER START>>>
module
{
        // Documentation, as displayed in './unrealircd module info nameofmodule', and possibly at other places:
        documentation "https://www.example.org/";

        // This is displayed in './unrealircd module info ..' and also if compilation of the module fails:
        troubleshooting "In case of problems, check the FAQ at ... or e-mail me at ...";
        min-unrealircd-version "5.*";
        max-unrealircd-version "5.*";

        post-install-text {
                "The module is installed. Now all you need to do is add a loadmodule line:";
                "loadmodule \"third/certificate-refresh\";";
                "And /REHASH the IRCd.";
                "The module does not need any other configuration.";
        }
}
*** <<<MODULE MANAGER END>>>
*/

#define _MCRF_USE_REINIT_SSL (UNREAL_VERSION_GENERATION == 5 && UNREAL_VERSION_MAJOR == 2 && UNREAL_VERSION_MINOR < 1)
#define _MCRF_TIMEOUT 43200000 /* 12 hours, in milliseconds. */

typedef struct mCRF_Watch_File mCRF_Watch_File;

struct mCRF_Watch_File
{
  char *path;
  time_t last_modified;
  mCRF_Watch_File *next;
};

/* Forward Declarations. */
EVENT(mCRF_timeout);
EVENT(mCRF_setup_files);
time_t mCRF_get_cert_time(const char *path);
mCRF_Watch_File *mCRF_add_watch_file(const char *path);
mCRF_Watch_File *mCRF_find_watch_file(const char *path);

static mCRF_Watch_File *watched_files;

EVENT(mCRF_timeout)
{
  TLSOptions *tls_options;
  int needReload = 0;
  mCRF_Watch_File *wptr;

  for (wptr = watched_files; wptr; wptr = wptr->next)
    {
      time_t ts_curr = mCRF_get_cert_time(wptr->path);
      if (ts_curr != wptr->last_modified)
	{
	  needReload = 1;
	  wptr->last_modified = ts_curr;
	}
    }
  
  if (needReload)
    {
      sendto_snomask(SNO_SNOTICE, "*** [third/certificate-refresh]: Server TLS certificate(s) updated, reloading certificates.");
      
#if _MCRF_USE_REINIT_SSL
      reinit_ssl(NULL);
#else
      reinit_tls();
#endif
    }
  
}

EVENT(mCRF_setup_files)
{
  ConfigItem_listen *lptr;
  ConfigItem_sni *sptr;
  TLSOptions *tls_options = get_tls_options_for_client(&me);

  if (tls_options)
    mCRF_add_watch_file(tls_options->certificate_file);

  for (lptr = conf_listen; lptr; lptr = lptr->next)
    {
      tls_options = lptr->tls_options;
      if (tls_options)
	mCRF_add_watch_file(tls_options->certificate_file);
    }

  for (sptr = conf_sni; sptr; sptr = sptr->next)
    {
      mCRF_add_watch_file(sptr->tls_options->certificate_file);
    }

}

time_t mCRF_get_cert_time(const char *path)
{
  time_t r = 0;
  struct stat st;

  if (!stat(path, &st))
    {
      r = st.st_mtime;
    }
  return r;
}

mCRF_Watch_File *mCRF_add_watch_file(const char *path)
{
  mCRF_Watch_File *wptr;

  if (path == NULL)
    return NULL;

  wptr = mCRF_find_watch_file(path);
  if (wptr)
    return wptr;
  
  wptr = safe_alloc(sizeof(mCRF_Watch_File));
  memset(wptr, 0, sizeof(mCRF_Watch_File));
  wptr->path = our_strdup(path);
  wptr->last_modified = mCRF_get_cert_time(wptr->path);

  if (watched_files == NULL)
    {
      watched_files = wptr;
    }
  else
    {
      mCRF_Watch_File *tmp, *prv;
      tmp = watched_files;

      while (tmp != NULL)
	{
	  prv = tmp;
	  tmp = tmp->next;
	}
      prv->next = wptr;
    }

  return wptr;
}

mCRF_Watch_File *mCRF_find_watch_file(const char *path)
{
  mCRF_Watch_File *wptr;
  for (wptr = watched_files; wptr; wptr = wptr->next)
    {
      if (smycmp(path, wptr->path) == 0)
	return wptr;
    }
  return NULL;
}

MOD_INIT()
{
  EventAdd(modinfo->handle, "mCRF_timeout", mCRF_timeout, NULL, _MCRF_TIMEOUT, 0);
  EventAdd(modinfo->handle, "mCRF_setup_files", mCRF_setup_files, NULL, 5 * 1000, 1);
 
  return MOD_SUCCESS;

}
  
MOD_UNLOAD()
{
  mCRF_Watch_File *wptr, *wptri;

  for (wptr = watched_files; wptr; wptr = wptri)
    {
      wptri = wptr->next;
      safe_free(wptr->path);
      safe_free(wptr);
    }

  return MOD_SUCCESS;
}

MOD_TEST()
{
  return MOD_SUCCESS;
}

MOD_LOAD()
{
  return MOD_SUCCESS;
}

/src/modules/third/hyb-statsconn.c

Shows RPL_STATSCONN upon client connection and when LUSERS is called. Doesn't add a lot of value otherwise, but I like how it shows how many actual IRC clients (as opposed to all accept()s in /STATS T) have connected to the server during the current run. I named it hybrid-statsconn since that is the first time I remember seeing this information, but I don't know where this numeric really came from. Oh well :)

[22:56:45] * There are 6 users and 410 invisible on 147 servers

[22:56:45] * 129 operator(s) online

[22:56:45] * 218 channels formed

[22:56:45] * I have 4 clients and 1 servers

[22:56:45] * Current local users 4, max 6

[22:56:45] * Current global users 416, max 1000001

[22:56:45] * Highest connection count: 7 (6 clients) (26 connections received)

(These were the stats after running for about two weeks without a reboot in the round robin)

/* License: GPLv2
*  Author: clrx
*/
#include "unrealircd.h"

ModuleHeader MOD_HEADER
= {
        "third/hyb-statsconn", /* name */
        "1.0.0", /* version */
        "Hyb-StatsConn: Shows RPL_STATSCONN", /* description */
        "clrx", /* author */
        "unrealircd-5", /* do not change this, it indicates module API version */
};

#define RPL_STATSCONN_MESSAGE ":Highest connection count: %d (%d clients) (%ld connections received)"

int m_hyb_statsconn_hook_welcome(Client *acptr, int after_numeric);
int m_hyb_statsconn_hook_local_server_connect(Client *acptr);
int m_hyb_statsconn_rehash_complete(void);
CMD_OVERRIDE_FUNC(m_hyb_statsconn_override);
void m_hyb_statsconn_show_statsconn(Client *acptr);

static long totalrestartcount = 0;
/* Keep track of our handle in order to reinstall the override after each rehash. */
Module *myHandle;

MOD_TEST()
{
  return MOD_SUCCESS;
}

MOD_INIT()
{
  /* Must mark as permanent, or else we will lose our count. */
  ModuleSetOptions(modinfo->handle, MOD_OPT_PERM, 1);

  myHandle = modinfo->handle;
  
  HookAdd(modinfo->handle, HOOKTYPE_SERVER_CONNECT, 0, m_hyb_statsconn_hook_local_server_connect);
  HookAdd(modinfo->handle, HOOKTYPE_WELCOME, 0, m_hyb_statsconn_hook_welcome);
  /* Even if the module is marked as permanent, /REHASH will unload the CommandOverride. So, if we rehash, we need to reload the Override. */
  HookAdd(modinfo->handle, HOOKTYPE_REHASH_COMPLETE, 999, m_hyb_statsconn_rehash_complete);
  return MOD_SUCCESS;
}

MOD_LOAD()
{
  /* Install override on first startup, only run once due to permanent module. */
  m_hyb_statsconn_rehash_complete();
  return MOD_SUCCESS;
}

MOD_UNLOAD()
{
  return MOD_SUCCESS;
}

CMD_OVERRIDE_FUNC(m_hyb_statsconn_override)
{
  CallCommandOverride(ovr, client, recv_mtags, parc, parv);

  /* This is recommended per the Unreal wiki. It's probably unnecessary as at this time
   * lusers does not offer a way to kill the client, and sendbufto_one also checks for a 
   * dead socket. But it doesn't hurt anything and provides future proofing incase
   * other innovations are invented!
   */
  if (IsDead(client))
    return;
  
  if (parc > 1)
    {
      Client *target = find_server(parv[1], NULL);
      if (target != &me)
	return;
    }

  m_hyb_statsconn_show_statsconn(client);
  
}

int m_hyb_statsconn_rehash_complete(void)
{
  /* re-install override after each rehash */
  CommandOverrideAdd(myHandle, "LUSERS", m_hyb_statsconn_override); 
  return HOOK_CONTINUE;
}

int m_hyb_statsconn_hook_local_server_connect(Client *acptr)
{
  /* Only care about local clients, but hooked in for all servers per API. Only increment
   * if client is a local server. */
  if (MyConnect(acptr) && IsServer(acptr))
    totalrestartcount = totalrestartcount + 1;
      
  return HOOK_CONTINUE;
}

int m_hyb_statsconn_hook_welcome(Client *acptr, int after_numeric)
{
  /* Is HOOK_WELCOME called for new servers? Don't know, don't care, be safe. */
  if (!IsUser(acptr))
    return HOOK_CONTINUE;

  if (after_numeric == RPL_GLOBALUSERS)
    {
      /*I haven't read the Unreal source code close enough to know if this is really necessary, but it doesn't hurt anything. */
      if (MyUser(acptr))
	totalrestartcount = totalrestartcount + 1;
      m_hyb_statsconn_show_statsconn(acptr);
    }

  return HOOK_CONTINUE;
}

void m_hyb_statsconn_show_statsconn(Client *acptr)
{
  int l_max_connection_count = max_connection_count;
  char flatmap = (FLAT_MAP && !ValidatePermissionsForPath("server:info:lusers",acptr,NULL,NULL,NULL)) ? 1 : 0;

  /* If we have a low number of users, the numbers won't make sense. */
  if (l_max_connection_count < (irccounts.me_max + irccounts.me_servers))
    l_max_connection_count = irccounts.me_max + irccounts.me_servers;

  if (flatmap)
      l_max_connection_count = irccounts.me_max;

    sendnumericfmt(acptr, RPL_STATSCONN, RPL_STATSCONN_MESSAGE,
		   l_max_connection_count, irccounts.me_max, totalrestartcount);
  
}