File: errors-t.c

package info (click to toggle)
lbcd 3.5.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,708 kB
  • sloc: ansic: 11,073; sh: 1,816; perl: 503; makefile: 165
file content (145 lines) | stat: -rw-r--r-- 5,225 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * Test for lbcd server error handling and replies.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2013
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * See LICENSE for licensing terms.
 */

#include <config.h>
#include <portable/socket.h>
#include <portable/system.h>

#include <time.h>

#include <server/protocol.h>
#include <tests/tap/basic.h>
#include <tests/tap/lbcd.h>
#include <util/network.h>


int
main(void)
{
    socket_type fd;
    struct sockaddr_in sin;
    size_t size;
    ssize_t result;
    struct lbcd_reply reply;
    struct lbcd_request request;
    char *buffer;

    /* Declare a plan. */
    plan(15);

    /* Start the lbcd daemon with no special flags. */
    lbcd_start(NULL);

    /* Set up our client socket. */
    fd = network_client_create(PF_INET, SOCK_DGRAM, "127.0.0.1");
    if (fd == INVALID_SOCKET)
        sysbail("cannot create client socket");
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(14330);
    sin.sin_addr.s_addr = htonl(0x7f000001UL);
    if (connect(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0)
        sysbail("cannot connect client socket");

    /* Send a truncated packet.  There should be no reply to this. */
    memset(&request, 0, sizeof(request));
    request.h.version = htons(3);
    request.h.id = htons(10);
    request.h.op = htons(LBCD_OP_LBINFO);
    result = send(fd, &request, sizeof(struct lbcd_header) / 2, 0);
    if (result != (ssize_t) sizeof(struct lbcd_header) / 2)
        sysbail("cannot send truncated request");

    /* Send a request with too many services.  Similarly, no reply. */
    memset(&request, 0, sizeof(request));
    request.h.version = htons(3);
    request.h.id = htons(10);
    request.h.op = htons(LBCD_OP_LBINFO);
    request.h.status = htons(LBCD_MAX_SERVICES + 1);
    size = sizeof(struct lbcd_request) + sizeof(lbcd_name_type);
    buffer = bcalloc(1, size);
    memcpy(buffer, &request, sizeof(request));
    result = send(fd, buffer, size, 0);
    if (result != (ssize_t) size)
        sysbail("cannot send request with too many services");
    free(buffer);

    /* Send a too-long request.  Similarly, no reply. */
    request.h.status = 0;
    result = send(fd, &request, sizeof(request), 0);
    if (result != (ssize_t) sizeof(request))
        sysbail("cannot send too-long request");

    /*
     * Okay, finally a request to which we should get a reply.  Send a request
     * for an unknown protocol version.
     */
    request.h.version = htons(LBCD_VERSION + 1);
    result = send(fd, &request, sizeof(struct lbcd_header), 0);
    if (result != (ssize_t) sizeof(struct lbcd_header))
        sysbail("cannot send unknown version query");
    memset(&reply, 0, sizeof(reply));
    result = recv(fd, &reply, sizeof(reply), 0);

    /*
     * We should get back an error message.  This is where we also test that
     * we're in synchronization and aren't getting weird errors from our
     * previous bad packets.
     */
    is_int(sizeof(struct lbcd_header), result,
           "Unknown version error reply is correct length");
    is_int(3, ntohs(reply.h.version), "...and is protocol version three");
    is_int(10, ntohs(reply.h.id), "...with correct id");
    is_int(LBCD_OP_LBINFO, ntohs(reply.h.op), "...and correct op");
    is_int(LBCD_STATUS_VERSION, ntohs(reply.h.status),
           "...and correct error status");

    /* Send a request for a service we're not allowed to query. */
    request.h.version = htons(3);
    request.h.status = htons(1);
    strlcpy(request.names[0],"rr", sizeof(request.names[0]));
    size = sizeof(struct lbcd_header) + sizeof(lbcd_name_type);
    result = send(fd, &request, size, 0);
    if (result != (ssize_t) size)
        sysbail("cannot send bad service query");
    memset(&reply, 0, sizeof(reply));
    result = recv(fd, &reply, sizeof(reply), 0);

    /* Check the resulting error message. */
    is_int(sizeof(struct lbcd_header), result,
           "Bad service error reply is correct length");
    is_int(3, ntohs(reply.h.version), "...and is protocol version three");
    is_int(10, ntohs(reply.h.id), "...with correct id");
    is_int(LBCD_OP_LBINFO, ntohs(reply.h.op), "...and correct op");
    is_int(LBCD_STATUS_ERROR, ntohs(reply.h.status),
           "...and correct error status");

    /* Send a request for an unknown op code. */
    request.h.op = htons(10);
    request.h.status = 0;
    result = send(fd, &request, sizeof(struct lbcd_header), 0);
    if (result != (ssize_t) sizeof(struct lbcd_header))
        sysbail("cannot send unknown op query");
    memset(&reply, 0, sizeof(reply));
    result = recv(fd, &reply, sizeof(reply), 0);

    /* Check the resulting error message. */
    is_int(sizeof(struct lbcd_header), result,
           "Unknown op error reply is correct length");
    is_int(3, ntohs(reply.h.version), "...and is protocol version three");
    is_int(10, ntohs(reply.h.id), "...with correct id");
    is_int(10, ntohs(reply.h.op), "...and correct op");
    is_int(LBCD_STATUS_UNKNOWN_OP, ntohs(reply.h.status),
           "...and correct error status");

    /* All done.  Clean up and return. */
    close(fd);
    return 0;
}