Hi Daniel:
 
Yes, TIPC 1.5.11 does support ancillary data.  However, the ancillary
data is not stored in the data sequence you describe; instead, each item
returned consists of a "struct cmsghdr" field (which describes what the
item is), then optional padding, then the actual value of the item being
returned, then more optional padding.  (Note: I didn't invent this
arrangement -- this is the standard way for socket-based protocols to do
it.)

So, to correctly handle the ancillary data your program needs to walk
the list of items to find the one(s) it is interested in, if they are
present.  Fortunately, there are a set of macros that help you do this.
(See http://linux.die.net/man/3/cmsg for more info.)  The sample code I
have provided gives an example of how this is done.
 
You should also note that TIPC does not support the MSG_ERRQUEUE flag on
receive operations.  Any message that is returned to the sender as
undeliverable arrives in the same receive queue as normal messages do.
 
Regards,
Al
 
*** BEGIN SAMPLE CODE ***

/*
 * Enhanced form of standard recvfrom() that displays
 * any ancillary data accompanying a received message.
 */
 
ssize_t recvfrom_anc(int sd, void *buf, size_t nbytes, int flags,
                     struct sockaddr *from, socklen_t *addrlen)
{
        struct msghdr msg;
        struct iovec iov;
        char anc_buf[CMSG_SPACE(8) + CMSG_SPACE(1024) + CMSG_SPACE(12)];
        struct cmsghdr *anc;
        unsigned char *cptr;
        __u32 *iptr;
        int i;
        int has_addr;
        socklen_t optlen;
        ssize_t sz;

        has_addr = (from != NULL) && (addrlen != NULL);

        iov.iov_base = buf;
        iov.iov_len = nbytes;

        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_name = from;
        msg.msg_namelen = (has_addr) ? *addrlen : 0;
        msg.msg_control = anc_buf;
        msg.msg_controllen = sizeof(anc_buf);

        sz = recvmsg(sd, &msg, flags);
        if (sz >= 0) {
                anc = CMSG_FIRSTHDR(&msg);
                while (anc != NULL) {
                        cptr = CMSG_DATA(anc);

                        if (anc->cmsg_type == TIPC_ERRINFO) {
                                iptr = (__u32 *)cptr;
                                printf("error code = %u, data size = %u
bytes\n",
                                       iptr[0], iptr[1]);
                                /*
                                 * provide the same return code value 
                                 * that TIPC's recv() and recvfrom()
generate
                                 */
                        i = -1;
                                optlen = sizeof(i);
                                getsockopt(sd, SOL_SOCKET, SO_TYPE, &i,
&optlen);
                                if (((i == SOCK_SEQPACKET) || (i ==
SOCK_STREAM))
                                    && (iptr[0] != TIPC_CONN_SHUTDOWN))
                                        sz = -1;
                        } else if (anc->cmsg_type == TIPC_RETDATA) {
                                for (i = anc->cmsg_len - sizeof(*anc); i
> 0; i--) {
                                        printf("returned byte 0x%02x\n",
*cptr);
                                        cptr++;
                                }
                        } else if (anc->cmsg_type == TIPC_DESTNAME) {
                                iptr = (__u32 *)cptr;
                                printf("destination name =
{%u,%u,%u}\n",
                                       iptr[0], iptr[1], iptr[2]);
                        } else {
                                printf("unrecognized ancillary data type
%u\n",
                                       anc->cmsg_type);
                        }

                        anc = CMSG_NXTHDR(&msg, anc);
                }

                if (has_addr)
                        *addrlen = msg.msg_namelen;
        }

        return sz;
}

 
*** END SAMPLE CODE ***


________________________________

        From: XU Yonggang [mailto:[EMAIL PROTECTED] 
        Sent: Tuesday, October 30, 2007 2:22 AM
        To: Stephens, Allan
        Subject: A question about TIPC
        
        
        Hello Allan,
         
        I have a question for TIPC socket API recvmsg(). I am doing a
test to generate a discarded message and reception by sender of a
"returned data message"  + error code. 
        My test result is very strange. The error code is 20, data
length is 50, but the TIPC_RETDATA is \0. and the type , lower instance
and uppper instance is not equal to my setting.
        I want to know whether this TIPC version (1.5.11) supports
recvmsg() ancillary data objects. 
         
         the "msg_control" field of "msg" (if non-NULL).
        Is the following data sequence right?
         
        bytes        4                     4              data length
4                       4                      4
                   |error code | data length |     data              |
type |     lower instance | upper instance
         
         
        Waiting for your response, Thanks.
         
        TIPC version tipc-1.5.11
        TIPC demo version tipc_demo-1.13 connection_demo
         
        
/******************************Output***********************************
*************/
        Connection setup 1: standard (TCP style) connect
        Client: Connection established
        Client: Sent msg "Hello World" 
        Client: recvmsg failed, errcode 20, datalen 50, data 
        type 1114112, lower 1114112, upper 903872512
         
        /******************************code
segment***************************************/
            char sbuf[40];
            char buf[1024];
            char control_buf[1024];
            struct msghdr msg;
            struct iovec iov = { buf, 1024 };
            memset( &msg, 0, sizeof(msg) );
            msg.msg_iov = &iov;
            msg.msg_iovlen = 1;
            msg.msg_control = &control_buf;
            msg.msg_controllen = 1024;
         
            struct ERRINFO
            {
                  int errcode;
                  int datalen;
            };
            char * pdata = NULL;
            struct ERRINFO * errinfo = msg.msg_control;
            pdata = (char *)msg.msg_control + sizeof(struct ERRINFO);
          int * itemp = NULL;
         
            strcpy(sbuf, "Hello World");
            if (0 > send(sd,sbuf,strlen(sbuf)+1,0)){
                perror("Client: Failed to send");
            }
            printf("Client: Sent msg \"%s\" \n", sbuf);
         
            int rc;
            rc = recvmsg(sd, &msg, MSG_ERRQUEUE);
            if (rc < 0)
            {
                printf("rc %d\n", rc);
                perror("recvmsg: ");
                return -1;
            }
            else if (rc == 0)
            {
                printf("Client: recvmsg failed, errcode %d, datalen %d,
data %s\n", errinfo->errcode, errinfo->datalen, pdata);
                itemp = pdata + errinfo->datalen;
                printf("type %d, lower %d, upper %d\n", *itemp, *(itemp
+ 1), *(itemp + 2));
            }
            else
            {
                printf("Client: Received response \"%s\" \n", (char
*)(msg.msg_iov->iov_base));
            }
         
         
        /*******************************programmers guide
*************************************/

        2.1.12 recvmsg

        --------------

        ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)

         

        Attempts to receive a message from the socket.  If successful,
the port ID of the message sender is captured in the "msg_name" field of
"msg" (if non-NULL) and ancillary data relating to the message is
captured in the "msg_control" field of "msg" (if non-NULL).

         

        The following ancillary data objects may be captured:

         

        1) TIPC_ERRINFO - The TIPC error code associated with a returned
data message or a connection termination message, and the length of the
returned data. (8 bytes: error code + data length)

        2) TIPC_RETDATA - The contents of a returned data message, up to
a maximum of 1024 bytes.

        3) TIPC_DESTNAME - The TIPC name or name sequence that was
specified by the sender of the message. (12 bytes: type + lower instance
+ upper instance; the latter two values are the same for a TIPC name,
but may differ for a name sequence)


        Best regards, 
        Daniel Xu 
        =============================================== 
        Alcatel Shanghai Bell Co.,Ltd 
        ASB/MCG/MRD/RDR/NodeB 
        E_mail:  [EMAIL PROTECTED] 
        Address:11F, 40#, Nanchang Rd, Nanjing 
        Alcanet: 27355216, Office Tel: +86-25-84731240*5216 
        =============================================== 


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
tipc-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to