$ git clone https://socialnetwork.ion.nu/socialnetwork.git
commit c76b97a476bf6899bd775e298f9ed5fad650304e
Author: Alicia <...>
Date: Fri Jun 9 15:53:49 2017 +0000
Switched from struct sockaddr to struct sockaddr_storage, which is large enough to hold IPv6 addresses.
diff --git a/peer.c b/peer.c
index 7d02247..dc3b50a 100644
--- a/peer.c
+++ b/peer.c
@@ -81,7 +81,7 @@ static void sendpeers(struct peer* peer, void* x, unsigned int len)
struct peeritem
{
uint16_t addrlen;
- struct sockaddr addr;
+ struct sockaddr_storage addr;
uint16_t peercount;
};
static void getpeers(struct peer* peer, void* data, unsigned int len)
@@ -95,7 +95,7 @@ static void getpeers(struct peer* peer, void* data, unsigned int len)
{
memcpy(&addrlen, data, sizeof(addrlen));
if(len<sizeof(addrlen)+addrlen+sizeof(pcount)){break;}
- if(addrlen<=sizeof(struct sockaddr))
+ if(addrlen<=sizeof(struct sockaddr_storage))
{
++pcount;
peers=realloc(peers, sizeof(struct peeritem)*pcount);
@@ -128,7 +128,7 @@ printf("We now have %u peers\n", peercount);
struct findpeer_request
{
unsigned char id[ID_SIZE];
- struct sockaddr addr;
+ struct sockaddr_storage addr;
uint16_t addrlen;
time_t timestamp;
};
@@ -144,7 +144,7 @@ printf("Got findpeer request for '"PEERFMT"'\n", PEERARG(id));
memcpy(&ttl, data+ID_SIZE, sizeof(ttl));
if(!ttl){return;}
--ttl;
- struct sockaddr addr;
+ struct sockaddr_storage addr;
uint16_t addrlen;
if(len>ID_SIZE+sizeof(ttl)+sizeof(addrlen))
{ // Has address already
@@ -350,7 +350,7 @@ struct peer* peer_get(struct udpstream* stream)
return peer_new(stream, 1);
}
-struct peer* peer_new_unique(int sock, struct sockaddr* addr, socklen_t addrlen)
+struct peer* peer_new_unique(int sock, struct sockaddr_storage* addr, socklen_t addrlen)
{
unsigned int i;
// Make sure we're not already connected to this peer
@@ -376,12 +376,20 @@ void peer_bootstrap(int sock, const char* peerlist)
entry=(end[0]?&end[1]:0);
char* port;
if((port=strchr(peer, '\r'))){port[0]=0;}
- if(!(port=strchr(peer, ':'))){continue;} // Bogus entry
+ if(!(port=strrchr(peer, ':'))){continue;} // Bogus entry
port[0]=0;
+ // Strip [ and ] (IPv6)
+ char* host=peer;
+ if(host[0]=='[')
+ {
+ host=&host[1];
+ char* end=strchr(host, ']');
+ if(end){end[0]=0;}
+ }
struct addrinfo* ai;
- if(!getaddrinfo(peer, &port[1], 0, &ai))
+ if(!getaddrinfo(host, &port[1], 0, &ai))
{
- peer_new_unique(sock, ai->ai_addr, ai->ai_addrlen);
+ peer_new_unique(sock, (struct sockaddr_storage*)ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(ai);
}
}
@@ -514,15 +522,11 @@ void peer_exportpeers(const char* path)
for(i=0; i<peercount; ++i)
{
if(!peers[i]->handshake){continue;} // Skip bad peers
- switch(peers[i]->addr.sa_family)
- {
- case AF_INET:
- {
- struct sockaddr_in* addr=(struct sockaddr_in*)&peers[i]->addr;
- unsigned char* ip=(unsigned char*)&addr->sin_addr.s_addr;
- dprintf(f, "%hhu.%hhu.%hhu.%hhu:%hu\n", ip[0], ip[1], ip[2], ip[3], ntohs(addr->sin_port));
- }
- }
+ char addr[INET6_ADDRSTRLEN];
+ char port[64];
+ if(getnameinfo((struct sockaddr*)&peers[i]->addr, peers[i]->addrlen, addr, INET6_ADDRSTRLEN, port, 64, NI_NUMERICHOST|NI_NUMERICSERV|NI_DGRAM)){continue;}
+ const char* fmt=((peers[i]->addr.ss_family==AF_INET6)?"[%s]:%s":"%s:%s");
+ dprintf(f, fmt, addr, port);
}
close(f);
}
diff --git a/peer.h b/peer.h
index b0b85b4..5b316b0 100644
--- a/peer.h
+++ b/peer.h
@@ -28,7 +28,7 @@ struct peer
uint8_t cmdlength;
char* cmdname;
int32_t datalength;
- struct sockaddr addr;
+ struct sockaddr_storage addr;
socklen_t addrlen;
unsigned char id[ID_SIZE]; // SHA2-256 sum of public key (binary)
gnutls_x509_crt_t cert;
@@ -44,7 +44,7 @@ extern void peer_registercmd(const char* name, void(*callback)(struct peer*,void
extern void peer_init(const char* keypath);
extern struct peer* peer_new(struct udpstream* stream, char server);
extern struct peer* peer_get(struct udpstream* stream);
-extern struct peer* peer_new_unique(int sock, struct sockaddr* addr, socklen_t addrlen);
+extern struct peer* peer_new_unique(int sock, struct sockaddr_storage* addr, socklen_t addrlen);
extern void peer_bootstrap(int sock, const char* peerlist);
extern void peer_handlesocket(int sock); // Incoming data
extern void peer_sendcmd(struct peer* peer, const char* cmd, const void* data, uint32_t len);
diff --git a/udpstream.c b/udpstream.c
index ba57da5..86cedf3 100644
--- a/udpstream.c
+++ b/udpstream.c
@@ -49,7 +49,7 @@ struct packet
struct udpstream
{
int sock;
- struct sockaddr addr;
+ struct sockaddr_storage addr;
socklen_t addrlen;
uint16_t inseq;
uint16_t outseq;
@@ -67,7 +67,7 @@ struct udpstream
static struct udpstream** streams=0;
static unsigned int streamcount=0;
-static struct udpstream* stream_new(int sock, struct sockaddr* addr, socklen_t addrlen)
+static struct udpstream* stream_new(int sock, struct sockaddr_storage* addr, socklen_t addrlen)
{
struct udpstream* stream=malloc(sizeof(struct udpstream));
stream->sock=sock;
@@ -89,7 +89,7 @@ static struct udpstream* stream_new(int sock, struct sockaddr* addr, socklen_t a
return stream;
}
-struct udpstream* udpstream_find(struct sockaddr* addr, socklen_t addrlen)
+struct udpstream* udpstream_find(struct sockaddr_storage* addr, socklen_t addrlen)
{
unsigned int i;
for(i=0; i<streamcount; ++i)
@@ -110,7 +110,7 @@ static ssize_t stream_send(struct udpstream* stream, uint8_t type, uint16_t seq,
memcpy(packet+sizeof(uint32_t), &seq, sizeof(uint16_t));
memcpy(packet+sizeof(uint32_t)+sizeof(uint16_t), &type, sizeof(uint8_t));
memcpy(packet+HEADERSIZE, buf, size);
- return sendto(stream->sock, packet, HEADERSIZE+size, 0, &stream->addr, stream->addrlen);
+ return sendto(stream->sock, packet, HEADERSIZE+size, 0, (struct sockaddr*)&stream->addr, stream->addrlen);
}
static void udpstream_requestresend(struct udpstream* stream, uint16_t seq)
@@ -163,7 +163,7 @@ static void stream_free(struct udpstream* stream)
}
}
-struct udpstream* udpstream_new(int sock, struct sockaddr* addr, socklen_t addrlen)
+struct udpstream* udpstream_new(int sock, struct sockaddr_storage* addr, socklen_t addrlen)
{
struct udpstream* stream=stream_new(sock, addr, addrlen);
stream->state=STATE_INIT; // If we're creating the stream we're the ones initializing it
@@ -175,9 +175,9 @@ void udpstream_readsocket(int sock)
{
time_t now=time(0);
char buf[1024];
- struct sockaddr addr;
+ struct sockaddr_storage addr;
socklen_t addrlen=sizeof(addr);
- ssize_t len=recvfrom(sock, buf, 1024, 0, &addr, &addrlen);
+ ssize_t len=recvfrom(sock, buf, 1024, 0, (struct sockaddr*)&addr, &addrlen);
struct udpstream* stream=udpstream_find(&addr, addrlen);
if(!stream){stream=stream_new(sock, &addr, addrlen);}
stream->buflen+=len;
@@ -370,7 +370,7 @@ ssize_t udpstream_write(struct udpstream* stream, const void* buf, size_t size)
return size;
}
-void udpstream_getaddr(struct udpstream* stream, struct sockaddr* addr, socklen_t* addrlen)
+void udpstream_getaddr(struct udpstream* stream, struct sockaddr_storage* addr, socklen_t* addrlen)
{
if(*addrlen>stream->addrlen){*addrlen=stream->addrlen;}
memcpy(addr, &stream->addr, *addrlen);
diff --git a/udpstream.h b/udpstream.h
index ccb2184..b1c4802 100644
--- a/udpstream.h
+++ b/udpstream.h
@@ -21,9 +21,9 @@
struct udpstream;
// Create a new stream on the given socket that sends and receives to/from the given address
-extern struct udpstream* udpstream_new(int sock, struct sockaddr* addr, socklen_t addrlen);
+extern struct udpstream* udpstream_new(int sock, struct sockaddr_storage* addr, socklen_t addrlen);
-extern struct udpstream* udpstream_find(struct sockaddr* addr, socklen_t addrlen);
+extern struct udpstream* udpstream_find(struct sockaddr_storage* addr, socklen_t addrlen);
extern void udpstream_readsocket(int sock);
@@ -35,7 +35,7 @@ extern ssize_t udpstream_read(struct udpstream* stream, void* buf, size_t size);
extern ssize_t udpstream_write(struct udpstream* stream, const void* buf, size_t size);
// Get the network address of a stream's peer (useful for UDP-punchthrough)
-extern void udpstream_getaddr(struct udpstream* stream, struct sockaddr* addr, socklen_t* addrlen);
+extern void udpstream_getaddr(struct udpstream* stream, struct sockaddr_storage* addr, socklen_t* addrlen);
extern int udpstream_getsocket(struct udpstream* stream);
diff --git a/udptest.c b/udptest.c
index be25c6f..68f7a96 100644
--- a/udptest.c
+++ b/udptest.c
@@ -31,7 +31,7 @@ int main(int argc, char** argv)
{
struct addrinfo* ai;
getaddrinfo(argv[1], argv[2], 0, &ai);
- stream=udpstream_new(sock, ai->ai_addr, ai->ai_addrlen);
+ stream=udpstream_new(sock, (struct sockaddr_storage*)ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(ai);
}
else if(argc>1)
@@ -60,13 +60,14 @@ int main(int argc, char** argv)
struct udpstream* rstream;
while((rstream=udpstream_poll()))
{
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
socklen_t addrlen=sizeof(addr);
- udpstream_getaddr(rstream, (struct sockaddr*)&addr, &addrlen);
- if(addr.sin_family==AF_INET)
+ udpstream_getaddr(rstream, &addr, &addrlen);
+ if(addr.ss_family==AF_INET)
{
- uint32_t ip=addr.sin_addr.s_addr;
- printf("From: %u.%u.%u.%u:%hu:\n", ip%0x100, (ip/0x100)%0x100, (ip/0x10000)%0x100, ip/0x1000000, ntohs(addr.sin_port));
+ uint32_t ip=((struct sockaddr_in*)&addr)->sin_addr.s_addr;
+ uint16_t port=((struct sockaddr_in*)&addr)->sin_port;
+ printf("From: %u.%u.%u.%u:%hu:\n", ip%0x100, (ip/0x100)%0x100, (ip/0x10000)%0x100, ip/0x1000000, ntohs(port));
}
ssize_t len=udpstream_read(rstream, buf, 1024);
if(len<1){udpstream_close(rstream); if(stream==rstream){stream=0;} continue;}