mirror of
https://github.com/3cky/mbusd.git
synced 2024-10-01 04:27:42 +02:00
Add IPv6 support (#53)
This commit is contained in:
parent
2aa063db79
commit
88916fe82d
34
src/conn.c
34
src/conn.c
@ -139,26 +139,28 @@ conn_open(void)
|
|||||||
{
|
{
|
||||||
int sd;
|
int sd;
|
||||||
conn_t *newconn;
|
conn_t *newconn;
|
||||||
struct sockaddr_in rmt_addr;
|
struct sockaddr_storage rmt_addr;
|
||||||
|
char ipstr[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
if ((sd = sock_accept(server_sd, &rmt_addr, TRUE)) == RC_ERR)
|
if ((sd = sock_accept(server_sd, (struct sockaddr *)&rmt_addr,
|
||||||
|
sizeof(rmt_addr), TRUE)) == RC_ERR)
|
||||||
{ /* error in conn_accept() */
|
{ /* error in conn_accept() */
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(0, "conn_open(): error in accept() (%s)", strerror(errno));
|
logw(0, "conn_open(): error in accept() (%s)", strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
inet_ntop(rmt_addr.ss_family, sock_addr((struct sockaddr *)&rmt_addr),
|
||||||
|
ipstr, sizeof(ipstr));
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(2, "conn_open(): accepting connection from %s",
|
logw(2, "conn_open(): accepting connection from %s", ipstr);
|
||||||
inet_ntoa(rmt_addr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
/* compare descriptor of connection with FD_SETSIZE */
|
/* compare descriptor of connection with FD_SETSIZE */
|
||||||
if (sd >= FD_SETSIZE)
|
if (sd >= FD_SETSIZE)
|
||||||
{
|
{
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(1, "conn_open(): FD_SETSIZE limit reached,"
|
logw(1, "conn_open(): FD_SETSIZE limit reached,"
|
||||||
" connection from %s will be dropped",
|
" connection from %s will be dropped", ipstr);
|
||||||
inet_ntoa(rmt_addr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
close(sd);
|
close(sd);
|
||||||
return;
|
return;
|
||||||
@ -168,8 +170,7 @@ conn_open(void)
|
|||||||
{
|
{
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(1, "conn_open(): number of connections limit reached,"
|
logw(1, "conn_open(): number of connections limit reached,"
|
||||||
" connection from %s will be dropped",
|
" connection from %s will be dropped", ipstr);
|
||||||
inet_ntoa(rmt_addr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
close(sd);
|
close(sd);
|
||||||
return;
|
return;
|
||||||
@ -177,8 +178,7 @@ conn_open(void)
|
|||||||
/* enqueue connection */
|
/* enqueue connection */
|
||||||
newconn = queue_new_elem(&queue);
|
newconn = queue_new_elem(&queue);
|
||||||
newconn->sd = sd;
|
newconn->sd = sd;
|
||||||
memcpy((void *) &newconn->sockaddr,
|
memcpy((void *) &newconn->remote_addr, &ipstr, sizeof(ipstr));
|
||||||
&rmt_addr, sizeof(struct sockaddr_in));
|
|
||||||
state_conn_set(newconn, CONN_HEADER);
|
state_conn_set(newconn, CONN_HEADER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,8 +192,7 @@ conn_close(conn_t *conn)
|
|||||||
{
|
{
|
||||||
conn_t *nextconn;
|
conn_t *nextconn;
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(2, "conn_close(): closing connection from %s",
|
logw(2, "conn_close(): closing connection from %s", conn->remote_addr);
|
||||||
inet_ntoa(conn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
/* close socket */
|
/* close socket */
|
||||||
close(conn->sd);
|
close(conn->sd);
|
||||||
@ -535,15 +534,13 @@ conn_loop(void)
|
|||||||
if (curconn->state == CONN_TTY)
|
if (curconn->state == CONN_TTY)
|
||||||
{ /* deadlock in CONN_TTY state, make attempt to reinitialize serial port */
|
{ /* deadlock in CONN_TTY state, make attempt to reinitialize serial port */
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(0, "conn[%s]: state CONN_TTY deadlock.",
|
logw(0, "conn[%s]: state CONN_TTY deadlock.", curconn->remote_addr);
|
||||||
inet_ntoa(curconn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
tty_reinit();
|
tty_reinit();
|
||||||
}
|
}
|
||||||
/* purge connection */
|
/* purge connection */
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(2, "conn[%s]: timeout, closing connection",
|
logw(2, "conn[%s]: timeout, closing connection", curconn->remote_addr);
|
||||||
inet_ntoa(curconn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
curconn = conn_close(curconn);
|
curconn = conn_close(curconn);
|
||||||
continue;
|
continue;
|
||||||
@ -789,8 +786,7 @@ conn_loop(void)
|
|||||||
/* check request function code */
|
/* check request function code */
|
||||||
unsigned char fc = MB_FRAME(curconn->buf, MB_FCODE);
|
unsigned char fc = MB_FRAME(curconn->buf, MB_FCODE);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
logw(7, "conn[%s]: read request fc %d",
|
logw(7, "conn[%s]: read request fc %d", curconn->remote_addr, fc);
|
||||||
inet_ntoa(curconn->sockaddr.sin_addr), fc);
|
|
||||||
#endif
|
#endif
|
||||||
switch (fc)
|
switch (fc)
|
||||||
{
|
{
|
||||||
@ -849,7 +845,7 @@ conn_loop(void)
|
|||||||
sprintf(v, "[%2.2x]", curconn->buf[i]);
|
sprintf(v, "[%2.2x]", curconn->buf[i]);
|
||||||
strncat(t, v, 1024-strlen(t));
|
strncat(t, v, 1024-strlen(t));
|
||||||
}
|
}
|
||||||
logw(5, "conn[%s]: request: %s", inet_ntoa(curconn->sockaddr.sin_addr), t);
|
logw(5, "conn[%s]: request: %s", curconn->remote_addr, t);
|
||||||
#endif
|
#endif
|
||||||
state_conn_set(curconn, CONN_TTY);
|
state_conn_set(curconn, CONN_TTY);
|
||||||
if (tty.state == TTY_READY)
|
if (tty.state == TTY_READY)
|
||||||
|
@ -104,7 +104,7 @@ typedef struct conn_t
|
|||||||
int sd; /* socket descriptor */
|
int sd; /* socket descriptor */
|
||||||
int state; /* current state */
|
int state; /* current state */
|
||||||
int timeout; /* timeout value, secs */
|
int timeout; /* timeout value, secs */
|
||||||
struct sockaddr_in sockaddr; /* connection structure */
|
char remote_addr[INET6_ADDRSTRLEN]; /* remote client address */
|
||||||
int ctr; /* counter of data in the buffer */
|
int ctr; /* counter of data in the buffer */
|
||||||
int read_len; /* length of modbus frame to read */
|
int read_len; /* length of modbus frame to read */
|
||||||
unsigned char buf[HDRSIZE + BUFSIZE]; /* data buffer */
|
unsigned char buf[HDRSIZE + BUFSIZE]; /* data buffer */
|
||||||
|
58
src/sock.c
58
src/sock.c
@ -58,12 +58,11 @@ sock_set_blkmode(int sd, int blkmode)
|
|||||||
* Return: socket descriptor, otherwise RC_ERR if there some errors
|
* Return: socket descriptor, otherwise RC_ERR if there some errors
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sock_create(int blkmode)
|
sock_create(int blkmode, sa_family_t sa_family)
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
if ((sock =
|
if ((sock = socket(sa_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
||||||
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
|
||||||
{
|
{
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(0, "sock_create(): unable to create socket (%s)",
|
logw(0, "sock_create(): unable to create socket (%s)",
|
||||||
@ -96,17 +95,23 @@ sock_create(int blkmode)
|
|||||||
int
|
int
|
||||||
sock_create_server(char *server_ip, unsigned short server_port, int blkmode)
|
sock_create_server(char *server_ip, unsigned short server_port, int blkmode)
|
||||||
{
|
{
|
||||||
struct sockaddr_in server_sockaddr;
|
struct sockaddr_storage server_sockaddr;
|
||||||
int sock_opt = 1;
|
int sock_opt = 1;
|
||||||
int server_s;
|
int server_s;
|
||||||
|
|
||||||
memset(&server_sockaddr, 0, sizeof(server_sockaddr));
|
memset(&server_sockaddr, 0, sizeof(server_sockaddr));
|
||||||
server_sockaddr.sin_family = AF_INET; // FIXME IPv6 support
|
|
||||||
|
|
||||||
/* parse address to bind socket */
|
/* parse address to bind socket */
|
||||||
if (server_ip != NULL)
|
if (server_ip != NULL)
|
||||||
{
|
{
|
||||||
if (inet_aton(server_ip, &server_sockaddr.sin_addr) == 0)
|
/* try first to parse server_ip as IPv6 address, if it fail, try to parse as IPv4 */
|
||||||
|
if (inet_pton(AF_INET6, server_ip,
|
||||||
|
&(*((struct sockaddr_in6 *)&server_sockaddr)).sin6_addr) != 0)
|
||||||
|
server_sockaddr.ss_family = AF_INET6;
|
||||||
|
else if (inet_pton(AF_INET, server_ip,
|
||||||
|
&(*((struct sockaddr_in *)&server_sockaddr)).sin_addr) != 0)
|
||||||
|
server_sockaddr.ss_family = AF_INET;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(0, "sock_create_server():"
|
logw(0, "sock_create_server():"
|
||||||
@ -117,12 +122,23 @@ sock_create_server(char *server_ip, unsigned short server_port, int blkmode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
{
|
||||||
|
server_sockaddr.ss_family = AF_INET; // TODO AF_INET6/in6addr_any?
|
||||||
|
(*((struct sockaddr_in *)&server_sockaddr)).sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
server_sockaddr.sin_port = htons(server_port);
|
/* parse IP port */
|
||||||
|
switch (server_sockaddr.ss_family) {
|
||||||
|
case AF_INET:
|
||||||
|
(*((struct sockaddr_in *)&server_sockaddr)).sin_port = htons(server_port);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
(*((struct sockaddr_in6 *)&server_sockaddr)).sin6_port = htons(server_port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* create socket in desired blocking mode */
|
/* create socket in desired blocking mode */
|
||||||
server_s = sock_create(blkmode);
|
server_s = sock_create(blkmode, server_sockaddr.ss_family);
|
||||||
if (server_s < 0) return server_s;
|
if (server_s < 0) return server_s;
|
||||||
|
|
||||||
/* set to close socket on exec() */
|
/* set to close socket on exec() */
|
||||||
@ -165,8 +181,8 @@ sock_create_server(char *server_ip, unsigned short server_port, int blkmode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* bind socket to given address and port */
|
/* bind socket to given address and port */
|
||||||
if (bind(server_s, (struct sockaddr *) & server_sockaddr,
|
if (bind(server_s, (struct sockaddr *)&server_sockaddr,
|
||||||
sizeof(server_sockaddr)) == -1)
|
sa_len((struct sockaddr *)&server_sockaddr)) == -1)
|
||||||
{
|
{
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
logw(0, "sock_create_server():"
|
logw(0, "sock_create_server():"
|
||||||
@ -198,13 +214,11 @@ sock_create_server(char *server_ip, unsigned short server_port, int blkmode)
|
|||||||
* RMT_ADDR - ptr to connection info structure
|
* RMT_ADDR - ptr to connection info structure
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sock_accept(int server_sd, struct sockaddr_in *rmt_addr, int blkmode)
|
sock_accept(int server_sd, struct sockaddr *rmt_addr, socklen_t rmt_len, int blkmode)
|
||||||
{
|
{
|
||||||
int sd, sock_opt = SOCKBUFSIZE;
|
int sd, sock_opt = SOCKBUFSIZE;
|
||||||
int rmt_len = sizeof(struct sockaddr_in);
|
|
||||||
|
|
||||||
sd = accept(server_sd, (struct sockaddr *) rmt_addr,
|
sd = accept(server_sd, rmt_addr, &rmt_len);
|
||||||
(socklen_t *) &rmt_len);
|
|
||||||
if (sd == -1)
|
if (sd == -1)
|
||||||
{
|
{
|
||||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||||
@ -241,3 +255,17 @@ sock_accept(int server_sd, struct sockaddr_in *rmt_addr, int blkmode)
|
|||||||
}
|
}
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return reference to socket address structure according to its family (AF_INET/AF_INET6)
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
sock_addr(struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
if (sa->sa_family == AF_INET)
|
||||||
|
{
|
||||||
|
return &(((struct sockaddr_in*)sa)->sin_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(((struct sockaddr_in6*)sa)->sin6_addr);
|
||||||
|
}
|
||||||
|
12
src/sock.h
12
src/sock.h
@ -44,11 +44,13 @@
|
|||||||
/* Socket buffers size */
|
/* Socket buffers size */
|
||||||
#define SOCKBUFSIZE 512
|
#define SOCKBUFSIZE 512
|
||||||
|
|
||||||
|
#define sa_len(sa_ptr) ((sa_ptr)->sa_family == AF_INET \
|
||||||
|
? sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6))
|
||||||
|
|
||||||
int sock_set_blkmode(int sd, int blkmode);
|
int sock_set_blkmode(int sd, int blkmode);
|
||||||
int sock_create(int blkmode);
|
int sock_create(int blkmode, sa_family_t sa_family);
|
||||||
int sock_create_server(char *server_ip,
|
int sock_create_server(char *server_ip, unsigned short server_port, int blkmode);
|
||||||
unsigned short server_port, int blkmode);
|
int sock_accept(int server_sd, struct sockaddr *rmt_addr, socklen_t rmt_len, int blkmode);
|
||||||
int sock_accept(int server_sd,
|
void *sock_addr(struct sockaddr *sa);
|
||||||
struct sockaddr_in *rmt_addr, int blkmode);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
21
src/state.c
21
src/state.c
@ -76,47 +76,40 @@ state_conn_set(conn_t *conn, int state)
|
|||||||
conn->ctr = 0;
|
conn->ctr = 0;
|
||||||
conn->read_len = HDRSIZE;
|
conn->read_len = HDRSIZE;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
logw(5, "conn[%s]: state now is CONN_HEADER",
|
logw(5, "conn[%s]: state now is CONN_HEADER", conn->remote_addr);
|
||||||
inet_ntoa(conn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case CONN_RQST_FUNC:
|
case CONN_RQST_FUNC:
|
||||||
conn->read_len = HDRSIZE + MB_FRAME(conn->buf, MB_LENGTH_L);
|
conn->read_len = HDRSIZE + MB_FRAME(conn->buf, MB_LENGTH_L);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
logw(5, "conn[%s]: state now is CONN_RQST_FUNC",
|
logw(5, "conn[%s]: state now is CONN_RQST_FUNC", conn->remote_addr);
|
||||||
inet_ntoa(conn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case CONN_RQST_NVAL:
|
case CONN_RQST_NVAL:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
logw(5, "conn[%s]: state now is CONN_RQST_NVAL",
|
logw(5, "conn[%s]: state now is CONN_RQST_NVAL", conn->remote_addr);
|
||||||
inet_ntoa(conn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case CONN_RQST_TAIL:
|
case CONN_RQST_TAIL:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
logw(5, "conn[%s]: state now is CONN_RQST_TAIL",
|
logw(5, "conn[%s]: state now is CONN_RQST_TAIL", conn->remote_addr);
|
||||||
inet_ntoa(conn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case CONN_TTY:
|
case CONN_TTY:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
logw(5, "conn[%s]: state now is CONN_TTY",
|
logw(5, "conn[%s]: state now is CONN_TTY", conn->remote_addr);
|
||||||
inet_ntoa(conn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case CONN_RESP:
|
case CONN_RESP:
|
||||||
conn->ctr = 0;
|
conn->ctr = 0;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
logw(5, "conn[%s]: state now is CONN_RESP",
|
logw(5, "conn[%s]: state now is CONN_RESP", conn->remote_addr);
|
||||||
inet_ntoa(conn->sockaddr.sin_addr));
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unknown state, exiting */
|
/* unknown state, exiting */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
logw(5, "conn_set_state([%s]) - invalid state (%d)",
|
logw(5, "conn_set_state([%s]) - invalid state (%d)", conn->remote_addr, state);
|
||||||
inet_ntoa(conn->sockaddr.sin_addr), state);
|
|
||||||
#endif
|
#endif
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user