int match_cidr(const char *s1, const char *s2) { struct irc_inaddr ipaddr, maskaddr; char mask[BUFSIZE]; char address[NICKLEN + USERLEN + HOSTLEN + 6]; char *ipmask; char *ip; char *len; int cidrlen, aftype; strcpy(mask, s1); strcpy(address, s2); ipmask = strrchr(mask, '@'); if(ipmask == NULL) return 0; *ipmask++ = '\0'; ip = strrchr(address, '@'); if(ip == NULL) return 0; *ip++ = '\0'; len = strrchr(ipmask, '/'); if(len == NULL) return 0; *len++ = '\0'; cidrlen = atoi(len); if(cidrlen == 0) return 0; #ifdef IPV6 if(strchr(ip, ':') && strchr(ipmask, ':')) aftype = AF_INET6; else #endif if(!strchr(ip, ':') && !strchr(ipmask, ':')) aftype = AF_INET; else return 0; inetpton(aftype, ip, &ipaddr); inetpton(aftype, ipmask, &maskaddr); if(comp_with_mask(&IN_ADDR(ipaddr), &IN_ADDR(maskaddr), cidrlen) && match(mask, address)) return 1; else return 0; }
int connect_to_server(t_graphic *c) { c->server.sin_family = AF_INET; c->server.sin_port = htons(c->port); if (((c->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 && my_perror(SYSCALL("socket"), FAILURE) == FAILURE) || (inet_aton(c->ip, IN_ADDR(&c->server.sin_addr.s_addr)) == -1 && my_perror(SYSCALL("inet_aton"), FAILURE) == FAILURE) || (connect(c->socket, C_SOCKADDR(&c->server), sizeof(c->server)) == -1 && my_perror(SYSCALL("connect"), FAILURE) == FAILURE)) return (close_graphic(c, FAILURE)); printf("Graphic trying to connect\n"); return (check_fds(c)); }
int dns_rr_to_sa(DNS_RR *rr, unsigned port, struct sockaddr *sa, SOCKADDR_SIZE *sa_length) { SOCKADDR_SIZE sock_addr_len; if (rr->type == T_A) { if (rr->data_len != sizeof(SOCK_ADDR_IN_ADDR(sa))) { errno = EINVAL; return (-1); } else if ((sock_addr_len = sizeof(*SOCK_ADDR_IN_PTR(sa))) > *sa_length) { errno = ENOSPC; return (-1); } else { memset((void *) SOCK_ADDR_IN_PTR(sa), 0, sock_addr_len); SOCK_ADDR_IN_FAMILY(sa) = AF_INET; SOCK_ADDR_IN_PORT(sa) = port; SOCK_ADDR_IN_ADDR(sa) = IN_ADDR(rr->data); #ifdef HAS_SA_LEN sa->sa_len = sock_addr_len; #endif *sa_length = sock_addr_len; return (0); } #ifdef HAS_IPV6 } else if (rr->type == T_AAAA) { if (rr->data_len != sizeof(SOCK_ADDR_IN6_ADDR(sa))) { errno = EINVAL; return (-1); } else if ((sock_addr_len = sizeof(*SOCK_ADDR_IN6_PTR(sa))) > *sa_length) { errno = ENOSPC; return (-1); } else { memset((void *) SOCK_ADDR_IN6_PTR(sa), 0, sock_addr_len); SOCK_ADDR_IN6_FAMILY(sa) = AF_INET6; SOCK_ADDR_IN6_PORT(sa) = port; SOCK_ADDR_IN6_ADDR(sa) = IN6_ADDR(rr->data); #ifdef HAS_SA_LEN sa->sa_len = sock_addr_len; #endif *sa_length = sock_addr_len; return (0); } #endif } else { errno = EAFNOSUPPORT; return (-1); } }
static struct Listener* make_listener(int port, struct irc_inaddr *addr) { struct Listener* listener = (struct Listener*) MyMalloc(sizeof(struct Listener)); assert(0 != listener); listener->name = me.name; listener->fd = -1; copy_s_addr(IN_ADDR(listener->addr),PIN_ADDR(addr)); listener->port = port; listener->next = NULL; return listener; }
static void accept_connection(int pfd, void *data) { static time_t last_oper_notice = 0; struct irc_sockaddr sai; struct irc_inaddr addr; int fd; int pe; struct Listener * listener = data; assert(listener != NULL); if(listener == NULL) return; /* * There may be many reasons for error return, but * in otherwise correctly working environment the * probable cause is running out of file descriptors * (EMFILE, ENFILE or others?). The man pages for * accept don't seem to list these as possible, * although it's obvious that it may happen here. * Thus no specific errors are tested at this * point, just assume that connections cannot * be accepted until some old is closed first. */ fd = comm_accept(listener->fd, &sai); copy_s_addr(IN_ADDR(addr), S_ADDR(sai)); #ifdef IPV6 if((IN6_IS_ADDR_V4MAPPED(&IN_ADDR2(addr))) || (IN6_IS_ADDR_V4COMPAT(&IN_ADDR2(addr)))) { memmove(&addr.sins.sin.s_addr, addr.sins.sin6.s6_addr+12, sizeof(struct in_addr)); sai.sins.sin.sin_family = AF_INET; } #endif if (fd < 0) { /* Re-register a new IO request for the next accept .. */ comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ, accept_connection, listener, 0); return; } /* * check for connection limit */ if ((MAXCONNECTIONS - 10) < fd) { ++ServerStats->is_ref; /* * slow down the whining to opers bit */ if((last_oper_notice + 20) <= CurrentTime) { sendto_realops_flags(UMODE_ALL, L_ALL,"All connections in use. (%s)", get_listener_name(listener)); last_oper_notice = CurrentTime; } send(fd, "ERROR :All connections in use\r\n", 32, 0); fd_close(fd); /* Re-register a new IO request for the next accept .. */ comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ, accept_connection, listener, 0); return; } /* Do an initial check we aren't connecting too fast or with too many * from this IP... */ if ((pe = conf_connect_allowed(&addr, sai.sins.sin.sin_family)) != 0) { ServerStats->is_ref++; /* XXX - this can only be BANNED_CLIENT? */ switch (pe) { case BANNED_CLIENT: send(fd, DLINE_WARNING, sizeof(DLINE_WARNING)-1, 0); break; } fd_close(fd); /* Re-register a new IO request for the next accept .. */ comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ, accept_connection, listener, 0); return; } ServerStats->is_ac++; add_connection(listener, fd); /* Re-register a new IO request for the next accept .. */ comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ, accept_connection, listener, 0); }
static int inetport(struct Listener* listener) { struct irc_sockaddr lsin; int fd; int opt = 1; /* * At first, open a new socket */ fd = comm_open(DEF_FAM, SOCK_STREAM, 0, "Listener socket"); #ifdef IPV6 if (!IN6_ARE_ADDR_EQUAL((struct in6_addr *)&listener->addr, &in6addr_any)) { #else if (INADDR_ANY != listener->addr.sins.sin.s_addr) { #endif inetntop(DEF_FAM, &IN_ADDR(listener->addr), listener->vhost, HOSTLEN); listener->name = listener->vhost; } if (fd == -1) { report_error(L_ALL, "opening listener socket %s:%s", get_listener_name(listener), errno); return 0; } else if ((HARD_FDLIMIT - 10) < fd) { report_error(L_ALL, "no more connections left for listener %s:%s", get_listener_name(listener), errno); fd_close(fd); return 0; } /* * XXX - we don't want to do all this crap for a listener * set_sock_opts(listener); */ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &opt, sizeof(opt))) { report_error(L_ALL, "setting SO_REUSEADDR for listener %s:%s", get_listener_name(listener), errno); fd_close(fd); return 0; } /* * Bind a port to listen for new connections if port is non-null, * else assume it is already open and try get something from it. */ memset(&lsin, 0, sizeof(struct irc_sockaddr)); S_FAM(lsin) = DEF_FAM; copy_s_addr(S_ADDR(lsin), IN_ADDR(listener->addr)); S_PORT(lsin) = htons(listener->port); if (bind(fd, (struct sockaddr*) &SOCKADDR(lsin), sizeof(struct irc_sockaddr))) { report_error(L_ALL, "binding listener socket %s:%s", get_listener_name(listener), errno); fd_close(fd); return 0; } if (listen(fd, HYBRID_SOMAXCONN)) { report_error(L_ALL, "listen failed for %s:%s", get_listener_name(listener), errno); fd_close(fd); return 0; } /* * XXX - this should always work, performance will suck if it doesn't */ if (!set_non_blocking(fd)) report_error(L_ALL, NONB_ERROR_MSG, get_listener_name(listener), errno); listener->fd = fd; /* Listen completion events are READ events .. */ accept_connection(fd, listener); return 1; } static struct Listener* find_listener(int port, struct irc_inaddr *addr) { struct Listener* listener = NULL; struct Listener* last_closed = NULL; for (listener = ListenerPollList; listener; listener = listener->next) { if ( (port == listener->port) && (!memcmp(&PIN_ADDR(addr), &IN_ADDR(listener->addr), sizeof(struct irc_inaddr)))) { /* Try to return an open listener, otherwise reuse a closed one */ if (listener->fd == -1) last_closed = listener; else return listener; } } return last_closed; } /* * add_listener- create a new listener * port - the port number to listen on * vhost_ip - if non-null must contain a valid IP address string in * the format "255.255.255.255" */ void add_listener(int port, const char* vhost_ip) { struct Listener* listener; struct irc_inaddr vaddr; /* * if no port in conf line, don't bother */ if (port == 0) return; #ifdef IPV6 copy_s_addr(IN_ADDR(vaddr), &in6addr_any); #else copy_s_addr(IN_ADDR(vaddr), INADDR_ANY); #endif if (vhost_ip) { if(inetpton(DEF_FAM, vhost_ip, &IN_ADDR(vaddr)) <= 0) return; } if ((listener = find_listener(port, &vaddr))) { if (listener->fd > -1) return; } else { listener = make_listener(port, &vaddr); listener->next = ListenerPollList; ListenerPollList = listener; } listener->fd = -1; if (inetport(listener)) listener->active = 1; else close_listener(listener); } /* * close_listener - close a single listener */ void close_listener(struct Listener* listener) { assert(listener != NULL); if(listener == NULL) return; if (listener->fd >= 0) { fd_close(listener->fd); listener->fd = -1; } listener->active = 0; if (listener->ref_count) return; free_listener(listener); }