Exemplo n.º 1
0
void sess_init(struct irc_session *sess,
               const char *server,
               uint16_t port,
               const char *nick,
               const char *user,
               const char *real,
               const char *pass)
{
    memset(sess, 0, sizeof(*sess));

    sess->channels = hashtable_new_with_free(
            ascii_hash,
            ascii_equal,
            free,
            irc_channel_free);

    sess->capabilities = hashtable_new_with_free(
            ascii_hash,
            ascii_equal,
            free,
            free);

    sess->start = time(NULL);

    strncpy(sess->hostname, server, sizeof(sess->hostname) - 1);
    sess->portno = port;

    strncpy(sess->nick, nick, sizeof(sess->nick) - 1);
    strncpy(sess->user, user, sizeof(sess->user) - 1);
    strncpy(sess->real, real, sizeof(sess->real) - 1);
    strncpy(sess->serverpass, pass, sizeof(sess->serverpass) - 1);

    tokenbucket_init(&sess->quota, FLOODPROT_CAPACITY, FLOODPROT_RATE);
}
Exemplo n.º 2
0
bool sockobj_open(struct sockobj * const obj)
{
    bool             ret      = false;
    int32_t          portsize = 0, flags;
    struct addrinfo *alist    = NULL, *anext = NULL, ahints;
    socklen_t        optlen, optval;
    char             ipport[6];

    if (UTILDEBUG_VERIFY(obj != NULL))
    {
        memset(&ahints, 0, sizeof(struct addrinfo));
        ahints.ai_family    = obj->conf.family;
        ahints.ai_socktype  = obj->conf.type;
        ahints.ai_flags     = AI_V4MAPPED | AI_ADDRCONFIG;
        ahints.ai_protocol  = 0;
        ahints.ai_canonname = NULL;
        ahints.ai_addr      = NULL;
        ahints.ai_next      = NULL;

        portsize = snprintf(ipport, 6, "%d", obj->conf.ipport);

        if ((portsize > 0) &&
            (portsize < 6) &&
            (getaddrinfo(obj->conf.ipaddr, ipport, &ahints, &alist) == 0))
        {
            for (anext = alist; anext != NULL; anext = anext->ai_next)
            {
                if ((anext->ai_family == obj->conf.family) &&
                    ((obj->fd = socket(anext->ai_family,
                                       anext->ai_socktype,
                                       anext->ai_protocol)) != -1))
                {
                    obj->addrself.sockaddr.ss_family = anext->ai_family;

                    inet_pton(obj->addrself.sockaddr.ss_family,
                              obj->conf.ipaddr,
                              utilinet_getaddrfromstorage(&obj->addrself.sockaddr));
                    *utilinet_getportfromstorage(&obj->addrself.sockaddr) = htons(obj->conf.ipport);
                    obj->addrself.addrlen = anext->ai_addrlen;

                    obj->addrpeer.sockaddr.ss_family = anext->ai_family;
                    inet_pton(obj->addrpeer.sockaddr.ss_family,
                              obj->conf.ipaddr,
                              utilinet_getaddrfromstorage(&obj->addrpeer.sockaddr));
                    *utilinet_getportfromstorage(&obj->addrpeer.sockaddr) = htons(obj->conf.ipport);
                    obj->addrpeer.addrlen = anext->ai_addrlen;

                    optlen = sizeof(obj->info.recv.winsize);
                    optval = 1;
                    obj->event.ops.fion_insertfd(&obj->event, obj->fd);
                    flags = fcntl(obj->fd, F_GETFL, 0);

                    if (!obj->event.ops.fion_setflags(&obj->event))
                    {
                        logger_printf(LOGGER_LEVEL_ERROR,
                                      "%s: socket %u event creation failed\n",
                                      __FUNCTION__,
                                      obj->sid,
                                      errno);
                        sockobj_close(obj);
                    }
                    else if (fcntl(obj->fd, F_SETFL, flags | O_NONBLOCK) != 0)
                    {
                        logger_printf(LOGGER_LEVEL_ERROR,
                                      "%s: socket %u O_NONBLOCK option failed (%d)\n",
                                      __FUNCTION__,
                                      obj->sid,
                                      errno);

                    }
                    // @todo - SO_LINGER? etc
                    else if (setsockopt(obj->fd,
                                        SOL_SOCKET,
                                        SO_REUSEADDR,
                                        &optval,
                                        sizeof(optval)) != 0)
                    {
                        logger_printf(LOGGER_LEVEL_ERROR,
                                      "%s: socket %u SO_REUSEADDR option failed (%d)\n",
                                      __FUNCTION__,
                                      obj->sid,
                                      errno);
                        sockobj_close(obj);
                    }
#if defined(SO_REUSEPORT)
                    else if (setsockopt(obj->fd,
                                        SOL_SOCKET,
                                        SO_REUSEPORT,
                                        &optval,
                                        sizeof(optval)) != 0)
                    {
                        logger_printf(LOGGER_LEVEL_ERROR,
                                      "%s: socket %u SO_REUSEPORT option failed (%d)\n",
                                      __FUNCTION__,
                                      obj->sid,
                                      errno);
                        sockobj_close(obj);
                    }
#endif
#if defined(__APPLE__)
                    else if (setsockopt(obj->fd,
                             SOL_SOCKET,
                             SO_NOSIGPIPE,
                             &optval,
                             sizeof(optval)) != 0)
                    {
                        logger_printf(LOGGER_LEVEL_ERROR,
                                      "%s: socket %u SO_NOSIGPIPE option failed (%d)\n",
                                      __FUNCTION__,
                                      obj->sid,
                                      errno);
                        sockobj_close(obj);
                    }
#endif
                    else if (getsockopt(obj->fd,
                                        SOL_SOCKET,
                                        SO_RCVBUF,
                                        &obj->info.recv.winsize,
                                        &optlen) != 0)
                    {
                        logger_printf(LOGGER_LEVEL_ERROR,
                                      "%s: socket %u SO_RCVBUF option failed (%d)\n",
                                      __FUNCTION__,
                                      obj->sid,
                                      errno);
                        sockobj_close(obj);
                    }
                    else if (getsockopt(obj->fd,
                                        SOL_SOCKET,
                                        SO_SNDBUF,
                                        &obj->info.send.winsize,
                                        &optlen) != 0)
                    {
                        logger_printf(LOGGER_LEVEL_ERROR,
                                      "%s: socket %u SO_SNDBUF option failed (%d)\n",
                                      __FUNCTION__,
                                      obj->sid,
                                      errno);
                        sockobj_close(obj);
                    }
                    else
                    {
                        tokenbucket_init(&obj->tb, obj->conf.ratelimitbps);
                        obj->state = SOCKOBJ_STATE_OPEN;
                        ret = true;
                    }

                    break;
                }
            }

            freeaddrinfo(alist);
        }
        else
        {
            logger_printf(LOGGER_LEVEL_ERROR,
                          "%s: failed to get address information (%d)\n",
                          __FUNCTION__,
                          errno);
        }
    }

    return ret;
}