--- libaitio/src/sock.c 2013/11/22 08:53:17 1.4.4.8 +++ libaitio/src/sock.c 2013/11/22 09:24:58 1.4.4.9 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: sock.c,v 1.4.4.8 2013/11/22 08:53:17 misho Exp $ +* $Id: sock.c,v 1.4.4.9 2013/11/22 09:24:58 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -124,6 +124,82 @@ end: } static void * +io_txNet(sched_task_t *task) +{ + int wlen; + sock_cli_t *cli = TASK_ARG(task); + sock_t *s = (sock_t*) cli->cli_parent; + + if (s->sock_type == SOCK_STREAM) + wlen = send(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task), 0); + else + wlen = sendto(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task), 0, + &cli->cli_addr.sa, cli->cli_addr.sa.sa_len); + if (wlen < 1) + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, cli->cli_fd); + + taskExit(task, NULL); +} + +static void * +io_txPty(sched_task_t *task) +{ + int wlen; + sock_cli_t *cli = TASK_ARG(task); + + wlen = write(TASK_FD(task), TASK_DATA(task), TASK_DATLEN(task)); + if (wlen < 1) + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, cli->cli_fd); + + taskExit(task, NULL); +} + +static void * +io_rxNet(sched_task_t *task) +{ + int rlen; + sock_cli_t *cli = TASK_ARG(task); + sock_t *s = (sock_t*) cli->cli_parent; + sockaddr_t sa; + socklen_t salen = sizeof sa.ss; + + if (s->sock_type == SOCK_STREAM) + rlen = recv(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[0]), + AIT_LEN(&cli->cli_buf[0]), 0); + else { + rlen = recvfrom(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[0]), + AIT_LEN(&cli->cli_buf[0]), 0, &sa.sa, &salen); + if (e_addrcmp(&cli->cli_addr, &sa, 42)) + goto end; + } + if (rlen < 1) + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, cli->cli_fd); + else + schedWrite(TASK_ROOT(task), io_txPty, cli, cli->cli_pty, + AIT_GET_BUF(&cli->cli_buf[0]), rlen); +end: + schedReadSelf(task); + taskExit(task, NULL); +} + +static void * +io_rxPty(sched_task_t *task) +{ + int rlen; + sock_cli_t *cli = TASK_ARG(task); + + rlen = read(TASK_FD(task), AIT_GET_BUF(&cli->cli_buf[1]), AIT_LEN(&cli->cli_buf[1])); + if (rlen < 1) + schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, cli->cli_fd); + else + schedWrite(TASK_ROOT(task), io_txNet, cli, cli->cli_fd, + AIT_GET_BUF(&cli->cli_buf[1]), rlen); + + schedReadSelf(task); + taskExit(task, NULL); +} + +static void * io_bridgeClient(sched_task_t *task) { int c, rlen; @@ -183,10 +259,10 @@ io_bridgeClient(sched_task_t *task) execv(*argv, argv); break; default: - schedRead(TASK_ROOT(task), io_rxPty, TASK_ARG(task), - cli->cli_pty, NULL, 0); - schedRead(TASK_ROOT(task), io_rxNet, TASK_ARG(task), - cli->cli_fd, NULL, 0); + schedRead(TASK_ROOT(task), io_rxPty, cli, cli->cli_pty, + TASK_ARG(task), 0); + schedRead(TASK_ROOT(task), io_rxNet, cli, cli->cli_fd, + TASK_ARG(task), 0); ioUpdTimerSocket(cli); break; }