- Added three new interfaces, NgAllocRecvMsg(), NgAllocRecvAsciiMsg(),

and NgAllocRecvData(), that dynamically allocate buffer for a binary
  message, an ascii message, and a data packet, respectively.  The size
  of the allocated buffer is equal to the socket's receive buffer size
  to guarantee that a message or a data packet is not truncated.

- Get rid of the static size buffer in NgSendAsciiMsg().

OK'ed by:	archie, julian
This commit is contained in:
ru 2004-01-27 20:25:14 +00:00
parent f24f6452fe
commit adc82a1e80
5 changed files with 109 additions and 9 deletions

View File

@ -16,9 +16,12 @@ MLINKS+= netgraph.3 NgSendMsg.3
MLINKS+= netgraph.3 NgSendAsciiMsg.3
MLINKS+= netgraph.3 NgSendMsgReply.3
MLINKS+= netgraph.3 NgRecvMsg.3
MLINKS+= netgraph.3 NgAllocRecvMsg.3
MLINKS+= netgraph.3 NgRecvAsciiMsg.3
MLINKS+= netgraph.3 NgAllocRecvAsciiMsg.3
MLINKS+= netgraph.3 NgSendData.3
MLINKS+= netgraph.3 NgRecvData.3
MLINKS+= netgraph.3 NgAllocRecvData.3
MLINKS+= netgraph.3 NgSetDebug.3
MLINKS+= netgraph.3 NgSetErrLog.3

View File

@ -91,13 +91,10 @@ NgSendMsg(int cs, const char *path,
int
NgSendAsciiMsg(int cs, const char *path, const char *fmt, ...)
{
const int bufSize = 1024;
char replybuf[2 * sizeof(struct ng_mesg) + bufSize];
struct ng_mesg *const reply = (struct ng_mesg *)replybuf;
struct ng_mesg *const binary = (struct ng_mesg *)reply->data;
struct ng_mesg *ascii;
struct ng_mesg *reply, *binary, *ascii;
char *buf, *cmd, *args;
va_list fmtargs;
int token;
/* Parse out command and arguments */
va_start(fmtargs, fmt);
@ -139,17 +136,22 @@ NgSendAsciiMsg(int cs, const char *path, const char *fmt, ...)
free(ascii);
/* Get reply */
if (NgRecvMsg(cs, reply, sizeof(replybuf), NULL) < 0)
if (NgAllocRecvMsg(cs, &reply, NULL) < 0)
return (-1);
/* Now send binary version */
binary = (struct ng_mesg *)reply->data;
if (++gMsgId < 0)
gMsgId = 1;
binary->header.token = gMsgId;
if (NgDeliverMsg(cs,
path, binary, binary->data, binary->header.arglen) < 0)
path, binary, binary->data, binary->header.arglen) < 0) {
free(reply);
return (-1);
return (binary->header.token);
}
token = binary->header.token;
free(reply);
return (token);
}
/*
@ -276,6 +278,24 @@ NgRecvMsg(int cs, struct ng_mesg *rep, size_t replen, char *path)
return (-1);
}
/*
* Identical to NgRecvMsg() except buffer is dynamically allocated.
*/
int
NgAllocRecvMsg(int cs, struct ng_mesg **rep, char *path)
{
int len;
socklen_t optlen;
optlen = sizeof(len);
if (getsockopt(cs, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 ||
(*rep = malloc(len)) == NULL)
return (-1);
if ((len = NgRecvMsg(cs, *rep, len, path)) < 0)
free(*rep);
return (len);
}
/*
* Receive a control message and convert the arguments to ASCII
*/
@ -321,3 +341,20 @@ NgRecvAsciiMsg(int cs, struct ng_mesg *reply, size_t replen, char *path)
return (0);
}
/*
* Identical to NgRecvAsciiMsg() except buffer is dynamically allocated.
*/
int
NgAllocRecvAsciiMsg(int cs, struct ng_mesg **reply, char *path)
{
int len;
socklen_t optlen;
optlen = sizeof(len);
if (getsockopt(cs, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 ||
(*reply = malloc(len)) == NULL)
return (-1);
if ((len = NgRecvAsciiMsg(cs, *reply, len, path)) < 0)
free(*reply);
return (len);
}

View File

@ -35,16 +35,22 @@
.\" $FreeBSD$
.\" $Whistle: netgraph.3,v 1.7 1999/01/25 07:14:06 archie Exp $
.\"
.Dd January 19, 1999
.Dd January 27, 2004
.Dt NETGRAPH 3
.Os
.Sh NAME
.Nm NgMkSockNode ,
.Nm NgNameNode ,
.Nm NgSendMsg ,
.Nm NgSendAsciiMsg ,
.Nm NgSendMsgReply ,
.Nm NgRecvMsg ,
.Nm NgAllocRecvMsg ,
.Nm NgRecvAsciiMsg ,
.Nm NgAllocRecvAsciiMsg ,
.Nm NgSendData ,
.Nm NgRecvData ,
.Nm NgAllocRecvData ,
.Nm NgSetDebug ,
.Nm NgSetErrLog
.Nd netgraph user library
@ -71,12 +77,18 @@
.Ft int
.Fn NgRecvMsg "int cs" "struct ng_mesg *rep" "size_t replen" "char *path"
.Ft int
.Fn NgAllocRecvMsg "int cs" "struct ng_mesg **rep" "char *path"
.Ft int
.Fn NgRecvAsciiMsg "int cs" "struct ng_mesg *rep" "size_t replen" "char *path"
.Ft int
.Fn NgAllocRecvAsciiMsg "int cs" "struct ng_mesg **rep" "char *path"
.Ft int
.Fn NgSendData "int ds" "const char *hook" "const u_char *buf" "size_t len"
.Ft int
.Fn NgRecvData "int ds" "u_char *buf" "size_t len" "char *hook"
.Ft int
.Fn NgAllocRecvData "int ds" "u_char **buf" "char *hook"
.Ft int
.Fn NgSetDebug "int level"
.Ft void
.Fo NgSetErrLog
@ -204,6 +216,15 @@ The length of the control message is returned.
A return value of zero indicates that the socket was closed.
.Pp
The
.Fn NgAllocRecvMsg
function works exactly like
.Fn NgRecvMsg ,
except that the buffer for a message is dynamically allocated
to guarantee that a message is not truncated.
The size of the buffer is equal to the socket's receive buffer size.
The caller is responsible for freeing the buffer when it is no longer required.
.Pp
The
.Fn NgRecvAsciiMsg
function works exactly like
.Fn NgRecvMsg ,
@ -222,6 +243,15 @@ version of the arguments (and the reply
header argument length field will be adjusted).
.Pp
The
.Fn NgAllocRecvAsciiMsg
function works exactly like
.Fn NgRecvAsciiMsg ,
except that the buffer for a message is dynamically allocated
to guarantee that a message is not truncated.
The size of the buffer is equal to the socket's receive buffer size.
The caller is responsible for freeing the buffer when it is no longer required.
.Pp
The
.Fn NgSendData
function writes a data packet out on the specified hook of the node
corresponding to data socket
@ -252,6 +282,15 @@ The length of the packet is returned.
A return value of zero indicates that the socket was closed.
.Pp
The
.Fn NgAllocRecvData
function works exactly like
.Fn NgRecvData ,
except that the buffer for a data packet is dynamically allocated
to guarantee that a data packet is not truncated.
The size of the buffer is equal to the socket's receive buffer size.
The caller is responsible for freeing the buffer when it is no longer required.
.Pp
The
.Fn NgSetDebug
and
.Fn NgSetErrLog

View File

@ -54,9 +54,12 @@ int NgSendAsciiMsg(int, const char *, const char *, ...) __printflike(3, 4);
int NgSendReplyMsg(int, const char *,
const struct ng_mesg *, const void *, size_t);
int NgRecvMsg(int, struct ng_mesg *, size_t, char *);
int NgAllocRecvMsg(int, struct ng_mesg **, char *);
int NgRecvAsciiMsg(int, struct ng_mesg *, size_t, char *);
int NgAllocRecvAsciiMsg(int, struct ng_mesg **, char *);
int NgSendData(int, const char *, const u_char *, size_t);
int NgRecvData(int, u_char *, size_t, char *);
int NgAllocRecvData(int, u_char **, char *);
int NgSetDebug(int);
void NgSetErrLog(void (*)(const char *fmt, ...),
void (*)(const char *fmt, ...));

View File

@ -242,6 +242,24 @@ NgRecvData(int ds, u_char * buf, size_t len, char *hook)
return (rtn);
}
/*
* Identical to NgRecvData() except buffer is dynamically allocated.
*/
int
NgAllocRecvData(int ds, u_char **buf, char *hook)
{
int len;
socklen_t optlen;
optlen = sizeof(len);
if (getsockopt(ds, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 ||
(*buf = malloc(len)) == NULL)
return (-1);
if ((len = NgRecvData(ds, *buf, len, hook)) < 0)
free(*buf);
return (len);
}
/*
* Write a packet to a data socket. The packet will be sent
* out the corresponding node on the specified hook.