/* $Id$
This file is part of libmspnet
-Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008, 2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
{
check_state(false);
- sockaddr sa;
+ sockaddr_storage sa;
socklen_t size=addr.fill_sockaddr(sa);
- int err=::connect(handle, &sa, size);
+ int err=::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
if(err==-1)
throw SystemError("Unable to connect", errno);
peer_addr=addr.copy();
delete local_addr;
- size=sizeof(sockaddr);
- getsockname(handle, &sa, &size);
+ size=sizeof(sockaddr_storage);
+ getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
local_addr=SockAddr::create(sa);
connected=true;
if(size==0)
return 0;
- sockaddr addr;
+ sockaddr_storage addr;
socklen_t addr_len=addr_.fill_sockaddr(addr);
- int ret=::sendto(handle, buf, size, 0, &addr, addr_len);
+ int ret=::sendto(handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), addr_len);
if(ret<0)
{
if(errno==EAGAIN)
if(size==0)
return 0;
- sockaddr addr;
- socklen_t addr_len=sizeof(sockaddr);
+ sockaddr_storage addr;
+ socklen_t addr_len=sizeof(sockaddr_storage);
- int ret=::recvfrom(handle, buf, size, 0, &addr, &addr_len);
+ int ret=::recvfrom(handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), &addr_len);
if(ret<0)
{
if(errno==EAGAIN)
/* $Id$
This file is part of libmspnet
-Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008, 2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
port(0)
{ }
-InetAddr::InetAddr(sockaddr_in &sa):
+InetAddr::InetAddr(const sockaddr_in &sa):
addr(sa.sin_addr.s_addr),
port(sa.sin_port)
{ }
string InetAddr::str() const
{
const unsigned char *ptr=reinterpret_cast<const unsigned char *>(&addr);
- return format("%d.%d.%d.%d:%d", static_cast<int>(ptr[0]), static_cast<int>(ptr[1]), static_cast<int>(ptr[2]), static_cast<int>(ptr[3]), ntohs(port));
+ string result = format("%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);
+ if(port)
+ result += format(":%d", ntohs(port));
+ return result;
}
unsigned InetAddr::fill_sockaddr(sockaddr &sa) const
/* $Id$
This file is part of libmspnet
-Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008, 2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
#else
#include <netinet/in.h>
#endif
-#include <string>
#include "sockaddr.h"
namespace Msp {
namespace Net {
-#ifdef WIN32
-typedef u_long in_addr_t;
-typedef u_short in_port_t;
-#endif
-
/**
Address class for IPv4 sockets.
*/
class InetAddr: public SockAddr
{
private:
+#ifdef WIN32
+ typedef u_long in_addr_t;
+ typedef u_short in_port_t;
+#endif
+
in_addr_t addr;
in_port_t port;
public:
InetAddr();
- InetAddr(sockaddr_in &);
+ InetAddr(const sockaddr_in &);
InetAddr(in_addr_t, in_port_t);
Family get_family() const { return INET; }
--- /dev/null
+/* $Id$
+
+This file is part of libmspnet
+Copyright © 2011 Mikkosoft Productions, Mikko Rasa
+Distributed under the LGPL
+*/
+
+#include <msp/core/except.h>
+#include <msp/strings/formatter.h>
+#include "inet6.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Net {
+
+Inet6Addr::Inet6Addr():
+ addr(in6addr_any),
+ port(0)
+{ }
+
+Inet6Addr::Inet6Addr(const sockaddr_in6 &sai6):
+ addr(sai6.sin6_addr),
+ port(sai6.sin6_port)
+{ }
+
+Inet6Addr::Inet6Addr(unsigned char a[16], in_port_t p):
+ port(p)
+{
+ std::copy(a, a+16, addr.s6_addr);
+}
+
+string Inet6Addr::str() const
+{
+ string result = "[";
+ for(unsigned i=0; i<16; i+=2)
+ {
+ unsigned short part = (addr.s6_addr[i]<<8) | addr.s6_addr[i+1];
+ if(i>0)
+ result += ':';
+ result += format("%x", part);
+ }
+ result += ']';
+ if(port)
+ result += format(":%d", ntohs(port));
+
+ return result;
+}
+
+unsigned Inet6Addr::fill_sockaddr(sockaddr &) const
+{
+ throw Exception("Inet6Addr doesn't fit in struct sockaddr");
+}
+
+unsigned Inet6Addr::fill_sockaddr(sockaddr_storage &sa) const
+{
+ sockaddr_in6 &sai6 = reinterpret_cast<sockaddr_in6 &>(sa);
+ sai6.sin6_family = AF_INET6;
+ sai6.sin6_port = port;
+ sai6.sin6_addr = addr;
+ sai6.sin6_flowinfo = 0;
+ sai6.sin6_scope_id = 0;
+
+ return sizeof(sockaddr_in6);
+}
+
+} // namespace Net
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspnet
+Copyright © 2011 Mikkosoft Productions, Mikko Rasa
+Distributed under the LGPL
+*/
+
+#ifndef MSP_NET_INET6_H_
+#define NSP_NET_INET6_H_
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <netinet/in.h>
+#endif
+#include "sockaddr.h"
+
+namespace Msp {
+namespace Net {
+
+class Inet6Addr: public SockAddr
+{
+private:
+#ifdef WIN32
+ typedef u_short in_port_t;
+#endif
+
+ in6_addr addr;
+ in_port_t port;
+
+public:
+ Inet6Addr();
+ Inet6Addr(const sockaddr_in6 &);
+ Inet6Addr(unsigned char [16], in_port_t);
+
+ virtual Family get_family() const { return INET6; }
+ virtual std::string str() const;
+
+ virtual unsigned fill_sockaddr(sockaddr &) const;
+ virtual unsigned fill_sockaddr(sockaddr_storage &) const;
+
+ virtual Inet6Addr *copy() const { return new Inet6Addr(*this); }
+};
+
+} // namespace Net
+} // namespace Msp
+
+#endif
/* $Id$
This file is part of libmspnet
-Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008, 2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
SockAddr *resolve(const string &s, Family family)
{
string host, serv;
- unsigned colon=s.find(':');
- if(colon!=string::npos)
+ if(s[0]=='[')
{
- host=s.substr(0, colon);
- serv=s.substr(colon+1);
+ unsigned bracket = s.find(']');
+ host = s.substr(1, bracket-1);
+ unsigned colon = s.find(':', bracket);
+ if(colon!=string::npos)
+ serv = s.substr(colon+1);
}
else
- host=s;
+ {
+ unsigned colon = s.find(':');
+ if(colon!=string::npos)
+ {
+ host = s.substr(0, colon);
+ serv = s.substr(colon+1);
+ }
+ else
+ host = s;
+ }
addrinfo hints={0, family, 0, 0, 0, 0, 0, 0};
addrinfo *res;
/* $Id$
This file is part of libmspnet
-Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008, 2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
#include <msp/core/except.h>
#include "inet.h"
+#include "inet6.h"
namespace Msp {
namespace Net {
-SockAddr *SockAddr::create(sockaddr &sa)
+unsigned SockAddr::fill_sockaddr(sockaddr_storage &sa) const
{
- switch(sa.sa_family)
+ return fill_sockaddr(reinterpret_cast<sockaddr &>(sa));
+}
+
+SockAddr *SockAddr::create(const sockaddr_storage &sa)
+{
+ switch(sa.ss_family)
{
case AF_INET:
- return new InetAddr(reinterpret_cast<sockaddr_in &>(sa));
+ return new InetAddr(reinterpret_cast<const sockaddr_in &>(sa));
+ case AF_INET6:
+ return new Inet6Addr(reinterpret_cast<const sockaddr_in6 &>(sa));
default:
throw InvalidParameterValue("Unknown address family");
}
/* $Id$
This file is part of libmspnet
-Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008, 2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
#ifndef MSP_NET_SOCKADDR_H_
#define MSP_NET_SOCKADDR_H_
+#include <string>
#ifndef WIN32
#include <sys/socket.h>
#endif
@return Number of bytes used
*/
virtual unsigned fill_sockaddr(sockaddr &) const =0;
+ virtual unsigned fill_sockaddr(sockaddr_storage &) const;
virtual SockAddr *copy() const =0;
virtual ~SockAddr() { }
- static SockAddr *create(sockaddr &);
+ static SockAddr *create(const sockaddr &sa) { return create(reinterpret_cast<const sockaddr_storage &>(sa)); }
+ static SockAddr *create(const sockaddr_storage &);
protected:
SockAddr() { }
};
/* $Id$
This file is part of libmspnet
-Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008, 2010-2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
local_addr(0),
peer_addr(paddr.copy())
{
- sockaddr sa;
- socklen_t size=sizeof(sockaddr);
- getsockname(handle, &sa, &size);
+ sockaddr_storage sa;
+ socklen_t size=sizeof(sockaddr_storage);
+ getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
local_addr=SockAddr::create(sa);
#ifdef WIN32
{
check_state(false);
- sockaddr sa;
+ sockaddr_storage sa;
unsigned size=addr.fill_sockaddr(sa);
- int err=::bind(handle, &sa, size);
+ int err=::bind(handle, reinterpret_cast<sockaddr *>(&sa), size);
if(err==-1)
throw SystemError("Unable to bind", errno);
/* $Id$
This file is part of libmspnet
-Copyright © 2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008, 2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
if(!listening)
throw InvalidState("Socket is not listening");
- sockaddr sa;
- socklen_t size=sizeof(sockaddr);
- SocketHandle new_h=::accept(handle, &sa, &size);
+ sockaddr_storage sa;
+ socklen_t size=sizeof(sockaddr_storage);
+ SocketHandle new_h=::accept(handle, reinterpret_cast<sockaddr *>(&sa), &size);
RefPtr<SockAddr> paddr=SockAddr::create(sa);
return new StreamSocket(new_h, *paddr);
/* $Id$
This file is part of libmspnet
-Copyright © 2008-2009 Mikkosoft Productions, Mikko Rasa
+Copyright © 2008-2009, 2011 Mikkosoft Productions, Mikko Rasa
Distributed under the LGPL
*/
if(connected)
throw InvalidState("Socket is already connected");
- sockaddr sa;
+ sockaddr_storage sa;
socklen_t size=addr.fill_sockaddr(sa);
#ifdef WIN32
- int err=WSAConnect(handle, &sa, size, 0, 0, 0, 0);
+ int err=WSAConnect(handle, reinterpret_cast<sockaddr *>(&sa), size, 0, 0, 0, 0);
if(err==SOCKET_ERROR)
{
int err_code=WSAGetLastError();
throw Exception(format("Unable to connect: %d", err_code));
}
#else
- int err=::connect(handle, &sa, size);
+ int err=::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
if(err==-1)
{
if(errno==EINPROGRESS)
peer_addr=addr.copy();
delete local_addr;
- size=sizeof(sockaddr);
- getsockname(handle, &sa, &size);
+ size=sizeof(sockaddr_storage);
+ getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
local_addr=SockAddr::create(sa);
if(err==0)