Listing 3. read_sctp_msg.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <netinet/sctp.h>

/* call by
     nread = read_sctp_msg(sockfd, &msg)
*/
int read_sctp_msg(int sockfd, uint8_t **p_msg) {
        int rcv_buf_size;
        int rcv_buf_size_len = sizeof(rcv_buf_size);
        uint8_t *buf;
        struct sockaddr_in peeraddr;
        int peer_len = sizeof(peeraddr);
        struct sctp_sndrcvinfo sri;
        int total_read = 0;

        *p_msg = NULL; /* default fail value */

        if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
                       &rcv_buf_size, &rcv_buf_size_len) == -1) {
                return -1;
        }
        if ((buf = malloc(rcv_buf_size)) == NULL) {
                return -1;
        }

        while (1) {
                int nread;
                int flags;

                nread = sctp_recvmsg(sockfd, buf+total_read,rcv_buf_size,
                                     (struct sockaddr *)
&peeraddr,&peer_len,
                                     &sri, &flags);
                if (nread < 0) {
                        return nread;
                }
                total_read += nread;

                if (flags & MSG_EOR) {
                        /* trim the buf and return msg */
                        printf("Trimming buf to %d\n", total_read);
                        *p_msg = realloc(buf, total_read);
                        return total_read;
                }
                buf = realloc(buf, total_read + rcv_buf_size);
        }

        /* error to get here? */
        free(buf);
        return -1;
}

