static int notify_send(struct sockaddr *to, char *zone_name) { int s; dns_sock_t *sock; if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { plog_error(LOG_ERR, MODULE, "socket() failed"); return -1; } if (connect(s, to, SALEN(to)) < 0) { plog_error(LOG_ERR, MODULE, "connect() failed"); close(s); return -1; } if ((sock = dns_sock_udp_new(s, &SockPropNotify)) == NULL) { plog_error(LOG_ERR, MODULE, "dns_sock_add_udp() failed"); close(s); return -1; } if (notify_send_message(sock, zone_name) < 0) { plog(LOG_ERR, "%s: dns_notify_send() failed", MODULE); dns_sock_free(sock); return -1; } return 0; }
int dns_util_socket_sa(int pf, int type, struct sockaddr *sa) { int s, on = 1; if ((s = socket(pf, type, 0)) < 0) { plog_error(LOG_ERR, MODULE, "socket() failed"); return -1; } if (pf == PF_INET6) { if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { plog_error(LOG_ERR, MODULE, "setsockopt(IPV6_V6ONLY) failed"); return -1; } } if (type == SOCK_STREAM) { if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { plog_error(LOG_ERR, MODULE, "setsockopt(SO_REUSEADDR) failed"); return -1; } } if (bind(s, (SA *) sa, SALEN(sa)) < 0) { plog_error(LOG_ERR, MODULE, "bind() failed"); return -1; } return s; }
bool pnet_server_start(pnet_socket *socket, const char *address) { if (unlikely(!address)) { plog_error("pnet_server_start() нет строки адреса"); return false; } if (unlikely(!pnet_internal_create_socket(socket, NN_REP))) { return false; } socket->endpoint_id = nn_bind(socket->socket_fd, address); if (unlikely(socket->endpoint_id < 0)) { plog_error("pnet_server_start() не удалось bind() | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } if (unlikely(!pnet_internal_get_socketfd(socket))) { return false; } socket->started = true; return true; }
bool pnet_internal_create_socket(pnet_socket *socket, pint16 type) { if (unlikely(!socket)) { plog_error("pnet_internal_create_socket() нет объекта socket"); return false; } int sock = nn_socket(AF_SP_RAW, type); if (unlikely(sock < 0)) { plog_error("pnet_internal_create_socket() не удалось создать сокет | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } socket->socket_fd = sock; int val = 1; if (unlikely(nn_setsockopt(socket->socket_fd, NN_TCP, NN_TCP_NODELAY, &val, sizeof(val)))) { plog_error("pnet_internal_create_socket() не удалось выставить NN_TCP_NODELAY | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } val = 0; if (unlikely(nn_setsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_LINGER, &val, sizeof(val)))) { plog_error("pnet_internal_create_socket() не удалось выставить NN_LINGER | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } val = 10000; if (unlikely(nn_setsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_RECONNECT_IVL_MAX, &val, sizeof(val)))) { plog_error("pnet_internal_create_socket() не удалось выставить NN_RECONNECT_IVL_MAX | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } return true; }
pint32 pnet_send(pnet_socket *socket, char *buffer) { if (unlikely(!socket)) { plog_error("pnet_send() нет объекта socket"); return -1; } if (unlikely(!buffer)) { plog_error("pnet_send() нет buffer"); return -1; } //int bytes = nn_send(socket->socket_fd, buffer, strlen(buffer), NN_DONTWAIT); struct nn_msghdr hdr; struct nn_iovec iov [2]; puint32 buf0 = ++rra | 0x80000000; char buf1 [10] = { 0 }; strcpy(buf1, buffer); iov [0].iov_base = &buf0; iov [0].iov_len = 4; iov [1].iov_base = buf1; iov [1].iov_len = sizeof (buf1); memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = iov; hdr.msg_iovlen = 2; int bytes = nn_sendmsg (socket->socket_fd, &hdr, NN_DONTWAIT); plog_dbg("pnet_send() send %d", bytes); //int rc = nn_freemsg(buffer); // plog_dbg("rc == %d", rc); return bytes; }
pint32 pnet_recv(pnet_socket *socket, char **buffer) { if (unlikely(!socket)) { plog_error("pnet_recv() нет объекта socket"); return -1; } if (unlikely(!buffer)) { plog_error("pnet_recv() buffer неверен"); return -1; } int bytes = nn_recv(socket->socket_fd, buffer, NN_MSG, NN_DONTWAIT); //int bytes = nn_recvmsg(socket->socket_fd, (struct nn_msghdr *)buffer, NN_DONTWAIT); /* struct nn_msghdr hdr; struct nn_iovec iov [2]; char buf0 [10] = { 0 }; char buf1 [6] = { 0 }; iov [0].iov_base = buf0; iov [0].iov_len = sizeof (buf0); iov [1].iov_base = buf1; iov [1].iov_len = sizeof (buf1); memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = iov; hdr.msg_iovlen = 2; int bytes = nn_recvmsg(socket->socket_fd, &hdr, NN_DONTWAIT); printf("%d | %s | %s\n", bytes, buf0, buf1); *buffer = strdup(buf0); */ return bytes; }
void pcore_hash_done(phash_pool *ptr) { phash_pool pool = (*ptr); if (!pool) { plog_error("%s(): Нет phash_pool!", __PRETTY_FUNCTION__); return; } plog_dbg("%s(): Очистка пула 0x%08X", __PRETTY_FUNCTION__, pool); tommy_node* i = tommy_list_head(pool->list); while (i) { tommy_node* i_next = i->next; if (!pcore_hash_deleteObject((phash_object*)&i->data)) { break; } i = i_next; } switch (pool->type) { case PHASH_FAST_SEARCH: tommy_hashdyn_done((tommy_hashdyn *)pool->hash_struct); break; case PHASH_FAST_INSERT: default: tommy_hashtable_done((tommy_hashtable *)pool->hash_struct); break; } pfree(&pool->hash_struct); pfree(&pool->list); pfree(&pool); }
int sf_socket_poll_wait(sf_instance_t *inst, int poll_fd, struct timeval *timeout) { int i, count; struct kevent kev[8]; struct timespec ts0, *ts = NULL; if (timeout != NULL) { ts0.tv_sec = timeout->tv_sec; ts0.tv_nsec = timeout->tv_usec * 1000; ts = &ts0; } if ((count = kevent(poll_fd, NULL, 0, kev, NELEMS(kev), ts)) < 0) { plog_error(LOG_ERR, "%s: kevent() failed", __func__); return -1; } for (i = 0; i < count; i++) { if (kev[i].filter == EVFILT_WRITE) sf_socket_write_event(inst, kev[i].udata); } for (i = 0; i < count; i++) { if (kev[i].filter == EVFILT_READ) sf_socket_read_event(inst, kev[i].udata); } return 0; }
int dns_util_select(int s, int timeout) { int r; fd_set fds; struct timeval tv, *timo; FD_ZERO(&fds); FD_SET(s, &fds); tv.tv_sec = timeout; tv.tv_usec = 0; again: timo = (timeout > 0) ? &tv : NULL; if ((r = select(s + 1, &fds, NULL, NULL, timo)) < 0) { if (errno == EAGAIN || errno == EINTR) goto again; plog_error(LOG_ERR, MODULE, "select() failed"); } if (r > 0 && FD_ISSET(s, &fds)) return 0; return -1; }
bool pnet_internal_get_socketfd(pnet_socket *socket) { size_t sd_size = sizeof(int); if (unlikely(nn_getsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_RCVFD, &socket->recv_fd, &sd_size))) { plog_error("pnet_server_start() не удалось получить NN_RCVFD | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } if (unlikely(nn_getsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_SNDFD, &socket->send_fd, &sd_size))) { plog_error("pnet_server_start() не удалось получить NN_SNDFD | %s (%d)", nn_strerror(nn_errno()), nn_errno()); return false; } return true; }
int dns_util_spawn(char *cmd, char **argv, int out) { int status; pid_t pchild, pgchild, rpid; if ((pchild = fork()) < 0) { plog_error(LOG_ERR, MODULE, "fork() failed"); return -1; } if (pchild == 0) { /* * child process: * don't call log functions because these are not async-signal-safe. */ if (out > 0 && dup2(out, 1) < 0) exit(EXIT_FAILURE); if ((pgchild = fork()) < 0) exit(EXIT_FAILURE); if (pgchild == 0) { if (execvp(cmd, argv) < 0) { plog_error(LOG_ERR, MODULE, "execvp() faild: %s", cmd); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); } else { /* parent process */ if ((rpid = waitpid(pchild, &status, 0)) < 0) { plog_error(LOG_ERR, MODULE, "%s: waitpid() faild"); return -1; } else if (rpid == pchild) { if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { plog(LOG_ERR, "%s: exec() faild: %s", MODULE, cmd); return -1; } } } return 0; }
int dns_util_setugid(int uid, int gid) { if (gid > 0) { if (setgid(gid) < 0) { plog_error(LOG_ERR, NULL, "setgid() failed"); return -1; } } if (uid > 0) { if (setuid(uid) < 0) { plog_error(LOG_ERR, NULL, "setuid() failed"); return -1; } } return 0; }
int dns_util_sa2str_wop(char *buf, int bufmax, struct sockaddr *sa) { if (getnameinfo(sa, SALEN(sa), buf, bufmax, NULL, 0, NI_NUMERICHOST) != 0) { plog_error(LOG_ERR, MODULE, "getnameinfo() failed"); return -1; } return 0; }
void pcore_hash_foreach(phash_pool pool, void (*ret_func)(const puint32 value, void* const data)) { if (!pool) { plog_error("%s(): Нет phash_pool!", __PRETTY_FUNCTION__); return; } if (!ret_func) { plog_error("%s(): Нет функции для вызова!", __PRETTY_FUNCTION__); return; } plog_dbg("%s(): Перебор пула 0x%08X и обращение к 0x%08X", __PRETTY_FUNCTION__, pool, &ret_func); tommy_node* i = tommy_list_head(pool->list); while (i) { phash_object obj = i->data; i = i->next; ret_func(obj->value, obj->data); } }
static bool pcore_hash_deleteObject(phash_object *object) { if (!object || !(*object)) { plog_error("%s(): Нет phash_object!", __PRETTY_FUNCTION__); return false; } plog_dbg("%s(): Очистка ресурсов 0x%08X со значением '%d'", __PRETTY_FUNCTION__, *object, (*object)->value); void *adr = *object; pfree(&adr); return true; }
static void notify_log(dns_sock_t *sock, char *zone_name) { char buf[64]; socklen_t slen; struct sockaddr_storage ss; slen = sizeof(ss); if (getpeername(sock->sock_fd, (SA *) &ss, &slen) < 0) { plog_error(LOG_ERR, MODULE, "getpeername() failed"); return; } dns_util_sa2str_wop(buf, sizeof(buf), (SA *) &ss); plog(LOG_INFO, "send notify to %s (zone \"%s\")", buf, zone_name); }
void pnet_socket_destroy(pnet_socket *socket) { if (unlikely(!socket)) { plog_error("pnet_socket_destroy() нет объекта socket"); return; } if (unlikely(!socket->socket_fd)) { return; } nn_shutdown(socket->socket_fd, 0); nn_close(socket->socket_fd); socket->socket_fd = 0; socket->endpoint_id = 0; socket->started = false; }
static int notify_sock_recv(dns_sock_buf_t *sbuf, dns_sock_t *sock) { int len; socklen_t fromlen; fromlen = sizeof(sbuf->sb_remote); if ((len = recvfrom(sock->sock_fd, sbuf->sb_buf, sizeof(sbuf->sb_buf), 0, (SA *) &sbuf->sb_remote, &fromlen)) < 0) { if (errno != EAGAIN) plog_error(LOG_ERR, MODULE, "recvfrom() failed"); return -1; } return len; }
static phash_object pcore_hash_newObject(const puint32 value, void* const data) { if (!data) { plog_error("%s(): Нет данных для сопоставления!", __PRETTY_FUNCTION__); return NULL; } plog_dbg("%s(): Подготовка нового объекта со значение '%d' и указателем на данные 0x%08X", __PRETTY_FUNCTION__, value, data); phash_object object = pmalloc_check(__PRETTY_FUNCTION__, sizeof(struct s_phash_object)); if (!object) { return NULL; } object->value = value; object->data = data; return object; }
void pcore_hash_insert(phash_pool pool, const puint32 value, void* const data) { if (!pool) { plog_error("%s(): Нет phash_pool!", __PRETTY_FUNCTION__); return; } plog_dbg("%s(): Вставка ресурсов со значением '%d'", __PRETTY_FUNCTION__, value); phash_object object = pcore_hash_newObject(value, data); tommy_list_insert_tail(pool->list, &object->list_node, object); switch (pool->type) { case PHASH_FAST_SEARCH: tommy_hashdyn_insert((tommy_hashdyn *)pool->hash_struct, &object->hash_node, object, tommy_inthash_u32(object->value)); break; case PHASH_FAST_INSERT: default: tommy_hashtable_insert((tommy_hashtable *)pool->hash_struct, &object->hash_node, object, tommy_inthash_u32(object->value)); break; } }
puint32 pcore_hash_size(phash_pool pool) { if (!pool) { plog_error("%s(): Нет phash_pool!", __PRETTY_FUNCTION__); return -1; } puint32 ret = 0; plog_dbg("%s(): Подсчёт количества элементов у пула 0x%08X", __PRETTY_FUNCTION__, pool); switch (pool->type) { case PHASH_FAST_SEARCH: ret = tommy_hashdyn_count((tommy_hashdyn *)pool->hash_struct); break; case PHASH_FAST_INSERT: default: ret = tommy_hashtable_count((tommy_hashtable *)pool->hash_struct); break; } return ret; }
void* pcore_hash_search(phash_pool pool, const puint32 value) { if (!pool) { plog_error("%s(): Нет phash_pool!", __PRETTY_FUNCTION__); return NULL; } plog_dbg("%s(): Поиск в пуле 0x%08X значения '%d'", __PRETTY_FUNCTION__, pool, value); phash_object ret = NULL; switch (pool->type) { case PHASH_FAST_SEARCH: ret = tommy_hashdyn_search((tommy_hashdyn *)pool->hash_struct, compare_hash_uint32, &value, tommy_inthash_u32(value)); break; case PHASH_FAST_INSERT: default: ret = tommy_hashtable_search((tommy_hashtable *)pool->hash_struct, compare_hash_uint32, &value, tommy_inthash_u32(value)); break; } return ret->data; }