fnetaccept: get client's address on each udp msg; win32 tweaks
1 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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
diff --git a/fnet.c b/fnet.c
index 66642d9..7606f0d 100644
--- a/fnet.c
+++ b/fnet.c
@@ -86,17 +86,17 @@ struct NetConn
SockType socktype;
ParsedV4V6 v4v6;
NetAddr remote, local;
- int fd;
+ sockt fd;
};
static NetConn* newnetconn(char *proto, char *addr, ConnType ct);
static int setsockdomaintype(NetConn *c, char *proto, char *addr);
-static int sockdial(NetConn *c);
-static int socklisten(NetConn *c);
-static int sockaccept(NetConn *c);
+static sockt sockdial(NetConn *c);
+static sockt socklisten(NetConn *c);
+static sockt sockaccept(NetConn *c);
static int setlocaddr(NetConn *c);
static int setremaddr(NetConn *c);
-static FILE* fdfile(int fd);
+static FILE* fdfile(sockt fd);
static int parsev4v6(char *addr, ParsedV4V6 *result);
static int setfneterr(char *fmt, ...);
static char* sockerrstr();
@@ -210,8 +210,8 @@ fnetaccept(NetConn *servc)
NetConn *clientc;
if(servc->socktype == DgRam){
- setfneterr("fnetaccept should be applied on stream sockets");
- return nil;
+ setremaddr(servc);
+ return servc;
}
clientc = newnetconn(servc->local.proto, servc->local.addr, Listen);
@@ -257,10 +257,10 @@ typedef struct sockaddr_un SockaddrUnix;
typedef struct sockaddr Sockaddr;
static
-int
+sockt
sockdial(NetConn *c)
{
- int fd;
+ sockt fd;
SockaddrIn addrV4;
SockaddrIn6 addrV6;
SockaddrUnix addrUnix;
@@ -296,7 +296,8 @@ sockdial(NetConn *c)
#endif
if(c->socktype == DgRam){
int b=1;
- setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &b, sizeof(b));
+ void *p= &b;
+ setsockopt(fd, SOL_SOCKET, SO_BROADCAST, p, sizeof(b));
}
switch(c->sockdomain)
@@ -339,10 +340,10 @@ sockdial(NetConn *c)
}
static
-int
+sockt
socklisten(NetConn *c)
{
- int fd;
+ sockt fd;
SockaddrIn addrV4;
SockaddrIn6 addrV6;
SockaddrUnix addrUnix;
@@ -424,14 +425,21 @@ socklisten(NetConn *c)
return fd;
}
-int
+sockt
sockaccept(NetConn *c)
{
- int cfd = accept(c->fd, nil, nil);
+ sockt cfd = accept(c->fd, nil, nil);
+#ifndef _WIN32
if(cfd < 0){
setfneterr("accept failed (%s)", sockerrstr());
return -1;
}
+#else
+ if(cfd == INVALID_SOCKET){
+ setfneterr("accept failed (%s)", sockerrstr());
+ return -1;
+ }
+#endif
return cfd;
}
@@ -517,10 +525,19 @@ setremaddr(NetConn *c)
}
}else{
char b[1];
+ SockaddrIn addr;
+ addr.sin_family = AF_UNSPEC;
+ memset(&addr, 0, sizeof(addr));
+ connect(c->fd, (Sockaddr*)&addr, sizeof(addr));
+
if(recvfrom(c->fd, b, 1, MSG_PEEK, paddr, &addrlen) < 0){
setfneterr("recvfrom failed (%s)", sockerrstr());
return -1;
}
+ if(connect(c->fd, paddr, addrlen) < 0){
+ setfneterr("connection failed (%s)", errnostr());
+ return -1;
+ }
}
if(c->sockdomain == IPv4){
@@ -543,7 +560,7 @@ setremaddr(NetConn *c)
#ifndef _WIN32
static
FILE*
-fdfile(int fd)
+fdfile(sockt fd)
{
FILE *f = fdopen(fd, "r+");
if(f == nil){