raijin
raijin

Reputation: 1

Duplicated Packets Received in UNIX Network Programming About SCTP

Here's my client code:

#include "unp.h"

int main(int argc, char **argv)
{
    int sock_fd;
    struct sockaddr_in servaddr;
    struct sctp_event_subscribe evnts;
    int echo_to_all = 0;

    if (argc < 2)
        err_quit("Missing host argument - use '%s host [echo]'\n",
                 argv[0]);
    if (argc > 2)
    {
        printf("Echoing messages to all streams\n");
        echo_to_all = 1;
    }
    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);
    Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

    bzero(&evnts, sizeof(evnts));
    evnts.sctp_data_io_event = 1;
    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
               &evnts, sizeof(evnts));
    if (echo_to_all == 0)
        sctpstr_cli(stdin, sock_fd, (SA *)&servaddr, sizeof(servaddr));
    else
        sctpstr_cli_echoall(stdin, sock_fd, (SA *)&servaddr, sizeof(servaddr));
    Close(sock_fd);
    return (0);
}

I execute the command with arg echo so that it will go into the function sctpstr_cli_echoall whose code is as followed. This function is going to send one message in every possible stream to the server.

void sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)
{
    struct sockaddr_in peeraddr;
    struct sctp_sndrcvinfo sri;
    char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];
    socklen_t len;
    int rd_sz, i, strsz;
    int msg_flags;

    bzero(sendline, sizeof(sendline));
    bzero(&sri, sizeof(sri));
    while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL)
    {
        strsz = strlen(sendline);
        if (sendline[strsz - 1] == '\n')
        {
            sendline[strsz - 1] = '\0';
            strsz--;
        }
        for (i = 0; i < SERV_MAX_SCTP_STRM; i++)
        {
            snprintf(sendline + strsz, sizeof(sendline) - strsz,
                     ".msg.%d", i);
            Sctp_sendmsg(sock_fd, sendline, sizeof(sendline),
                         to, tolen,
                         0, 0,
                         i,
                         0, 0);
        }
        for (i = 0; i < SERV_MAX_SCTP_STRM; i++)
        {
            len = sizeof(peeraddr);
            rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),
                                 (SA *)&peeraddr, &len,
                                 &sri, &msg_flags);
            printf("From str:%d seq:%d (assoc:0x%x):",
                   sri.sinfo_stream, sri.sinfo_ssn,
                   (unsigned int)sri.sinfo_assoc_id);
            printf("%.*s\n", rd_sz, recvline);
        }
    }
}

The code of server is as follows. It just sends back whatever it received to the client as an echo server. I execute the command with arg 0, which indicates that it will send back the data in the same stream as it received the data.

void sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)
{
    struct sockaddr_in peeraddr;
    struct sctp_sndrcvinfo sri;
    char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];
    socklen_t len;
    int rd_sz, i, strsz;
    int msg_flags;

    bzero(sendline, sizeof(sendline));
    bzero(&sri, sizeof(sri));
    while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL)
    {
        strsz = strlen(sendline);
        if (sendline[strsz - 1] == '\n')
        {
            sendline[strsz - 1] = '\0';
            strsz--;
        }
        for (i = 0; i < SERV_MAX_SCTP_STRM; i++)
        {
            snprintf(sendline + strsz, sizeof(sendline) - strsz,
                     ".msg.%d", i);
            Sctp_sendmsg(sock_fd, sendline, sizeof(sendline),
                         to, tolen,
                         0, 0,
                         i,
                         0, 0);
        }
        for (i = 0; i < SERV_MAX_SCTP_STRM; i++)
        {
            len = sizeof(peeraddr);
            rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),
                                 (SA *)&peeraddr, &len,
                                 &sri, &msg_flags);
            printf("From str:%d seq:%d (assoc:0x%x):",
                   sri.sinfo_stream, sri.sinfo_ssn,
                   (unsigned int)sri.sinfo_assoc_id);
            printf("%.*s\n", rd_sz, recvline);
        }
    }
}
int sctp_get_no_strms(int sock_fd, sctp_assoc_t sinfo_assoc_id)
{
    int retsz;
    struct sctp_status status;
    retsz = sizeof(status);
    bzero(&status, sizeof(status));

    status.sstat_assoc_id = sinfo_assoc_id;
    Getsockopt(sock_fd, IPPROTO_SCTP, SCTP_STATUS,
               &status, &retsz);
    return (status.sstat_outstrms);
}

I run the program and the client output as followed, shows I received the first packet twice.

package data

Hope anyone could help me solve the problem?

Upvotes: 0

Views: 92

Answers (0)

Related Questions