Example #1
0
/*
 * Execute nsupdate.pl with IP and HIT given as environment variables
 */
int run_nsupdate(char *ips, char *hit, int start)
{
	struct sigaction act;
	pid_t child_pid;

	HIP_DEBUG("Updating dns records...\n");

	act.sa_handler = sig_chld;

	/* We don't want to block any other signals */
	sigemptyset(&act.sa_mask);

	/*
	 * We're only interested in children that have terminated, not ones
	 * which have been stopped (eg user pressing control-Z at terminal)
	 */
	act.sa_flags = SA_NOCLDSTOP | SA_RESTART;

	/* Make the handler effective */
	if (sigaction(SIGCHLD, &act, NULL) < 0) {
		HIP_PERROR("sigaction");
        	return ERR;
	}

	/* Let us fork to execute nsupdate as a separate process */
	child_pid=fork();

	if (child_pid<0) {
		HIP_PERROR("fork");
		return ERR;
	}
	else if (child_pid == 0) {// CHILD
		char start_str[2];
#if 0
		/* Close open sockets since FD_CLOEXEC was not used */
		close_all_fds_except_stdout_and_stderr();
#endif

		snprintf(start_str, sizeof(start_str), "%i", start);

		char *env_ips = make_env(VAR_IPS, ips);
		char *env_hit = make_env(VAR_HIT, hit);
		char *env_start = make_env(VAR_START, start_str);

		char *cmd[] = { NSUPDATE_ARG0, NULL };
		char *env[] = { env_ips, env_hit, env_start, NULL };

		HIP_DEBUG("Executing %s with %s; %s; %s\n", NSUPDATE_PL, env_hit, env_ips, env_start);
		execve (NSUPDATE_PL, cmd, env);

		/* Executed only if error */
		HIP_PERROR("execve");
		exit(1); // just in case
	}
	else {// PARENT
		/* We execute waitpid in SIGCHLD handler */
		return OK;
	}
}
Example #2
0
/**
 * tell firewall to turn on or off the ESP relay mode
 *
 * @param action HIP_MSG_OFFER_FULLRELAY or HIP_MSG_CANCEL_FULLRELAY
 *
 * @return zero on success or negative on failure
 */
int hip_firewall_set_esp_relay(int action)
{
    struct hip_common *msg = NULL;
    int                err = 0;
    int                sent;

    HIP_DEBUG("Setting ESP relay to %d\n", action);
    if (!(msg = hip_msg_alloc())) {
        return -ENOMEM;
    }
    HIP_IFEL(hip_build_user_hdr(msg,
                                action ? HIP_MSG_OFFER_FULLRELAY : HIP_MSG_CANCEL_FULLRELAY, 0),
             -1, "Build header failed\n");

    sent = hip_sendto_firewall(msg);
    if (sent < 0) {
        HIP_PERROR("Send to firewall failed: ");
        err = -1;
        goto out_err;
    }
    HIP_DEBUG("Sent %d bytes to firewall.\n", sent);

out_err:
    free(msg);
    return err;
}
Example #3
0
File: message.c Project: surki/hipl
int hip_read_user_control_msg(int socket, struct hip_common *hip_msg,
			      struct sockaddr_in6 *saddr)
{
	int err = 0, bytes, hdr_size = sizeof(struct hip_common), total;
	socklen_t len;

	memset(saddr, 0, sizeof(*saddr));

	len = sizeof(*saddr);

	HIP_IFEL(((total = hip_peek_recv_total_len(socket, 0, HIP_DEFAULT_MSG_TIMEOUT)) <= 0), -1,
		 "recv peek failed\n");

	_HIP_DEBUG("msg total length = %d\n", total);

	/** @todo Compiler warning;
	    warning: pointer targets in passing argument 6 of 'recvfrom'
	    differ in signedness. */
	HIP_IFEL(((bytes = recvfrom(socket, hip_msg, total, 0,
				    (struct sockaddr *) saddr,
				    &len)) != total), -1, "recv\n");

	HIP_DEBUG("received user message from local port %d\n",
		   ntohs(saddr->sin6_port));
	_HIP_DEBUG("read_user_control_msg recv len=%d\n", len);
	_HIP_HEXDUMP("recv saddr ", saddr, sizeof(struct sockaddr_un));
	_HIP_DEBUG("read %d bytes succesfully\n", bytes);
 out_err:
	if (bytes < 0 || err)
		HIP_PERROR("perror: ");

	return err;
}
Example #4
0
/*
 * Called from hip_for_each_hi
 */
int run_nsupdate_for_hit (struct hip_host_id_entry *entry, void *opaq)
{
	int start = 0;
	char ip_str[40]; // buffer for one IP address
	char ips_str[1024] = ""; // list of IP addresses
  	hip_list_t *item, *tmp_hip_list_t;
  	int i;
	char hit[INET6_ADDRSTRLEN + 2];

	if (opaq != NULL)
		start = * (int *) opaq;

	HIP_DEBUG("run_nsupdate_for_hit (start=%d)\n", start);

	hip_convert_hit_to_str(&entry->lhi.hit,NULL, hit);

	/* make space-separated list of IP addresses in ips_str */
  	list_for_each_safe(item, tmp_hip_list_t, addresses, i) {
		struct netdev_address *n = list_entry(item);

		if (netdev_address_to_str(n, ip_str, sizeof(ip_str))==NULL)
			HIP_PERROR("netdev_address_to_str");
		else {
			if (ips_str[0]!=0) // not empty
				strncat(ips_str, " ", sizeof(ips_str)-strlen(ips_str));
			strncat(ips_str, ip_str, sizeof(ips_str)-strlen(ips_str));
		}
	}

	run_nsupdate(ips_str, hit, start);

	return 0;
}
Example #5
0
/**
 * init_dht_gateway_socket_gw - Initializes socket for the openDHT
				communications based on gateway address family
 * @param sockfd	Socket descriptor to be initialized.
 * @param af		Address family
 *
 * @return Returns positive if socket creation was ok negative on error.
 */
int init_dht_gateway_socket_gw(int sockfd, struct addrinfo *gateway) {
    //default address family
    int af = AF_INET;

    if(gateway)
	af = gateway->ai_family;

    if ((sockfd = socket(af, SOCK_STREAM, IPPROTO_TCP)) < 0)
        HIP_PERROR("OpenDHT socket\n");
    
    return(sockfd);      
}
Example #6
0
int opendht_send(int sockfd, void *packet)
{
	int err = 0, len = strlen((char *)packet); 
  
	_HIP_DEBUG("Packet: %s\n",put_packet);
	_HIP_DEBUG("OpenDHT send: packet length: %d\n", len);
	
	if (len > 0)
		err = send(sockfd, (char *) packet, len, 0);

	if (err < 1)
		HIP_PERROR("Error opendht_send: ");

    return 0;
}
Example #7
0
/*
 * returns string "name=value"
 * remember to free()
 */
char *make_env(char *name, char *value)
{
 if ((name==NULL) || (value==NULL))
	return NULL;

 char *result = malloc(strlen(name) + 1 + strlen(value) + 1); // name,'=',value,0

 if (result == NULL) {
	HIP_PERROR("malloc");
	return NULL;
 }

 strcpy(result, name);
 strcat(result, "=");
 strcat(result, value);
 return result;
}
Example #8
0
/*
 * Close file descriptors except for the standard output and the standard error
 */
int close_all_fds_except_stdout_and_stderr()
{
	/* get maximum file descriptor number that can be opened */
        struct rlimit rlim;
        if (getrlimit(RLIMIT_NOFILE, &rlim)!=0) {
                HIP_PERROR("getrlimit");
		return ERR;
	}

	int fd; // no C99 :(
	for (fd = 0; fd < rlim.rlim_cur; fd++)
		switch (fd) {
			case STDOUT_FILENO: break;
			case STDERR_FILENO: break;
			default: close(fd);
		}

	return OK;
}
Example #9
0
/**
 *  connect_dht_gateway - Connects to given v6 gateway
 *  @param sockfd
 *  @param addrinfo Address to connect to 
 *  @param blocking 1 for blocking connect 0 for nonblocking
 *
 *  @return Returns 0 on success -1 otherwise, if nonblocking can return EINPRGORESS
 */
int connect_dht_gateway(int sockfd,
			   struct addrinfo * gateway,
			   int blocking){
    int flags = 0, error = 0;
    struct sockaddr_in *sa_v4;
    struct sockaddr_in6 *sa_v6;

    struct sigaction act, oact;
    act.sa_handler = connect_alarm;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    
    if(gateway == NULL){
            HIP_ERROR("No OpenDHT Serving Gateway Address.\n");
            return(-1);
    }
    
    if(blocking == 0)
        goto unblock;

    // blocking connect
    if(sigaction(SIGALRM, &act, &oact) < 0){
            HIP_DEBUG("Signal error before OpenDHT connect, "
                      "connecting without alarm\n");
            error = connect(sockfd, gateway->ai_addr, gateway->ai_addrlen);
    }else {
            HIP_DEBUG("Connecting to OpenDHT with alarm\n");
            if (alarm(DHT_CONNECT_TIMEOUT) != 0)
                HIP_DEBUG("Alarm was already set, connecting without\n");
            error = connect(sockfd, gateway->ai_addr, gateway->ai_addrlen);
            alarm(0);
            if (sigaction(SIGALRM, &oact, &act) <0 ) 
                HIP_DEBUG("Signal error after OpenDHT connect\n");
    }
    
    if(error < 0){
            HIP_PERROR("OpenDHT connect:");
            if (errno == EINTR)
                HIP_DEBUG("Connect to OpenDHT timedout\n");
            return(-1);
    }else{
	if(gateway->ai_family == AF_INET){
	    sa_v4 = (struct sockaddr_in *)gateway->ai_addr;
	    HIP_DEBUG_INADDR("Connected to OpenDHT v4 gateway", &(sa_v4->sin_addr));
	}
	else if(gateway->ai_family == AF_INET6){
            sa_v6 = (struct sockaddr_in6 *)gateway->ai_addr;
            HIP_DEBUG_IN6ADDR("Connected to OpenDHT v6 gateway", &(sa_v6->sin6_addr));
	}
	else{
	    HIP_DEBUG("Wrong address family for OPENDHT gateway %d\n", gateway->ai_family);
	}
	return(0);
    }
        
 unblock:
    // unblocking connect
    flags = fcntl(sockfd, F_GETFL, 0);
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); 
    
    if(gateway->ai_family == AF_INET){
	    sa_v4 = (struct sockaddr_in *)gateway->ai_addr;
	    HIP_DEBUG_INADDR("Connecting to OpenDHT v4 gateway", &(sa_v4->sin_addr));
    }
    else if(gateway->ai_family == AF_INET6){
            sa_v6 = (struct sockaddr_in6 *)gateway->ai_addr;
            HIP_DEBUG_IN6ADDR("Connecting to OpenDHT v6 gateway", &(sa_v6->sin6_addr));
    }
    else{
	    HIP_DEBUG("Wrong address family for OPENDHT gateway %d\n", gateway->ai_family);
    }

    if(connect(sockfd, gateway->ai_addr, gateway->ai_addrlen) < 0){
            if (errno == EINPROGRESS)
                return(EINPROGRESS);
            else{
                    HIP_PERROR("OpenDHT connect:");
                    return(-1);
            }
    }else{
            // connect ok
            return(0);
    }
}
Example #10
0
/**
 * main_server_native - it handles the functionality of the client-native
 * @param socktype the type of socket
 * @param port_name the prot number
 *
 * @return 1 with success, 0 otherwise.
 */
int main_server_native(int socktype, char *port_name, char *name)
{
	struct endpointinfo hints, *res = NULL;
	struct sockaddr_eid peer_eid;
	struct sockaddr_hip our_sockaddr, peer_sock;
	char mylovemostdata[IP_MAXPACKET];
	int recvnum, sendnum, serversock = 0, sockfd = 0, err = 0, on = 1;
	int endpoint_family = PF_HIP;
	socklen_t peer_eid_len = sizeof(struct sockaddr_hip);

	/* recvmsg() stuff for UDP multihoming */
	char control[CMSG_SPACE(40)];
	struct cmsghdr *cmsg;
	struct inet6_pktinfo *pktinfo;
	struct iovec iov = { &mylovemostdata, sizeof(mylovemostdata) - 1 };
	struct msghdr msg = { &peer_sock, sizeof(peer_sock), &iov, 1,
						&control, sizeof(control), 0 };

	serversock = socket(endpoint_family, socktype, 0);
	if (serversock < 0) {
		HIP_PERROR("socket: ");
		err = 1;
		goto out_err;
	}

	setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if (socktype == SOCK_DGRAM)
		setsockopt(serversock, IPPROTO_IPV6, IPV6_2292PKTINFO, &on, sizeof(on));

	memset(&hints, 0, sizeof(struct endpointinfo));
	hints.ei_family = endpoint_family;
	hints.ei_socktype = socktype;

	HIP_DEBUG("Native server calls getendpointinfo\n");

	err = getendpointinfo(NULL, port_name, &hints, &res);
	if (err || !res) {
		HIP_ERROR("Resolving of peer identifiers failed (%d)\n", err);
		goto out_err;
	}

	memset(&our_sockaddr, 0, sizeof(struct sockaddr_hip));
	if (name) {
		HIP_IFEL(inet_pton(AF_INET6, name, &our_sockaddr.ship_hit) != 1,
						    1, "Failed to parse HIT\n");
	}
	our_sockaddr.ship_port = htons(atoi(port_name));
	HIP_DEBUG("Binding to port %d\n", ntohs(our_sockaddr.ship_port));
	our_sockaddr.ship_family = endpoint_family;

	if (bind(serversock, &our_sockaddr, sizeof(struct sockaddr_hip)) < 0) {
		HIP_PERROR("bind: ");
		err = 1;
		goto out_err;
	}
	
	HIP_DEBUG("Native server calls listen\n");

	if (socktype == SOCK_STREAM && listen(serversock, 1) < 0) {
		HIP_PERROR("listen: ");
		err = 1;
		goto out_err;
	}

	HIP_DEBUG("Native server waits connection request\n");

	while(1) {
		if (socktype == SOCK_STREAM) {
			sockfd = accept(serversock, (struct sockaddr *) &peer_sock,
					&peer_eid_len);
			if (sockfd < 0) {
				HIP_PERROR("accept: ");
				err = 1;
				goto out_err;
			}

			while((recvnum = recv(sockfd, mylovemostdata,
					      sizeof(mylovemostdata), 0)) > 0 ) {
				mylovemostdata[recvnum] = '\0';
				printf("%s", mylovemostdata);
				fflush(stdout);

				sendnum = send(sockfd, mylovemostdata, recvnum, 0);
				if (sendnum < 0) {
					HIP_PERROR("send: ");
					err = 1;
					goto out_err;
				}
			}
		} else { /* UDP */
			sockfd = serversock;
			serversock = 0;
			while((recvnum = recvmsg(sockfd, &msg, 0)) > 0) {
				for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
					if (cmsg->cmsg_level == IPPROTO_IPV6 &&
					    cmsg->cmsg_type == IPV6_2292PKTINFO) {
						pktinfo = CMSG_DATA(cmsg);
						break;
					}
				}
				HIP_DEBUG_HIT("localaddr", &pktinfo->ipi6_addr);
				iov.iov_len = strlen(mylovemostdata);

				/* ancillary data contains the src
				 * and dst addresses */
				sendnum = sendmsg(sockfd, &msg, 0);
				if (sendnum < 0) {
					HIP_PERROR("sendto: ");
					err = 1;
					goto out_err;
				}
			}
		}
	}

out_err:

	if (res)
		free_endpointinfo(res);

	if (sockfd)
		close(sockfd); // discard errors
	if (serversock)
		close(serversock); // discard errors

	return err;
}
Example #11
0
/**
 * main_client_native - it handles the functionality of the client-native
 * @param proto type of protocol
 * @param socktype the type of socket
 * @param peer_name the peer name
 * @param peer_port_name the prot number
 *
 * @return 1 with success, 0 otherwise.
 */
int main_client_native(int socktype, char *peer_name, char *peer_port_name)
{
	//struct endpointinfo hints, *epinfo = NULL, *res = NULL;
	//struct endpointinfo *epinfo;
	struct addrinfo hints, *res = NULL;
	struct timeval stats_before, stats_after;
	struct sockaddr_hip peer_sock;
	unsigned long stats_diff_sec, stats_diff_usec;
	char mylovemostdata[IP_MAXPACKET];
	char receiveddata[IP_MAXPACKET];
	int recvnum, sendnum;
	int datalen = 0;
	int datasent = 0;
	int datareceived = 0;
	int ch;
	int err = 0;
	int sockfd = -1;
	se_family_t endpoint_family;

	endpoint_family = PF_HIP;

	sockfd = socket(endpoint_family, socktype, 0);
	HIP_IFEL(sockfd < 0, 1, "creation of socket failed\n");

#if 0
	/* set up host lookup information  */
	memset(&hints, 0, sizeof(hints));
	//hints.ei_socktype = socktype;
	//hints.ei_family = endpoint_family;
	hints.ai_socktype = socktype;
	hints.ai_family = endpoint_family;
	/* Use the following flags to use only the kernel list for name resolution
	 * hints.ei_flags = AI_HIP | AI_KERNEL_LIST;
	 */

	/* lookup host */
	//err = getendpointinfo(peer_name, peer_port_name, &hints, &res);
	if (err) {
		HIP_ERROR("getendpointfo failed\n");
		goto out_err;
	}
	//hints.ai_flags |= AI_EXTFLAGS;
	//hints.ai_eflags |= HIP_PREFER_ORCHID;

	err = getaddrinfo(peer_name, peer_port_name, &hints, &res);
	if (err) {
		HIP_ERROR("getaddrinfo failed (%d): %s\n", err, gepi_strerror(err));
		goto out_err;
	}
	if (!res) {
		HIP_ERROR("NULL result, TODO\n");
		goto out_err;
	}

/*
	HIP_DEBUG("family=%d value=%d\n", res->ei_family,
		  ntohs(((struct sockaddr_eid *) res->ei_endpoint)->eid_val));
*/
#endif

	/* XX TODO: Do a proper getaddrinfo() */
	memset(&peer_sock, 0, sizeof(peer_sock));
	peer_sock.ship_family = PF_HIP;
	HIP_IFEL(inet_pton(AF_INET6, peer_name, &peer_sock.ship_hit) != 1, 1, "Failed to parse HIT\n");
	peer_sock.ship_port = htons(atoi(peer_port_name));
	HIP_DEBUG("Connecting to %s port %d\n", peer_name, peer_sock.ship_port);

	// data from stdin to buffer
	memset(receiveddata, 0, IP_MAXPACKET);
	memset(mylovemostdata, 0, IP_MAXPACKET);

	printf("Input some text, press enter and ctrl+d\n");

	// horrible code
	while ((ch = fgetc(stdin)) != EOF && (datalen < IP_MAXPACKET)) {
		mylovemostdata[datalen] = (unsigned char) ch;
		datalen++;
	}

	gettimeofday(&stats_before, NULL);

#if 0
	epinfo = res;
	while(epinfo) {
		err = connect(sockfd, (struct sockaddr *) epinfo->ei_endpoint, epinfo->ei_endpointlen);
		//err = connect(sockfd, res->ai_addr, res->ai_addrlen);
		if (err) {
			HIP_PERROR("connect");
			goto out_err;
		}
		epinfo = epinfo->ei_next;
	}
#endif

	err = connect(sockfd, &peer_sock, sizeof(peer_sock));
	if (err) {
		HIP_PERROR("connect: ");
		goto out_err;
	}

	gettimeofday(&stats_after, NULL);
	stats_diff_sec  = (stats_after.tv_sec - stats_before.tv_sec) * 1000000;
	stats_diff_usec = stats_after.tv_usec - stats_before.tv_usec;

	HIP_DEBUG("connect took %.10f sec\n",
		  (stats_diff_sec + stats_diff_usec) / 1000000.0);

	/* Send the data read from stdin to the server and read the response.
	   The server should echo all the data received back to here. */
	while((datasent < datalen) || (datareceived < datalen)) {

		if (datasent < datalen) {
			sendnum = send(sockfd, mylovemostdata + datasent, datalen - datasent, 0);
      
			if (sendnum < 0) {
				HIP_PERROR("send");
				err = 1;
				goto out_err;
			}
			datasent += sendnum;
		}

		if (datareceived < datalen) {
			recvnum = recv(sockfd, receiveddata + datareceived,
				       datalen-datareceived, 0);
			if (recvnum <= 0) {
				HIP_PERROR("recv");
				err = 1;
				goto out_err;
			}
			datareceived += recvnum;
		}
	}

	HIP_IFEL(memcmp(mylovemostdata, receiveddata, IP_MAXPACKET),
				1, "Sent and received data did not match\n");

out_err:
	/*if (res)
		//free_endpointinfo(res);
		freeaddrinfo(res);*/
	if (sockfd > -1)
		close(sockfd); // discard errors

	HIP_INFO("Result of data transfer: %s.\n", (err ? "FAIL" : "OK"));

	return err;
}