--- 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;
}
|