int xmpp_component_child_process(int data_pipe) { int fd, maxfd, rv; fd_set fdset; xode_pool pool; xode_stream stream; struct xmpp_private_data priv; struct xmpp_pipe_cmd *cmd; while (1) { fd = net_connect(xmpp_host, xmpp_port); if (fd < 0) { sleep(3); continue; } curr_fd = fd; priv.fd = fd; priv.running = 1; pool = xode_pool_new(); stream = xode_stream_new(pool, stream_node_callback, &priv); net_printf(fd, "<?xml version='1.0'?>" "<stream:stream xmlns='jabber:component:accept' to='%s' " "version='1.0' xmlns:stream='http://etherx.jabber.org/streams'>", xmpp_domain); while (priv.running) { FD_ZERO(&fdset); FD_SET(data_pipe, &fdset); FD_SET(fd, &fdset); maxfd = fd > data_pipe ? fd : data_pipe; rv = select(maxfd + 1, &fdset, NULL, NULL, NULL); if (rv < 0) { if (errno == EINTR) { continue; } LM_ERR("select() failed: %s\n", strerror(errno)); } else if (!rv) { /* timeout */ } else if (FD_ISSET(fd, &fdset)) { char *buf = net_read_static(fd); if (!buf) /* connection closed */ break; LM_DBG("server read\n[%s]\n", buf); xode_stream_eat(stream, buf, strlen(buf)); } else if (FD_ISSET(data_pipe, &fdset)) { if (read(data_pipe, &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to read from command pipe: %s\n", strerror(errno)); } else { xmpp_component_net_send(cmd, &priv); } } } xode_pool_free(pool); close(fd); } return 0; }
int xmpp_component_child_process(int data_pipe) { int fd, maxfd, rv; fd_set fdset; xode_pool pool; xode_stream stream; struct xmpp_private_data priv; struct xmpp_pipe_cmd *cmd; while (1) { fd = net_connect(xmpp_host, xmpp_port); if (fd < 0) { sleep(3); continue; } priv.fd = fd; priv.running = 1; pool = xode_pool_new(); stream = xode_stream_new(pool, stream_node_callback, &priv); net_printf(fd, "<?xml version='1.0'?>" "<stream:stream xmlns='jabber:component:accept' to='%s' " "version='1.0' xmlns:stream='http://etherx.jabber.org/streams'>", xmpp_domain); while (priv.running) { FD_ZERO(&fdset); FD_SET(data_pipe, &fdset); FD_SET(fd, &fdset); maxfd = fd > data_pipe ? fd : data_pipe; rv = select(maxfd + 1, &fdset, NULL, NULL, NULL); /* update the local config framework structures */ cfg_update(); if (rv < 0) { LM_ERR("select() failed: %s\n", strerror(errno)); } else if (!rv) { /* timeout */ } else if (FD_ISSET(fd, &fdset)) { char *buf = net_read_static(fd); if (!buf) /* connection closed */ break; LM_DBG("server read\n[%s]\n", buf); xode_stream_eat(stream, buf, strlen(buf)); } else if (FD_ISSET(data_pipe, &fdset)) { if (read(data_pipe, &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to read from command pipe: %s\n", strerror(errno)); } else { LM_DBG("got pipe cmd %d\n", cmd->type); switch (cmd->type) { case XMPP_PIPE_SEND_MESSAGE: do_send_message_component(&priv, cmd); break; case XMPP_PIPE_SEND_PACKET: case XMPP_PIPE_SEND_PSUBSCRIBE: case XMPP_PIPE_SEND_PNOTIFY: do_send_bulk_message_component(&priv, cmd); break; } xmpp_free_pipe_cmd(cmd); } } } xode_pool_free(pool); close(fd); } return 0; }
int xmpp_server_child_process(int data_pipe) { int rv; int listen_fd; fd_set fdset; struct xmpp_connection *conn; snprintf(local_secret, sizeof(local_secret), "%s", random_secret()); while ((listen_fd = net_listen(xmpp_domain, xmpp_port)) < 0) { /* ugh. */ sleep(3); } while (1) { FD_ZERO(&fdset); FD_SET(data_pipe, &fdset); FD_SET(listen_fd, &fdset); /* check for dead connections */ for (conn = conn_list; conn; ) { struct xmpp_connection *next = conn->next; if (conn->type == CONN_DEAD) conn_free(conn); conn = next; } for (conn = conn_list; conn; conn = conn->next) { /* check if we need to set up a connection */ if (conn->type == CONN_OUTBOUND && conn->fd == -1) { if ((conn->fd = net_connect(conn->domain, xmpp_port)) >= 0) { net_printf(conn->fd, "<?xml version='1.0'?>" "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:server' version='1.0' " "xmlns:db='jabber:server:dialback' to='%s' from='%s'>", conn->domain, xmpp_domain); net_printf(conn->fd, "<stream:features xmlns:stream='http://etherx.jabber.org/streams'/>"); } else { conn->type = CONN_DEAD; } } if (conn->fd != -1) FD_SET(conn->fd, &fdset); } rv = select(FD_SETSIZE, &fdset, NULL, NULL, NULL); /* update the local config framework structures */ cfg_update(); if (rv < 0) { LM_ERR("select() failed: %s\n", strerror(errno)); } else if (!rv) { /* timeout */ } else { for (conn = conn_list; conn; conn = conn->next) { if (conn->fd != -1 && FD_ISSET(conn->fd, &fdset)) { char *buf = net_read_static(conn->fd); if (!buf) { conn->type = CONN_DEAD; } else { LM_DBG("stream (fd %d, domain '%s') read\n[%s]\n", conn->fd, conn->domain, buf); xode_stream_eat(conn->stream, buf, strlen(buf)); } } } if (FD_ISSET(listen_fd, &fdset)) { struct sockaddr_in sin; unsigned int len = sizeof(sin); int fd; if ((fd = accept(listen_fd,(struct sockaddr*)&sin, &len))<0) { LM_ERR("accept() failed: %s\n", strerror(errno)); } else { LM_DBG("accept()ed connection from %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); conn_new(CONN_INBOUND, fd, NULL); } } if (FD_ISSET(data_pipe, &fdset)) { struct xmpp_pipe_cmd *cmd; if (read(data_pipe, &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to read from command pipe: %s\n", strerror(errno)); } else { LM_DBG("got pipe cmd %d\n", cmd->type); switch (cmd->type) { case XMPP_PIPE_SEND_MESSAGE: do_send_message_server(cmd); break; case XMPP_PIPE_SEND_PACKET: case XMPP_PIPE_SEND_PSUBSCRIBE: case XMPP_PIPE_SEND_PNOTIFY: break; } xmpp_free_pipe_cmd(cmd); } } } } return 0; }