static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) { tcp_sockdata_t *sock; int sock_id; int rc; ipc_call_t answer; log_msg(LVL_DEBUG, "tcp_sock_socket()"); rc = tcp_sock_create(client, &sock); if (rc != EOK) { async_answer_0(callid, rc); return; } sock->laddr.ipv4 = TCP_IPV4_ANY; sock->lconn = NULL; sock->backlog = 0; sock_id = SOCKET_GET_SOCKET_ID(call); rc = tcp_sock_finish_setup(sock, &sock_id); if (rc != EOK) { tcp_sock_uncreate(sock); async_answer_0(callid, rc); return; } SOCKET_SET_SOCKET_ID(answer, sock_id); SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE); SOCKET_SET_HEADER_SIZE(answer, sizeof(tcp_header_t)); async_answer_3(callid, EOK, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); }
void telnet_init() { sock_telnet.rbuf.buf = telnet_rcv_buffer; sock_telnet.rbuf.length = TELNET_RCV_SIZE; sock_telnet.rbuf.start = 0; sock_telnet.rbuf.stop = 0; sock_telnet.sbuf.buf = telnet_snd_buffer; sock_telnet.sbuf.length = TELNET_SND_SIZE; sock_telnet.sbuf.start = 0; sock_telnet.sbuf.stop = 0; tcp_sock_create(&sock_telnet, 23); tcp_sock_listen(&sock_telnet); }
bool tcp_sock_active_init(t_sock *sock, char *host, int port) { struct sockaddr_in sock_addr; if ((*sock == -1 && (*sock = tcp_sock_create()) == -1) || tcp_sock_get_addr(&sock_addr, inet_addr(host), port) == NULL) return (false); if (connect(*sock, (const struct sockaddr *)&sock_addr, sizeof(sock_addr)) == -1) { close(*sock); return (print_perror("socket connection failed")); } return (true); }
/* ** These functions are callable in two different ways ** depending on what the first argument is : ** - a pointer to t_sock returned by tcp_sock_create() ** - a pointer to a t_sock set to -1 ** ** If the socket received as argument was not a ** pre-created socket then these functions will create one ** before initializing it and storing it in the pointer. ** ** Also, if either of theses functions fail, the socket will ** be closed and no longer valid. */ bool tcp_sock_passive_init(t_sock *sock, int port, int nbClients) { struct sockaddr_in sock_addr; if ((*sock == -1 && (*sock = tcp_sock_create()) == -1) || tcp_sock_get_addr(&sock_addr, INADDR_ANY, port) == NULL) return (false); if (bind(*sock, (const struct sockaddr *)&sock_addr, sizeof(sock_addr)) == -1) { close(*sock); return (print_perror("failed to bind socket to address")); } if (tcp_sock_set_reusable(sock, true) == false) return (false); if (nbClients == 0 || listen(*sock, nbClients) == -1) { close(*sock); return (print_perror("failed to set socket as passive")); } return (true); }
static void tcp_sock_accept(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) { ipc_call_t answer; int socket_id; int asock_id; socket_core_t *sock_core; tcp_sockdata_t *socket; tcp_sockdata_t *asocket; tcp_error_t trc; tcp_sock_t lsocket; tcp_sock_t fsocket; tcp_conn_t *conn; tcp_conn_t *rconn; tcp_sock_lconn_t *lconn; int rc; log_msg(LVL_DEBUG, "tcp_sock_accept()"); socket_id = SOCKET_GET_SOCKET_ID(call); asock_id = SOCKET_GET_NEW_SOCKET_ID(call); sock_core = socket_cores_find(&client->sockets, socket_id); if (sock_core == NULL) { async_answer_0(callid, ENOTSOCK); return; } socket = (tcp_sockdata_t *)sock_core->specific_data; fibril_mutex_lock(&socket->lock); log_msg(LVL_DEBUG, " - verify socket->conn"); if (socket->conn != NULL) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, EINVAL); return; } if (list_empty(&socket->ready)) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, ENOENT); return; } lconn = list_get_instance(list_first(&socket->ready), tcp_sock_lconn_t, ready_list); list_remove(&lconn->ready_list); conn = lconn->conn; tcp_uc_set_cstate_cb(conn, NULL, NULL); /* Replenish listening connection */ lsocket.addr.ipv4 = TCP_IPV4_ANY; lsocket.port = sock_core->port; fsocket.addr.ipv4 = TCP_IPV4_ANY; fsocket.port = TCP_PORT_ANY; trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, tcp_open_nonblock, &rconn); if (rconn == NULL) { /* XXX Clean up */ fibril_mutex_unlock(&socket->lock); async_answer_0(callid, ENOMEM); return; } tcp_uc_set_cstate_cb(rconn, tcp_sock_cstate_cb, lconn); assert(trc == TCP_EOK); rconn->name = (char *)"S"; lconn->conn = rconn; /* Allocate socket for accepted connection */ rc = tcp_sock_create(client, &asocket); if (rc != EOK) { fibril_mutex_unlock(&socket->lock); async_answer_0(callid, rc); return; } asocket->conn = conn; log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n"); rc = tcp_sock_finish_setup(asocket, &asock_id); if (rc != EOK) { tcp_sock_uncreate(asocket); fibril_mutex_unlock(&socket->lock); async_answer_0(callid, rc); return; } fibril_add_ready(asocket->recv_fibril); log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n"); SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE); SOCKET_SET_SOCKET_ID(answer, asock_id); SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in)); async_answer_3(callid, asocket->sock_core->socket_id, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); /* Push one fragment notification to client's queue */ log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n"); fibril_mutex_unlock(&socket->lock); }