Example #1
0
static int remote_service_unregister(struct hostctrl *hc, 
                                     const struct service_id *srvid,
                                     unsigned short prefix_bits)
{
    struct ctrlmsg_register req;

    if (!srvid)
        return -1;

    memset(&req, 0, sizeof(req));
    req.cmh.type = CTRLMSG_TYPE_UNREGISTER;
    req.cmh.len = htons(sizeof(req));
    req.cmh.xid = ++hc->xid;
	req.srvid_prefix_bits = 
        (prefix_bits > SERVICE_ID_MAX_PREFIX_BITS) ?
        0 : prefix_bits;
    memcpy(&req.srvid, srvid, sizeof(*srvid));
    //memcpy(&req.address, ipaddr, sizeof(*ipaddr));
        
    LOG_DBG("prefix_bits=%u sizeof(req)=%zu %s\n",
            req.srvid_prefix_bits, 
            sizeof(req), 
            service_id_to_str(&req.srvid));
                
    return message_channel_send(hc->mc, &req.cmh, sizeof(req));
}
static int local_service_generic(struct hostctrl *hc, int type,
                                 const struct service_id *srvid,
                                 unsigned short prefix_bits,
                                 unsigned int priority,
                                 unsigned int weight,
                                 const struct in_addr *ipaddr)
{
    struct {
        struct ctrlmsg_service cm;
        struct service_info service;
    } req;

    if (!srvid)
        return -1;

    memset(&req, 0, sizeof(req));
    req.cm.cmh.type = type;
    req.cm.cmh.xid = ++hc->xid;
    req.cm.cmh.len = CTRLMSG_SERVICE_NUM_LEN(1);
    req.cm.service[0].srvid_prefix_bits =
        (prefix_bits > SERVICE_ID_MAX_PREFIX_BITS) ?
        0 : prefix_bits;
    req.cm.service[0].priority = priority;
    req.cm.service[0].weight = weight;
    memcpy(&req.cm.service[0].srvid, srvid, sizeof(*srvid));

    if (ipaddr)
        memcpy(&req.cm.service[0].address, ipaddr, sizeof(*ipaddr));

    req.cm.service[0].if_index = -1;

    /* strncpy(req.cm.ifname, ifname, IFNAMSIZ - 1); */

    LOG_DBG("op=%d prefix_bits=%u len=%u sizeof(req)=%zu %zu %s\n",
            type, req.cm.service[0].srvid_prefix_bits,
            CTRLMSG_SERVICE_LEN(&req.cm), sizeof(req),
            CTRLMSG_SERVICE_NUM(&req.cm),
            service_id_to_str(&req.cm.service[0].srvid));

    return message_channel_send(hc->mc, &req.cm, req.cm.cmh.len);
}
Example #3
0
int server(void)
{
        int sock, backlog = 8;;
        struct sockaddr_sv servaddr, cliaddr;  
    
        if ((sock = socket_sv(AF_SERVAL, SOCK_DGRAM, SERVAL_PROTO_UDP)) < 0) {
                fprintf(stderr, "error creating AF_SERVAL socket: %s\n", 
                        strerror_sv(errno));
                return -1;
        }
  
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sv_family = AF_SERVAL;
        servaddr.sv_srvid.s_sid32[0] = htonl(ECHO_SERVICE_ID);
  
        set_reuse_ok(sock);
  
        if (bind_sv(sock, (struct sockaddr *)&servaddr, 
                    sizeof(servaddr)) < 0) {
                fprintf(stderr, "error binding socket: %s\n", 
                        strerror_sv(errno));
                close_sv(sock);
                return -1;
        }
        
        printf("server: bound to service id %d\n", ECHO_SERVICE_ID);

        listen_sv(sock, backlog);

        do {
                socklen_t l = sizeof(cliaddr);
                int k = 0;

                printf("calling accept\n");

                int fd = accept_sv(sock, (struct sockaddr *)&cliaddr, &l);

                if (fd < 0) {
                        fprintf(stderr, "error accepting new conn %s\n", 
                                strerror_sv(errno));
                        return -1;
                }

                printf("server: recv conn from service id %s; got fd = %d\n",
                       service_id_to_str(&cliaddr.sv_srvid), fd);
        

                do {
                        unsigned N = 2000;
                        char buf[N];
                        int n;
      
                        printf("server: waiting on client request\n");

                        if ((n = recv_sv(fd, buf, N, 0)) < 0) {
                                fprintf(stderr, 
                                        "server: error receiving client request: %s\n",
                                        strerror_sv(errno));
                                break;
                        }
                        if (n == 0) {
                                fprintf(stderr, "server: received EOF; "
                                        "listening for new conns\n");
                                break;
                        }
                        buf[n] = '\0';
                        
                        printf("server: request (%d bytes): %s\n", n, buf);

                        if (n > 0) {
                                char buf2[n];
                                int i = 0;
                                for (; i < n; i++)
                                        buf2[i] = toupper(buf[i]);
                                fprintf(stderr, "server: Convert and send upcase:");
                                for (i = 0; i < n; i++)
                                        fprintf(stderr, "%c", buf2[i]);
                                fprintf(stderr, "\n");
                                send_sv(fd, buf2, n, 0);
                                if (strcmp(buf, "quit") == 0)
                                        break;
                        }
                        k++;
                } while (1);
                close_sv(fd);
                printf("Server listening for NEW connections\n");
        } while (1);
        close_sv(sock);

        printf("Exiting\n");

        return -1;
}
Example #4
0
static int client(const char *filepath, 
                  struct in_addr *srv_inetaddr, int port)
{
        int sock, ret = EXIT_FAILURE;
        union {
                struct sockaddr_sv serval;
                struct sockaddr_in inet;
                struct sockaddr saddr;
        } cliaddr, srvaddr;
        socklen_t addrlen = 0;
        unsigned char digest[SHA_DIGEST_LENGTH];
        unsigned short srv_inetport = (unsigned short)port;
        int family = AF_SERVAL;

        memset(&cliaddr, 0, sizeof(cliaddr));
        memset(&srvaddr, 0, sizeof(srvaddr));

        if (srv_inetaddr) {
                family = AF_INET;
                cliaddr.inet.sin_family = family;
                cliaddr.inet.sin_port = htons(6767);
                srvaddr.inet.sin_family = family;
                srvaddr.inet.sin_port = htons(srv_inetport);
                memcpy(&srvaddr.inet.sin_addr, srv_inetaddr, 
                       sizeof(*srv_inetaddr));
                addrlen = sizeof(cliaddr.inet);
        } else {
                cliaddr.serval.sv_family = family;
                cliaddr.serval.sv_srvid.s_sid32[0] = htonl(getpid());
                srvaddr.serval.sv_family = AF_SERVAL;
                memcpy(&srvaddr.serval.sv_srvid, 
                       &server_srvid, sizeof(server_srvid));
                addrlen = sizeof(cliaddr.serval);
                /* srvaddr.sv_flags = SV_WANT_FAILOVER; */
        }
        
        sock = socket_sv(family, SOCK_STREAM, 0);
        
        set_reuse_ok(sock);
        
        if (family == AF_SERVAL) {
                ret = bind_sv(sock, &cliaddr.saddr, addrlen);
                
                if (ret < 0) {
                        fprintf(stderr, "error client binding socket: %s\n", 
                                strerror_sv(errno));
                        goto out;
                }
        }
        
        if (family == AF_INET) {
                char buf[18];
                printf("Connecting to service %s:%u\n",
                       inet_ntop(family, srv_inetaddr, buf, 18), 
                       srv_inetport);
        } else {
                printf("Connecting to service id %s\n", 
                       service_id_to_str(&srvaddr.serval.sv_srvid));
        }
        ret = connect_sv(sock, &srvaddr.saddr, addrlen);
    
        if (ret < 0) {
                fprintf(stderr, "ERROR connecting: %s\n",
                        strerror_sv(errno));
                goto out;
        }
#if defined(SERVAL_NATIVE)
        {
                struct {
                        struct sockaddr_sv sv;
                        struct sockaddr_in in;
                } saddr;
                socklen_t addrlen = sizeof(saddr.in);
                char ipaddr[18];

                memset(&saddr, 0, sizeof(saddr));
                
                ret = getsockname(sock, (struct sockaddr *)&saddr, &addrlen);

                if (ret == -1) {
                        fprintf(stderr, "Could not get sock name : %s\n",
                                strerror(errno));
                } else {
                        printf("sock name is %s @ %s\n",
                               service_id_to_str(&saddr.sv.sv_srvid),
                               inet_ntop(AF_INET, &saddr.in.sin_addr, 
                                         ipaddr, 18));
                }

                memset(&saddr, 0, sizeof(saddr));
                
                ret = getpeername(sock, (struct sockaddr *)&saddr, &addrlen);

                if (ret == -1) {
                        fprintf(stderr, "Could not get peer name : %s\n",
                                strerror(errno));
                } else {
                        printf("peer name is %s @ %s\n",
                               service_id_to_str(&saddr.sv.sv_srvid),
                               inet_ntop(AF_INET, &saddr.in.sin_addr, 
                                         ipaddr, 18));
                }
        } 
#endif
        printf("Connected successfully!\n");
        
        ret = recv_file(sock, filepath, digest);
        
        if (ret == EXIT_SUCCESS) {
                printf("SHA1 digest is [%s]\n", digest_to_str(digest));
        } else {
                printf("Receive failed\n");
        }
out:
        fprintf(stderr, "Closing socket...\n");
        close_sv(sock);

        return ret;
}
Example #5
0
static int service_parse_args(int argc, char **argv, void **result)
{
        static struct arguments args;
	char *ptr, *prefix = NULL;
        int i, ret;

        memset(&args, 0, sizeof(args));
        args.op = __SERVICE_OP_MAX;
        args.prefix_bits = SERVICE_ID_MAX_PREFIX_BITS;
        args.priority = 1;
        args.weight = 0;

	if (argc < 3)
                return -1;

        for (i = 0; i < __SERVICE_OP_MAX; i++) {
                if (strcmp(argv[0], opnames[i].name) == 0 ||
                    strcmp(argv[0], opnames[i].long_name) == 0) {
                        args.op = i;
                        break;
                }
        }

        if (args.op == __SERVICE_OP_MAX)
                return -1;
        
        argc--;
        argv++;

        /* Check for hexadecimal serviceID. */
        if (strcmp(argv[0], "default") == 0) {
                /* Do nothing, serviceID already set to zero */
        } else if (argv[0][0] == '0' && argv[0][1] == 'x') {
                int len;
                
                argv[0] += 2;
                ptr = argv[0];

                while (*ptr != ':' && *ptr != '\0')
                        ptr++;
                
                if (*ptr == ':') {
                        prefix = ptr + 1;
                        *ptr = '\0';
                }
               
                len = strlen(argv[0]);

                if (len > 64)
                        len = 64;
                
                if (serval_pton(argv[0], &args.srvid) == -1)
                        return -1;
        } else {
                unsigned long id = strtoul(argv[0], &ptr, 10);
                
                if (!((*ptr == '\0' || *ptr == ':') && argv[0] != '\0')) {
                        fprintf(stderr, "bad service id format '%s',"
                                " should be short integer string\n",
                                argv[0]);
                        return -1;
                }
                if (*ptr == ':')
                        prefix = ++ptr;

                args.srvid.s_sid32[0] = ntohl(id);
        }
        
        if (prefix) {
                args.prefix_bits = strtoul(prefix, &ptr, 10);
                
                if (!(*ptr == '\0' && prefix != '\0')) {
                        fprintf(stderr, "bad prefix string %s\n",
                                prefix);
                        return -1;
                }
                if (args.prefix_bits > SERVICE_ID_MAX_PREFIX_BITS || 
                    args.prefix_bits == 0)
                        args.prefix_bits = SERVICE_ID_MAX_PREFIX_BITS;
        }

        argc--;
        argv++;

        if (argc == 0) {
                fprintf(stderr, "No target IP in rule\n");
                return -1;
        }
        
        ret = name_to_inet_addr(argv[0], &args.ipaddr1);
        
        if (ret != 1) {
                fprintf(stderr, "Bad IP address: '%s'\n",
                        argv[0]);
                return -1;
        }

        args.ip1 = &args.ipaddr1;

        argc--;
        argv++;

        while (argc) {
                if (strcmp("priority", argv[0]) == 0) {
                        char *ptr = NULL;
                        
                        if (argc < 2) {
                                fprintf(stderr, "No priority number given\n");
                                return -1;
                        }
                        
                        args.priority = strtoul(argv[1], &ptr, 10);
                        
                        if (*ptr != '\0' || argv[1][0] == '\0') {
                                fprintf(stderr, "Bad priority %s\n",
                                        argv[1]);
                                return -1;
                        }

                        argc--;
                        argv++;
                } else if (strcmp("weight", argv[0]) == 0) {
                        char *ptr = NULL;
                        
                        if (argc < 2) {
                                fprintf(stderr, "No weight given\n");
                                return -1;
                        }
                        
                        args.weight = strtoul(argv[1], &ptr, 10);
                        
                        if (*ptr != '\0' || argv[1][0] == '\0') {
                                fprintf(stderr, "Bad weight %s\n",
                                        argv[1]);
                                return -1;
                        }

                        argc--;
                        argv++;
                } else {
                        ret = name_to_inet_addr(argv[0], &args.ipaddr2);
                        
                        if (ret != 1) {
                                fprintf(stderr, "Bad IP address: '%s'\n",
                                        argv[0]);
                                return -1;
                        }
                        args.ip2 = &args.ipaddr2;
                }
                argc--;
                argv++;
        }
        {
                char buf[18];
                printf("%s %s:%u %s priority=%u weight=%u\n",
                       opnames[args.op].long_name,
                       service_id_to_str(&args.srvid), 
                       args.prefix_bits, 
                       inet_ntop(AF_INET, &args.ipaddr1, buf, 18),
                       args.priority,
                       args.weight);
        }
        
        *result = &args;

        return 0;
}
Example #6
0
int main(int argc, char **argv)
{
	int sock;
        const char *ipdst = "192.168.56.102";
	unsigned long data = 8;
	ssize_t ret = 0;
        struct {
                struct sockaddr_sv sv;
                struct sockaddr_in in;
        } addr;

        if (argc > 1) {
                ipdst = argv[1];
        }
        
	sock = socket_sv(AF_SERVAL, SOCK_DGRAM, 0);

	if (sock == -1) { 
		fprintf(stderr, "could not create SERVAL socket: %s\n",
			strerror(errno));
		goto out;
	}

        memset(&addr, 0, sizeof(addr));
	addr.sv.sv_family = AF_SERVAL;
	addr.sv.sv_srvid.s_sid16[0] = htons(6); 
	addr.in.sin_family = AF_INET;
	
        if (inet_pton(AF_INET, ipdst, &addr.in.sin_addr) != 1) {
                fprintf(stderr, "Bad advisory IP address %s\n",
                        ipdst);
                goto out;
        }
        
        printf("My serviceID is \'%s\'\n",
               service_id_to_str(&addr.sv.sv_srvid));
               
        ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr.sv));

        if (ret == -1) {
		fprintf(stderr, "bind: %s\n", strerror_sv(errno));
                goto out;
        }

	addr.sv.sv_srvid.s_sid16[0] = htons(7);
        
        printf("Sending to \'%s\' %s\n",
               service_id_to_str(&addr.sv.sv_srvid),
               ipdst);

	ret = sendto_sv(sock, &data, sizeof(data), 0, 
                        (struct sockaddr *)&addr, sizeof(addr));

	if (ret == -1) {
		fprintf(stderr, "sendto: %s\n", strerror_sv(errno));
	}
out:
        close(sock);

	return ret;
}
Example #7
0
int main(int argc, char **argv)
{
	int sock;
        const char *ipdst = "192.168.56.102";
	unsigned long data = 10;
	ssize_t ret = 0;
        struct {
                struct sockaddr_sv sv;
                struct sockaddr_in in;
        } addr;

        if (argc > 1) {
                ipdst = argv[1];
        }
        
	sock = socket_sv(AF_SERVAL, SOCK_DGRAM, 0);

	if (sock == -1) { 
		fprintf(stderr, "could not create SERVAL socket: %s\n",
			strerror(errno));
		goto out;
	}

        /*
        struct addrinfo* a = NULL;
        struct addrinfo hints;
        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE;
        getaddrinfo(NULL, "3900", &hints, &a);
        struct addrinfo *res;
        for(res = a; res != NULL; res = res->ai_next)
                {   
                        struct sockaddr_in* saddr = (struct sockaddr_in*)res->ai_addr;
                        printf("hostname: %s\n", inet_ntoa(saddr->sin_addr));
                } 
        */

        memset(&addr, 0, sizeof(addr));
	addr.sv.sv_family = AF_SERVAL;
	addr.sv.sv_srvid.s_sid16[0] = htons(6); 
	addr.in.sin_family = AF_INET;
	
        if (inet_pton(AF_INET, ipdst, &addr.in.sin_addr) != 1) {
                 fprintf(stderr, "Bad advisory IP address %s\n",
                        ipdst);
                goto out;
        }
        
        printf("My serviceID is \'%s\'\n",
               service_id_to_str(&addr.sv.sv_srvid));
               
        ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr.sv));

        if (ret == -1) {
		fprintf(stderr, "bind: %s\n", strerror_sv(errno));
                goto out;
        }

	addr.sv.sv_srvid.s_sid32[0] = htonl(10);
        
        printf("Sending to \'%s\' %s\n",
               service_id_to_str(&addr.sv.sv_srvid),
               ipdst);

	ret = sendto_sv(sock, &data, sizeof(data), 0, 
                        (struct sockaddr *)&addr, sizeof(addr.sv));

	if (ret == -1) {
		fprintf(stderr, "sendto: %s\n", strerror_sv(errno));
	}
out:
        close(sock);

	return ret;
}
Example #8
0
int client(char *ip) {
	struct sockaddr_sv srvaddr;
	struct sockaddr_sv cliaddr;
        struct sockaddr_in myaddr;
        struct sockaddr_in dummyaddr;
        int dummysize;
	int ret = 0;
	unsigned N = 2000;
	char sbuf[N];
        char rbuf[N+1];

        sock_backchannel = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

        if (sock_backchannel == -1) {
                fprintf(stderr, "socket: %s\n",
                        strerror_sv(errno));
                return -1;
        }
        set_reuse_ok(sock_backchannel);
        memset((char *)&myaddr, 0, sizeof(myaddr));
        myaddr.sin_family = AF_INET;
        inet_aton(ip, &myaddr.sin_addr);
        myaddr.sin_port = htons(BACKCHANNEL_PORT);

        bind(sock_backchannel, (struct sockaddr *)&myaddr, sizeof(myaddr));

	bzero(&srvaddr, sizeof(srvaddr));
	srvaddr.sv_family = AF_SERVAL;
	srvaddr.sv_srvid.s_sid32[0] = htonl(ECHO_SERVICE_ID);

	sock = socket_sv(AF_SERVAL, SOCK_DGRAM, SERVAL_PROTO_UDP);


        if (sock == -1) {
                fprintf(stderr, "socket: %s\n",
                        strerror_sv(errno));
                return -1;
        }

	set_reuse_ok(sock);

	bzero(&cliaddr, sizeof(cliaddr));
	cliaddr.sv_family = AF_SERVAL;
	cliaddr.sv_srvid.s_sid32[0] = htonl(CLIENT_SERVICE_ID);

        ret = bind_sv(sock, (struct sockaddr *) &cliaddr, sizeof(cliaddr));

	if (ret < 0) {
		fprintf(stderr, "bind: %s\n",
                        strerror_sv(errno));
		return -1;
	}


        ret = connect_sv(sock, (struct sockaddr *)&srvaddr, sizeof(srvaddr));

	if (ret < 0) {
		fprintf(stderr, "connect: %s\n",
			strerror_sv(errno));
		return -1;
	}

	printf("connected\n");

	while (1) {
                sprintf(sbuf, "ping %s %d", ip, BACKCHANNEL_PORT);
		printf("client: sending \"%s\" to service ID %s\n",
                       sbuf, service_id_to_str(&srvaddr.sv_srvid));

                ret = sendto_sv(sock, sbuf, strlen(sbuf), 0, (struct sockaddr *)&srvaddr, sizeof(srvaddr));

		if (ret < 0) {
			fprintf(stderr, "send failed (%s)\n",
                                strerror_sv(errno));
                        break;
		}

		ret = recvfrom(sock_backchannel, rbuf, N, 0, (struct sockaddr *)&dummyaddr, &dummysize);
		rbuf[ret] = 0;

                if (ret == 0) {
                        printf("server closed\n");
                        break;
                } else {
                        printf("Response from server: %s\n", rbuf);

                        if (strcmp(sbuf, "quit") == 0)
                                break;
                }
                sleep(1);
	}

	if (close_sv(sock) < 0)
		fprintf(stderr, "close: %s\n",
                        strerror_sv(errno));

        return ret;
}
Example #9
0
static int server(const char *filepath, 
                  size_t send_memory_buffer_size, 
                  int family)
{
        int sock;
        int backlog = 8;    
        union {
                 struct sockaddr_sv serval;
                struct sockaddr_in inet;
                struct sockaddr saddr;
        } cliaddr, srvaddr;
        socklen_t addrlen = 0;
        unsigned char digest[SHA_DIGEST_LENGTH];
        int ret = EXIT_FAILURE;
        unsigned short srv_inetport = 49254;

        memset(&cliaddr, 0, sizeof(cliaddr));
        memset(&srvaddr, 0, sizeof(srvaddr));

        if (family == AF_INET) {
                cliaddr.inet.sin_family = family;
                srvaddr.inet.sin_family = family;
                srvaddr.inet.sin_addr.s_addr = INADDR_ANY;
                srvaddr.inet.sin_port = htons(srv_inetport);
                addrlen = sizeof(srvaddr.inet);
        } else {
                cliaddr.serval.sv_family = family;
                srvaddr.serval.sv_family = AF_SERVAL;
                memcpy(&srvaddr.serval.sv_srvid,
                       &listen_srvid, sizeof(listen_srvid));
                addrlen = sizeof(cliaddr.serval);
        }
      
        sock = socket_sv(family, SOCK_STREAM, 0);

        if (sock < 0) {
                fprintf(stderr, "error creating AF_SERVAL socket: %s\n", 
                        strerror(errno));
                return EXIT_FAILURE;
        }
  
        set_reuse_ok(sock);
        
        ret = bind_sv(sock, &srvaddr.saddr, addrlen);
  
        if (ret < 0) {
                fprintf(stderr, "error binding socket: %s\n", strerror(errno));
                close_sv(sock);
                return ret;
        }
        
        if (family == AF_INET) {
                printf("server: bound to port %u\n",
                       srv_inetport);
        } else {
                printf("server: bound to service id %s\n", 
                       service_id_to_str(&listen_srvid));
        }
        
        ret = listen_sv(sock, backlog);

        if (ret < 0) {
                fprintf(stderr, "error setting listening socket: %s\n", 
                        strerror(errno));
                close_sv(sock);
                return ret;
        }
    
        while (!should_exit) {
                socklen_t l = addrlen;
                int client_sock;
                long offset = 0;

                printf("Waiting for new connections\n");
                
                client_sock = accept_sv(sock, &cliaddr.saddr, &l);
        
                if (client_sock < 0) {
                        fprintf(stderr, "error accepting new conn: %s\n", 
                                strerror_sv(errno));
                        continue;
                }
                
                if (family == AF_INET) {
                        char buf[18];
                        printf("Connect request from %s:%u\n",
                               inet_ntop(family, 
                                         &cliaddr.inet.sin_addr, buf, 18),
                               ntohs(cliaddr.inet.sin_port));
                } else {
                        printf("Connect req from service id %s (sock = %d)\n",
                               service_id_to_str(&cliaddr.serval.sv_srvid), 
                               client_sock);
                }
                
                if (send_memory_buffer_size > 0)
                        ret = send_memory_buffer(client_sock, 
                                                 send_memory_buffer_size, 
                                                 digest);
                else
                        ret = send_file(client_sock, filepath, offset, 
                                        digest);

                if (ret == EXIT_SUCCESS) {
                        printf("Send successful\n");
                        printf("SHA1 digest is [%s]\n", digest_to_str(digest));
                } else if (ret < 0) {
                        fprintf(stderr, "Failed data transfer to client\n");
                        //should_exit = 1;
                }
                close_sv(client_sock);
        } 

        close_sv(sock);

        return ret;
}
Example #10
0
int Mailbox(int sid) {

        int sock;
        struct sockaddr_sv mboxaddr, cliaddr;

	socklen_t addrlen = sizeof(cliaddr);
    
        if ((sock = socket_sv(AF_SERVAL, SOCK_DGRAM, SERVAL_PROTO_UDP)) < 0) {
                fprintf(stderr, "error creating AF_SERVAL socket: %s\n", 
                        strerror_sv(errno));
                return -1;
        }
  
        memset(&mboxaddr, 0, sizeof(mboxaddr));
        mboxaddr.sv_family = AF_SERVAL;
        mboxaddr.sv_srvid.s_sid32[0] = htonl(sid);
  
        set_reuse_ok(sock);
  
        if (bind_sv(sock, (struct sockaddr *)&mboxaddr, 
                    sizeof(mboxaddr)) < 0) {
                fprintf(stderr, "error binding socket: %s\n", 
                        strerror_sv(errno));
                close_sv(sock);
                return -1;
        }
        
        printf("mailbox: bound to service id %d\n", sid);
        memset(&cliaddr, 0, sizeof(cliaddr));

        payload p;
        int n;
        list_node_t *pl;
        while (1) {

                n = recvfrom_sv(sock, &p, sizeof(payload), 0, 
                                  (struct sockaddr *)&cliaddr, &addrlen);
		
                if (n == -1) {
                        fprintf(stderr, "recvfrom: %s\n", strerror_sv(errno));
                        return -1;
                }

                /*
                if (n == 0) {
                        fprintf(stderr, "server: received EOF");
                        break;
                }
                */

                printf("Received a %zd byte packet number %d type %d from \'%s\' \n", n, p.num, p.type, 
                       service_id_to_str(&cliaddr.sv_srvid));

                //rbuf[n] = '\0';
                if (p.type==DATA) {
                        pl = list_node_new(&p);
                        list_rpush(dataPackets,pl);
                }
                printf("length of buffer: %d\n", dataPackets->len);
        }

        close_sv(sock);
        return -1;
}
Example #11
0
static int ctrl_handle_add_service_msg(struct ctrlmsg *cm, int peer)
{
        struct ctrlmsg_service *cmr = (struct ctrlmsg_service *)cm;
        unsigned int num_res = CTRLMSG_SERVICE_NUM(cmr);
        /* TODO - flags, etc */
        unsigned int i, index = 0;
        int err = 0;

        LOG_DBG("adding %u services, msg size %u\n", 
                num_res, CTRLMSG_SERVICE_LEN(cmr));
        
        for (i = 0; i < num_res; i++) {
                struct net_device *dev = NULL;
                struct service_info *entry = &cmr->service[i];
                unsigned short prefix_bits = SERVICE_ID_MAX_PREFIX_BITS;

                if (entry->type == SERVICE_RULE_FORWARD) {
                        dev = resolve_dev(entry);
                        
                        if (!dev)
                                continue;
                }

                if (entry->srvid_prefix_bits > 0)
                        prefix_bits = entry->srvid_prefix_bits;
         
#if defined(ENABLE_DEBUG)
                {
                        char ipstr[18];
                        LOG_DBG("Adding service id: %s(%u) "
                                "@ address %s, priority %u, weight %u\n", 
                                service_id_to_str(&entry->srvid), 
                                prefix_bits, 
                                inet_ntop(AF_INET, &entry->address,
                                          ipstr, sizeof(ipstr)),
                                entry->priority, entry->weight);
                }
#endif
                err = service_add(&entry->srvid, 
                                  prefix_bits, 
                                  entry->type,
                                  entry->srvid_flags, 
                                  entry->priority, 
                                  entry->weight,
                                  &entry->address, 
                                  sizeof(entry->address),
                                  make_target(dev), GFP_KERNEL);
                if (dev)
                        dev_put(dev);

                if (err > 0) {
                        if (index < i) {
                                /* copy it over */
                                memcpy(&cmr->service[index], 
                                       entry, sizeof(*entry));
                        }
                        index++;
                } else {
                        LOG_ERR("Error adding service %s: err=%d\n", 
                                service_id_to_str(&entry->srvid), err);
                }
        }

        if (index == 0) {
                /* Just return the original request with a return value */
                cm->retval = CTRLMSG_RETVAL_NOENTRY;
        } else {
                /* Return the entries added */
                cm->retval = CTRLMSG_RETVAL_OK;
                cm->len = CTRLMSG_SERVICE_NUM_LEN(index);
        }

        ctrl_sendmsg(cm, peer, GFP_KERNEL);

        return 0;
}
Example #12
0
static int ctrl_handle_get_service_msg(struct ctrlmsg *cm, int peer)
{
        struct ctrlmsg_service *cmg = (struct ctrlmsg_service *)cm;
        struct service_entry *se;
        struct service_iter iter;
        unsigned short prefix_bits = SERVICE_ID_MAX_PREFIX_BITS;
        struct target *t;

        LOG_DBG("getting service: %s\n",
                service_id_to_str(&cmg->service[0].srvid));

        if (cmg->service[0].srvid_prefix_bits > 0)
                prefix_bits = cmg->service[0].srvid_prefix_bits;

        se = service_find(&cmg->service[0].srvid, 
                          prefix_bits);

        if (se) {
                struct ctrlmsg_service *cres;
                size_t size = CTRLMSG_SERVICE_NUM_LEN(se->count);
                int i = 0;
                          
                cres = kmalloc(size, GFP_KERNEL);

                if (!cres) {
                        service_entry_put(se);
                        cm->retval = CTRLMSG_RETVAL_ERROR;
                        ctrl_sendmsg(cm, peer, GFP_KERNEL);
                        return -ENOMEM;
                }

                memset(cres, 0, size);
                cres->cmh.type = CTRLMSG_TYPE_GET_SERVICE;
                cres->cmh.len = size;
                cres->cmh.xid = cm->xid;
                cres->xid = cmg->xid;

                memset(&iter, 0, sizeof(iter));
                service_iter_init(&iter, se, SERVICE_ITER_FORWARD);

                while ((t = service_iter_next(&iter)) != NULL) {
                        struct service_info *entry = &cres->service[i++];

                        service_get_id(se, &entry->srvid);
                        memcpy(&entry->address, 
                               t->dst, t->dstlen);
                        
                        entry->srvid_prefix_bits = service_get_prefix_bits(se);
                        entry->srvid_flags = service_iter_get_flags(&iter);
                        entry->weight = t->weight;
                        entry->priority = service_iter_get_priority(&iter);
                        
#if defined(ENABLE_DEBUG)
                        {
                                char buf[18];
                                LOG_DBG("Get %s %s priority=%u weight=%u\n", 
                                service_id_to_str(&entry->srvid), 
                                        inet_ntop(AF_INET, &t->dst, 
                                                  buf, 18),
                                        entry->priority,
                                        entry->weight);
                        }
#endif
                        
                }

                service_iter_destroy(&iter);
                service_entry_put(se);

                if (i == 0)
                        cres->cmh.retval = CTRLMSG_RETVAL_NOENTRY;
                else
                        cres->cmh.retval = CTRLMSG_RETVAL_OK;

                ctrl_sendmsg(&cres->cmh, peer, GFP_KERNEL);
                kfree(cres);
                LOG_DBG("Service %s matched %u entries. msg_len=%u\n",
                        service_id_to_str(&cmg->service[0].srvid),
                        se->count, cres->cmh.len);
        } else {
                cmg->service[0].srvid_flags = SVSF_INVALID;
                cmg->cmh.retval = CTRLMSG_RETVAL_NOENTRY;
                ctrl_sendmsg(&cmg->cmh, peer, GFP_KERNEL);
                LOG_DBG("Service %s not found\n",
                        service_id_to_str(&cmg->service[0].srvid));
        }

        return 0;
}
Example #13
0
static int ctrl_handle_mod_service_msg(struct ctrlmsg *cm, int peer)
{
        struct ctrlmsg_service *cmr = (struct ctrlmsg_service *)cm;
        unsigned int num_res = CTRLMSG_SERVICE_NUM(cmr);
        unsigned int i, index = 0;
        int err = 0;

        if (num_res < 2 || num_res % 2 != 0) {
                LOG_DBG("Not an even number of service infos\n");
                return 0;
        }

        LOG_DBG("modifying %u services\n", num_res / 2);

        for (i = 0; i < num_res; i += 2) {
                struct net_device *dev;
                struct service_info *entry_old = &cmr->service[i];
                struct service_info *entry_new = &cmr->service[i+1];
                unsigned short prefix_bits = SERVICE_ID_MAX_PREFIX_BITS;
                
                if (entry_old->srvid_prefix_bits > 0)
                        prefix_bits = entry_old->srvid_prefix_bits;

#if defined(ENABLE_DEBUG)
                {
                        char buf[18];
                        LOG_DBG("Modifying: %s flags(%i) bits(%i) %s\n", 
                                service_id_to_str(&entry_old->srvid), 
                                entry_old->srvid_flags, 
                                prefix_bits,
                                inet_ntop(AF_INET, &entry_old->address, 
                                          buf, 18));
                }
#endif
                dev = resolve_dev(entry_old);
                
                if (!dev)
                        continue;

                err = service_modify(&entry_old->srvid,
                                     prefix_bits,
                                     SERVICE_RULE_FORWARD,
                                     entry_old->srvid_flags, 
                                     entry_new->priority, 
                                     entry_new->weight, 
                                     &entry_old->address,
                                     sizeof(entry_old->address),
                                     &entry_new->address,
                                     sizeof(entry_new->address), 
                                     make_target(dev));
                if (err > 0) {
                        if (index < i) {
                                /* copy it over */
                                memcpy(&cmr->service[index], 
                                       entry_new, sizeof(*entry_new));
                        }
                        index++;
                } else {
                        LOG_ERR("Could not modify service %s: %i\n", 
                                service_id_to_str(&entry_old->srvid), 
                                err);
                }
                dev_put(dev);
        }
        
        if (index == 0) {
                cm->retval = CTRLMSG_RETVAL_NOENTRY;
        } else {
                cm->retval = CTRLMSG_RETVAL_OK;
                cm->len = CTRLMSG_SERVICE_NUM_LEN(index);
        }
        
        ctrl_sendmsg(cm, peer, GFP_KERNEL);

        return 0;
}
Example #14
0
static int ctrl_handle_del_service_msg(struct ctrlmsg *cm, int peer)
{
        struct ctrlmsg_service *cmr = (struct ctrlmsg_service *)cm;
        unsigned int num_res = CTRLMSG_SERVICE_NUM(cmr);
        const size_t cmsg_size = sizeof(struct ctrlmsg_service_info_stat) + 
                sizeof(struct service_info_stat) * num_res;
        struct ctrlmsg_service_info_stat *cms;
        struct service_id null_service = { .s_sid = { 0 } };
        unsigned int i = 0, index = 0;
        int err = 0;       

        LOG_DBG("deleting %u services\n", num_res);

        cms = kmalloc(cmsg_size, GFP_KERNEL);

        if (!cms) {
                cm->retval = CTRLMSG_RETVAL_ERROR;
                ctrl_sendmsg(cm, peer, GFP_KERNEL);
                return -ENOMEM;
        }

        memset(cms, 0, cmsg_size);

        for (i = 0; i < num_res; i++) {
                struct service_info *entry = &cmr->service[i];
                struct service_info_stat *stat = &cms->service[index];
                struct target_stats tstat;
                struct service_entry *se;
                unsigned short prefix_bits = SERVICE_ID_MAX_PREFIX_BITS;

                /*
                  We might be trying to delete the "default" entry. In
                  that case
                */
                if (memcmp(&entry->srvid, &null_service, 
                           sizeof(null_service)) == 0 ||
                    entry->srvid_prefix_bits > 0)
                        prefix_bits = entry->srvid_prefix_bits;
                
                stat->service.srvid_prefix_bits = prefix_bits;
                se = service_find_exact(&entry->srvid, 
                                        prefix_bits);

                if (!se) {
                        LOG_DBG("No match for serviceID %s:(%u)\n",
                                service_id_to_str(&entry->srvid),
                                prefix_bits);
                        continue;
                }

                memset(&tstat, 0, sizeof(tstat));
                
                err = service_entry_remove_target(se,
                                                  entry->type,
                                                  &entry->address, 
                                                  sizeof(entry->address), 
                                                  &tstat);

                if (err > 0) {
                        stat->duration_sec = tstat.duration_sec;
                        stat->duration_nsec = tstat.duration_nsec;
                        stat->packets_resolved = tstat.packets_resolved;
                        stat->bytes_resolved = tstat.bytes_resolved;
                        stat->packets_dropped = tstat.packets_dropped;
                        stat->bytes_dropped = tstat.packets_dropped;

                        //if (index < i) {
                                memcpy(&stat->service, entry, 
                                       sizeof(*entry));
                        //}
                        LOG_DBG("Service ID %s:%u\n", service_id_to_str(&stat->service.srvid), stat->service.srvid_prefix_bits);
                        index++;
                } else if (err == 0) {
                        LOG_ERR("Could not find target for service %s\n", 
                                service_id_to_str(&entry->srvid));
                } else {
                        LOG_ERR("Could not remove service %s - err %d\n", 
                                service_id_to_str(&entry->srvid), 
                                err);
                }

                service_entry_put(se);
        }

        if (index == 0) {
                cm->retval = CTRLMSG_RETVAL_NOENTRY;
                ctrl_sendmsg(cm, peer, GFP_KERNEL);
        } else {
                cms->cmh.type = CTRLMSG_TYPE_DEL_SERVICE;
                cms->xid = cmr->xid;
                cms->cmh.xid = cm->xid;
                cms->cmh.retval = CTRLMSG_RETVAL_OK;
                cms->cmh.len = CTRLMSG_SERVICE_INFO_STAT_NUM_LEN(index);
                ctrl_sendmsg(&cms->cmh, peer, GFP_KERNEL);
        }

        kfree(cms);

        return 0;
}