Index: ossp-pkg/l2/l2_ch_socket.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ch_socket.c,v rcsdiff -q -kk '-r1.30' '-r1.31' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ch_socket.c,v' 2>/dev/null --- l2_ch_socket.c 2001/10/04 13:35:47 1.30 +++ l2_ch_socket.c 2001/11/02 18:42:51 1.31 @@ -38,57 +38,16 @@ #include "l2.h" #include "l2_p.h" -#if defined(HAVE_INET_PTON) -#define l2_inet_pton inet_pton -#elif defined(HAVE_INET_ATON) - -/****************************************************************** -IPv4 source used from Unix Network Programming by Richard STEVENS - ******************************************************************/ -static int l2_inet_pton(int iFamily, const char *szAddress, void *pvMemref) -{ - int i = 0; - struct in_addr IP4Addr; - struct in6_addr IP6Addr; - const char *szIndex = NULL; /* To index IPv6 validity */ - char *szNextfield = ""; /* For IPv6 address trans */ - - assert(pvMemref != NULL); - if (iFamily == AF_INET) { - if (inet_aton(szAddress, &IP4Addr)) { - memcpy(pvMemref, &IP4Addr, sizeof(struct in_addr)); - return 1; /* Success */ - } - return 0; - } - else if (iFamily == AF_INET6) { /* Translate IPv6 addresses */ - szIndex = szAddress; /* Initialize, verify in loop */ - for (i = 0; (i < 8) && szNextfield; i++) { /* Iterate through fields */ - IP6Addr.__u6_addr.__u6_addr16[i] =\ - ntohs((u_int16_t)strtol(szIndex, &szNextfield, 16)); - szIndex = szNextfield + 1; - } - - if ((i != 8) || (*szNextfield)) - return 0; - else { /* Success */ - memcpy(pvMemref, &IP6Addr, sizeof(struct in6_addr)); - return 1; - } - } - else { /* User converting from an address family that we don't support */ - errno = EAFNOSUPPORT; - return -1; - } -} -#else -#error "neither inet_pton nor inet_aton available" -#endif +#define L2_SOCKET_SABUFREAD 4096 +#define L2_SOCKET_SABUFWRITE 4096 /* declare private channel configuration */ typedef struct { + sa_addr_t *saaServer; + sa_t *saServer; + long lTimeout; + char *szHost; /* IP Address or name of host to connect to */ - int iFamily; /* IP version to use, AF_INET4 or AF_INET6 */ int iProto; /* Protocol to use, IPPROTO_TCP or IPPROTO_UDP */ int iPort; /* TCP Port to connect to */ int iSocket; /* Socket descriptor used during writing */ @@ -104,8 +63,11 @@ return L2_ERR_MEM; /* initialize configuration with reasonable defaults */ + cfg->saaServer = NULL; + cfg->saServer = NULL; + cfg->lTimeout = 30; + cfg->szHost = NULL; - cfg->iFamily = -1; cfg->iProto = -1; cfg->iPort = 0; cfg->iSocket = -1; @@ -121,28 +83,18 @@ { l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; char *szProtocol = NULL; - char *szFamily = NULL; l2_param_t pa[5]; l2_result_t rv; /* feed and call generic parameter parsing engine */ - L2_PARAM_SET(pa[0], ipversion, STRING, szFamily); - L2_PARAM_SET(pa[1], protocol, STRING, szProtocol); + L2_PARAM_SET(pa[0], protocol, STRING, &szProtocol); + L2_PARAM_SET(pa[1], timeout, INT, &cfg->lTimeout); L2_PARAM_SET(pa[2], host, CHARPTR, &cfg->szHost); L2_PARAM_SET(pa[3], port, INT, &cfg->iPort); L2_PARAM_END(pa[4]); rv = l2_util_setparams(pa, fmt, ap); /* translate incoming configuration parameters */ - if (szFamily != NULL) { - if (strcmp(szFamily, "AF_INET6") == 0) - cfg->iFamily = AF_INET6; - else if (strcmp(szFamily, "AF_INET") == 0) - cfg->iFamily = AF_INET; - else - return L2_ERR_ARG; - } - if (szProtocol != NULL) { if (strcmp(szProtocol, "IPPROTO_UDP") == 0) cfg->iProto = IPPROTO_UDP; @@ -152,7 +104,6 @@ return L2_ERR_ARG; } - free(szFamily); free(szProtocol); return rv; } @@ -160,154 +111,53 @@ /* open channel */ static l2_result_t hook_open(l2_context_t *ctx, l2_channel_t *ch) { - l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; - struct hostent *pHostentry; - struct sockaddr_in IP4Localsock, IP4Sockaddr; - struct sockaddr_in6 IP6Localsock, IP6Sockaddr; + sa_rc_t rc; + l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; - /* make sure a target is configured */ + /* make sure a path was set */ if (cfg->szHost == NULL) return L2_ERR_USE; - /* open channel socket */ - if (cfg->iFamily == AF_INET) { /* IPv4 */ - /* initialize address structures */ - memset(&IP4Localsock, 0, sizeof(IP4Localsock)); - memset(&IP4Sockaddr, 0, sizeof(IP4Sockaddr)); - - /* resolve host numerically */ - if (l2_inet_pton(AF_INET, cfg->szHost, &IP4Sockaddr.sin_addr.s_addr) == 1) { - IP4Sockaddr.sin_family = AF_INET; - IP4Sockaddr.sin_port = htons(cfg->iPort); - } - /* resolve host nominally */ - else if ((pHostentry = gethostbyname(cfg->szHost)) != NULL) { - if (pHostentry->h_addrtype == AF_INET) { - IP4Sockaddr.sin_family = AF_INET; - IP4Sockaddr.sin_port = htons(cfg->iPort); - memcpy(&IP4Sockaddr.sin_addr.s_addr, pHostentry->h_addr_list[0], - sizeof(IP4Sockaddr.sin_addr.s_addr)); - } - else - return L2_ERR_USE; /* what?? we specify IPv4 when it is not? */ - } - else /* host string was not parsable for some reason */ - return L2_ERR_SYS; + /* create socket address */ + if ((rc = sa_addr_create(&cfg->saaServer)) != SA_OK) + return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT); + if ((rc = sa_addr_u2a(cfg->saaServer, "inet://%s:%d", + cfg->szHost, cfg->iPort)) != SA_OK) + return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT); + + /* create socket */ + if ((rc = sa_create(&cfg->saServer)) != SA_OK) + return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT); + + /* configure socket parameters */ + sa_timeout(cfg->saServer, SA_TIMEOUT_ALL, cfg->lTimeout, 0); + sa_buffer (cfg->saServer, SA_BUFFER_READ, L2_SOCKET_SABUFREAD); + sa_buffer (cfg->saServer, SA_BUFFER_WRITE, L2_SOCKET_SABUFWRITE); - if (cfg->iProto == IPPROTO_TCP) { /* with TCP we must connect */ - if ((cfg->iSocket = socket(PF_INET, SOCK_STREAM, cfg->iProto)) == -1) - return L2_ERR_SYS; - - /* if we have a socket, then bind ourselves to any port number */ - IP4Localsock.sin_family = AF_INET; - IP4Localsock.sin_addr.s_addr = htonl(INADDR_ANY); - IP4Localsock.sin_port = htons(0); - - if (bind(cfg->iSocket, (struct sockaddr *)&IP4Localsock,\ - sizeof(IP4Localsock))) { - return L2_ERR_SYS; - } - - if (connect(cfg->iSocket, (struct sockaddr *)&IP4Sockaddr, - sizeof(IP4Sockaddr))) { - close(cfg->iSocket); - return L2_ERR_SYS; - } - } - else if (cfg->iProto == IPPROTO_UDP) { /* with UDP we do not connect */ - if ((cfg->iSocket = socket(PF_INET, SOCK_DGRAM, cfg->iProto)) == -1) - return L2_ERR_SYS; - - /* if we have a socket, then bind ourselves to any port number */ - IP4Localsock.sin_family = AF_INET; - IP4Localsock.sin_addr.s_addr = htonl(INADDR_ANY); - IP4Localsock.sin_port = htons(0); - - if (bind(cfg->iSocket, (struct sockaddr *)&IP4Localsock,\ - sizeof(IP4Localsock))) { - return L2_ERR_SYS; - } - } - - return L2_OK; - } - else if (cfg->iFamily == AF_INET6) { /* IPv6 */ - /* initialize address structures */ - memset(&IP6Localsock, 0, sizeof(IP6Localsock)); - memset(&IP6Sockaddr, 0, sizeof(IP6Sockaddr)); - - /* resolve host numerically */ - if (l2_inet_pton(AF_INET6, cfg->szHost, &IP6Sockaddr.sin6_addr.s6_addr) == 1) { - IP6Sockaddr.sin6_family = AF_INET6; - IP6Sockaddr.sin6_port = htons(cfg->iPort); - } - /* resolve host nominally */ - else if ((pHostentry = gethostbyname(cfg->szHost)) != NULL) { - if (pHostentry->h_addrtype == AF_INET6) { - IP6Sockaddr.sin6_family = AF_INET6; - IP6Sockaddr.sin6_port = htons(cfg->iPort); - memcpy(&IP6Sockaddr.sin6_addr.s6_addr, pHostentry->h_addr_list[0],\ - sizeof(IP6Sockaddr.sin6_addr.s6_addr)); - } - else - return L2_ERR_USE; /* what?? we specify IPv6 when it is not? */ - } - else /* host string was not parsable for some reason */ - return L2_ERR_SYS; - - if (cfg->iProto == IPPROTO_TCP) { /* with TCP we must connect */ - if ((cfg->iSocket = socket(PF_INET6, SOCK_STREAM, cfg->iProto)) == -1) - return L2_ERR_SYS; - - /* if we have a socket, then bind ourselves to any port number */ - IP6Localsock.sin6_family = AF_INET6; - IP6Localsock.sin6_addr = in6addr_any; - IP6Localsock.sin6_port = htons(0); - - if (bind(cfg->iSocket, (struct sockaddr *)&IP6Localsock,\ - sizeof(IP6Localsock))) { - return L2_ERR_SYS; - } - - if (connect(cfg->iSocket, (struct sockaddr *)&IP6Sockaddr,\ - sizeof(IP6Sockaddr))) { - close(cfg->iSocket); - return L2_ERR_SYS; - } - } - else if (cfg->iProto == IPPROTO_UDP) { /* with UDP we do not connect */ - if ((cfg->iSocket = socket(PF_INET, SOCK_DGRAM, cfg->iProto)) == -1) - return L2_ERR_SYS; - - /* if we have a socket, then bind ourselves to any port number */ - IP6Localsock.sin6_family = AF_INET6; - IP6Localsock.sin6_addr = in6addr_any; - IP6Localsock.sin6_port = htons(0); - - if (bind(cfg->iSocket, (struct sockaddr *)&IP6Localsock,\ - sizeof(IP6Localsock))) { - return L2_ERR_SYS; - } - } - - return L2_OK; - } - - return L2_ERR_USE; + return L2_OK; } /* write to channel */ static l2_result_t hook_write(l2_context_t *ctx, l2_channel_t *ch, l2_level_t level, const char *buf, size_t buf_size) { - struct sockaddr_in IP4Sockaddr, IP6Sockaddr; - l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; - size_t sizeWrite; - size_t sizeRemain; + l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; + size_t sizeWrite; + size_t sizeRemain; + sa_t *sa; + sa_rc_t rc; + sa_addr_t *saa; /* parameter checks */ - if (cfg->iSocket == -1) - return L2_ERR_ARG; + assert(cfg->saServer != NULL); + + /* establish connection to server */ + saa = cfg->saaServer; + sa = cfg->saServer; + if ((rc = sa_connect(sa, saa)) != SA_OK) { + sa_shutdown(sa, "rw"); /* shutdown connection to server */ + return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT); + } if (cfg->iProto == IPPROTO_TCP) { /* write message to channel socket, but check to make */ @@ -315,39 +165,9 @@ sizeWrite = 0; sizeRemain = buf_size; while(sizeRemain) { - sizeWrite = send(cfg->iSocket, buf + sizeWrite, sizeRemain, 0); + if ((rc = sa_write(sa, buf, sizeRemain, &sizeWrite)) != SA_OK) + return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT); sizeRemain = sizeRemain - sizeWrite; /* how much is left? */ - - if (sizeWrite == -1) - return L2_ERR_SYS; - } - } - else if (cfg->iProto == IPPROTO_UDP) { - /* write message to the host target, but check to make */ - /* sure that the whole message was successfully written */ - sizeWrite = 0; - sizeRemain = buf_size; - while(sizeRemain) { - if (cfg->iFamily == AF_INET) { /* IPv4 */ -/* TODO !!! */ sizeWrite = sendto(cfg->iSocket, buf + sizeWrite, sizeRemain, 0,\ -/* Fill in */ (struct sockaddr *)&IP4Sockaddr, sizeof(IP4Sockaddr)); -/* the host */ -/* address */ sizeRemain = sizeRemain - sizeWrite; /* how much is left? */ -/* structs */ - if (sizeWrite == -1) - return L2_ERR_SYS; - } - else if (cfg->iFamily == AF_INET6) { /* IPv6 */ - /* TODO !!! */ sizeWrite = sendto(cfg->iSocket, buf + sizeWrite, sizeRemain, 0,\ - /* Fill in */ (struct sockaddr *)&IP6Sockaddr, sizeof(IP6Sockaddr)); - /* the host */ - /* address */ sizeRemain = sizeRemain - sizeWrite; /* how much is left? */ - /* structs */ - if (sizeWrite == -1) - return L2_ERR_USE; - } - else /* Neither IPv4 nor IPv6 */ - return L2_ERR_USE; } } @@ -360,12 +180,17 @@ l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp; /* parameter checks */ - if (cfg->iSocket == -1) - return L2_ERR_USE; +/* FIXME! assert(cfg->saServer->fdSocket != -1); */ - /* close channel socket */ - if ((shutdown(cfg->iSocket, SHUT_RDWR)) || (close(cfg->iSocket))) - return L2_ERR_SYS; + /* destroy remote address */ + if (cfg->saServer != NULL) { + sa_destroy(cfg->saServer); + cfg->saServer = NULL; + } + if (cfg->saaServer != NULL) { + sa_addr_destroy(cfg->saaServer); + cfg->saaServer = NULL; + } return L2_OK; } Index: ossp-pkg/l2/l2_test.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_test.c,v rcsdiff -q -kk '-r1.34' '-r1.35' -u '/v/ossp/cvs/ossp-pkg/l2/l2_test.c,v' 2>/dev/null --- l2_test.c 2001/10/22 16:32:29 1.34 +++ l2_test.c 2001/11/02 18:42:51 1.35 @@ -183,12 +183,12 @@ if ((chSock = l2_channel_create(&l2_handler_socket)) == NULL) /* Socket */ die("failed to create socket channel"); - if (l2_channel_configure(chSock, "protocol,ipversion,host,port",\ - "IPPROTO_TCP", "AF_INET", "localhost", 2002) != L2_OK) + if (l2_channel_configure(chSock, "protocol,host,port",\ + "IPPROTO_TCP", "localhost", 2002) != L2_OK) die("failed to configure socket tcp/ipv4 channel"); #if 0 - if (l2_channel_configure(chSock, "protocol,ipversion,host,port",\ - "IPPROTO_TCP", "AF_INET6", "0:0:0:0:0:0:0:1", 2002) != L2_OK) + if (l2_channel_configure(chSock, "protocol,host,port",\ + "IPPROTO_TCP", "0:0:0:0:0:0:0:1", 2002) != L2_OK) die("failed to configure socket tcp/ipv6 channel"); #endif if (l2_channel_open(chSock) != L2_OK)