((ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L)
struct Socket_tag {
- struct socket_function_table *fn;
+ const struct socket_function_table *fn;
/* the above variable absolutely *must* be the first in this structure */
char *error;
SOCKET s;
struct SockAddr_tag {
char *error;
- /* address family this belongs to, AF_INET for IPv4, AF_INET6 for IPv6. */
+ /*
+ * Which address family this address belongs to. AF_INET for
+ * IPv4; AF_INET6 for IPv6; AF_UNSPEC indicates that name
+ * resolution has not been done and a simple host name is held
+ * in this SockAddr structure.
+ */
int family;
unsigned long address; /* Address IPv4 style. */
#ifdef IPV6
struct addrinfo *ai; /* Address IPv6 style. */
#endif
+ char hostname[512]; /* Store an unresolved host name. */
};
static tree234 *sktree;
}
}
-SockAddr sk_namelookup(char *host, char **canonicalname)
+SockAddr sk_namelookup(const char *host, char **canonicalname)
{
SockAddr ret = smalloc(sizeof(struct SockAddr_tag));
unsigned long a;
return ret;
}
+SockAddr sk_nonamelookup(const char *host)
+{
+ SockAddr ret = smalloc(sizeof(struct SockAddr_tag));
+ ret->error = NULL;
+ ret->family = AF_UNSPEC;
+ strncpy(ret->hostname, host, lenof(ret->hostname));
+ ret->hostname[lenof(ret->hostname)-1] = '\0';
+ return ret;
+}
+
void sk_getaddr(SockAddr addr, char *buf, int buflen)
{
#ifdef IPV6
- if (addr->family == AF_INET) {
+ if (addr->family == AF_INET6) {
+ FIXME; /* I don't know how to get a text form of an IPv6 address. */
+ } else
#endif
+ if (addr->family == AF_INET) {
struct in_addr a;
a.s_addr = htonl(addr->address);
strncpy(buf, inet_ntoa(a), buflen);
-#ifdef IPV6
+ buf[buflen-1] = '\0';
} else {
- FIXME; /* I don't know how to get a text form of an IPv6 address. */
+ assert(addr->family == AF_UNSPEC);
+ strncpy(buf, addr->hostname, buflen);
+ buf[buflen-1] = '\0';
}
+}
+
+int sk_hostname_is_local(char *name)
+{
+ return !strcmp(name, "localhost");
+}
+
+int sk_address_is_local(SockAddr addr)
+{
+#ifdef IPV6
+ if (addr->family == AF_INET6) {
+ FIXME; /* someone who can compile for IPV6 had better do this bit */
+ } else
#endif
+ if (addr->family == AF_INET) {
+ struct in_addr a;
+ a.s_addr = htonl(addr->address);
+ return ipv4_is_loopback(a);
+ } else {
+ assert(addr->family == AF_UNSPEC);
+ return 0; /* we don't know; assume not */
+ }
}
int sk_addrtype(SockAddr addr)
{
- return (addr->family == AF_INET ? ADDRTYPE_IPV4 : ADDRTYPE_IPV6);
+ return (addr->family == AF_INET ? ADDRTYPE_IPV4 :
+#ifdef IPV6
+ addr->family == AF_INET6 ? ADDRTYPE_IPV6 :
+#endif
+ ADDRTYPE_NAME);
}
void sk_addrcopy(SockAddr addr, char *buf)
{
+ assert(addr->family != AF_UNSPEC);
#ifdef IPV6
- if (addr->family == AF_INET) {
+ if (addr->family == AF_INET6) {
+ memcpy(buf, (char*) addr->ai, 16);
+ } else
#endif
+ if (addr->family == AF_INET) {
struct in_addr a;
a.s_addr = htonl(addr->address);
memcpy(buf, (char*) &a.s_addr, 4);
-#ifdef IPV6
- } else {
- memcpy(buf, (char*) addr->ai, 16);
}
-#endif
}
void sk_addr_free(SockAddr addr)
}
static void sk_tcp_close(Socket s);
-static int sk_tcp_write(Socket s, char *data, int len);
-static int sk_tcp_write_oob(Socket s, char *data, int len);
+static int sk_tcp_write(Socket s, const char *data, int len);
+static int sk_tcp_write_oob(Socket s, const char *data, int len);
static void sk_tcp_set_private_ptr(Socket s, void *ptr);
static void *sk_tcp_get_private_ptr(Socket s);
static void sk_tcp_set_frozen(Socket s, int is_frozen);
Socket sk_register(void *sock, Plug plug)
{
- static struct socket_function_table fn_table = {
+ static const struct socket_function_table fn_table = {
sk_tcp_plug,
sk_tcp_close,
sk_tcp_write,
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
int nodelay, Plug plug)
{
- static struct socket_function_table fn_table = {
+ static const struct socket_function_table fn_table = {
sk_tcp_plug,
sk_tcp_close,
sk_tcp_write,
/*
* Open socket.
*/
+ assert(addr->family != AF_UNSPEC);
s = socket(addr->family, SOCK_STREAM, 0);
ret->s = s;
Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
{
- static struct socket_function_table fn_table = {
+ static const struct socket_function_table fn_table = {
sk_tcp_plug,
sk_tcp_close,
sk_tcp_write,
ret->oobinline = 0;
-
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on));
-
#ifdef IPV6
if (addr->family == AF_INET6) {
memset(&a6, 0, sizeof(a6));
}
}
-static int sk_tcp_write(Socket sock, char *buf, int len)
+static int sk_tcp_write(Socket sock, const char *buf, int len)
{
Actual_Socket s = (Actual_Socket) sock;
return bufchain_size(&s->output_data);
}
-static int sk_tcp_write_oob(Socket sock, char *buf, int len)
+static int sk_tcp_write_oob(Socket sock, const char *buf, int len)
{
Actual_Socket s = (Actual_Socket) sock;
/* wParam is the socket itself */
- /*
- * One user has reported an assertion failure in tree234 which
- * indicates a null element pointer has been passed to a
- * find*234 function. The following find234 is the only one in
- * the whole program that I can see being capable of doing
- * this, hence I'm forced to conclude that WinSock is capable
- * of sending me netevent messages with wParam==0. I want to
- * know what the rest of the message is if it does so!
- */
- if (wParam == 0) {
- char *str;
- str = dupprintf("Strange WinSock message: wp=%08x lp=%08x",
- (int)wParam, (int)lParam);
- logevent(NULL, str);
- connection_fatal(NULL, str);
- sfree(str);
- }
+ if (wParam == 0)
+ return 1; /* boggle */
s = find234(sktree, (void *) wParam, cmpforsearch);
if (!s)