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
