Newer
Older
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
const char * real_address(const char *address, struct sockaddr_in6 *rval)
{
struct addrinfo hints;
struct addrinfo *result;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_CANONNAME;
hints.ai_protocol = 0;
int res = getaddrinfo(address, NULL, &hints, &result);
if ( res != 0 )
return gai_strerror(res);
rval = (struct sockaddr_in6 *) memcpy( (void *) rval, result->ai_addr, sizeof(struct sockaddr_in6));
freeaddrinfo(result);
return NULL;
}
void ipv6_to_str_unexpanded(char *str, const struct in6_addr *addr) {
sprintf(str, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
(int)addr->s6_addr[0], (int)addr->s6_addr[1],
(int)addr->s6_addr[2], (int)addr->s6_addr[3],
(int)addr->s6_addr[4], (int)addr->s6_addr[5],
(int)addr->s6_addr[6], (int)addr->s6_addr[7],
(int)addr->s6_addr[8], (int)addr->s6_addr[9],
(int)addr->s6_addr[10], (int)addr->s6_addr[11],
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[14], (int)addr->s6_addr[15]);
}
int create_socket_bind(struct sockaddr_in6 * source_addr)
{
// TODO: Create a IPv6 socket supporting datagrams
int sock = socket(AF_INET6, SOCK_DGRAM, 0);
// TODO: Bind it to the source
int err = bind(sock, (struct sockaddr *) source_addr, sizeof(struct sockaddr_in6));
if (err == -1)
return -1;
char text[100];
ipv6_to_str_unexpanded(text, &(source_addr->sin6_addr));
//const char * addr_str = inet_ntop(AF_INET6, (void *) &(source_addr->sin6_addr), text, 100);
DEBUG("Successfully bound to IPv6 address : %s, port : %d", text, ntohs(source_addr->sin6_port));
return sock;
}
int create_socket_connect(struct sockaddr_in6 * dest_addr)
{
int sock = socket(AF_INET6, SOCK_DGRAM, 0);
int err = connect(sock, (struct sockaddr *) dest_addr, sizeof(*dest_addr));
if (err == -1)
return -1;
char text[100];
ipv6_to_str_unexpanded(text, &(dest_addr->sin6_addr));
DEBUG("Successfully connected to IPv6 addresss: %s, port : %d", text, ntohs(dest_addr->sin6_port));
return sock;
}
int create_socket(struct sockaddr_in6 *source_addr, int src_port, struct sockaddr_in6 *dest_addr, int dst_port)
{
{
source_addr->sin6_port = htons(src_port);
return create_socket_bind(source_addr);
} else if ( source_addr == NULL && dest_addr != NULL ){
dest_addr->sin6_port = htons(dst_port);
return create_socket_connect(dest_addr);
}
return -1;
}
int wait_for_client(int sfd)
int MAX_MESSAGE_SIZE = 1024;
uint8_t buff[MAX_MESSAGE_SIZE]; // allocate the receive buffer on the stack
struct sockaddr_storage peer_addr; // allocate the peer's address on the stack. It will be initialized when we receive a message
socklen_t peer_addr_len = sizeof(struct sockaddr_storage); // variable that will contain the length of the peer's address
ssize_t amount_read = recvfrom(sfd, buff, MAX_MESSAGE_SIZE, MSG_PEEK, (struct sockaddr *) &peer_addr, &peer_addr_len);
if (amount_read == -1){
int err = connect(sfd, (struct sockaddr *) &peer_addr, sizeof(struct sockaddr_storage));
Vany Ingenzi
a validé
char text[100];
struct sockaddr_in6 * cast = (struct sockaddr_in6 *) &peer_addr;
ipv6_to_str_unexpanded(text, &(cast->sin6_addr));
DEBUG("Successfully connected to IPv6 addresss: %s, port : %d", text, ntohs(cast->sin6_port));
Vany Ingenzi
a validé
}
unsigned long long int time_milliseconds(struct timeval *time)
{
return ((unsigned long long int) time->tv_sec * 1000) + ((unsigned long long int) time->tv_usec / 1000);
}
void write_stats_to_file(const char * pathname, transfer_stats_t * stats_file, agents_t caller)
Vany Ingenzi
a validé
{
if (pathname == NULL || stats_file == NULL)
return;
int fd = open(pathname, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU);
Vany Ingenzi
a validé
if (fd == -1)
{
// We can use strerror cause here the error is known since we are using standard library open
DEBUG("%s", strerror(errno));
return;
}
Vany Ingenzi
a validé
char buffer[100];
ret = sprintf((char *) &buffer, "data_sent:%llu\n", stats_file->data_sent);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "data_received:%llu\n", stats_file->data_received);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "data_truncated_received:%llu\n", stats_file->data_truncated_received);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "fec_sent:%llu\n", stats_file->fec_sent);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "fec_received:%llu\n", stats_file->fec_received);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "ack_sent:%llu\n", stats_file->ack_sent);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "ack_received:%llu\n", stats_file->ack_received);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "nack_received:%llu\n", stats_file->nack_received);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "packet_ignored:%llu\n", stats_file->packet_ignored);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
if (caller == RECEIVER)
{
ret = sprintf((char *) &buffer, "packet_duplicated:%llu\n", stats_file->packet_duplicated);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "packet_recovered:%llu\n", stats_file->packet_recovered);
ret = write(fd, buffer, strlen(buffer));
}
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "min_rtt:%llu\n", stats_file->min_rtt);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "max_rtt:%llu\n", stats_file->max_rtt);
ret = write(fd, buffer, strlen(buffer));
Vany Ingenzi
a validé
ret = sprintf((char *) &buffer, "packet_retransmitted:%llu\n", stats_file->packet_retransmitted);
ret = write(fd, buffer, strlen(buffer));
}
Vany Ingenzi
a validé
close(fd);
Vany Ingenzi
a validé
DEBUG("Wrote the transfer statistics to %s.", pathname);
return;