summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-03-08 17:19:50 +0100
committerStefan Metzmacher <metze@samba.org>2009-03-08 17:22:25 +0100
commitf9156f6c77d9e87edc153b024a1d564b44eedd8f (patch)
treeff92cdb53c407d7e26a79a5bc4e5cc2c8b11ab42
parent81e2633e41e9c8c1dddff7cc1122c7d6f28626bd (diff)
downloadsamba-f9156f6c77d9e87edc153b024a1d564b44eedd8f.tar.gz
samba-f9156f6c77d9e87edc153b024a1d564b44eedd8f.tar.bz2
samba-f9156f6c77d9e87edc153b024a1d564b44eedd8f.zip
socket_wrapper: correctly handle connected dgram sockets
metze
-rw-r--r--lib/socket_wrapper/socket_wrapper.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index 1f56a8358e..b2d3a6b15d 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -202,6 +202,7 @@ struct socket_info
int bound;
int bcast;
int is_server;
+ int connected;
char *path;
char *tmp_path;
@@ -1487,6 +1488,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
child_si->protocol = parent_si->protocol;
child_si->bound = 1;
child_si->is_server = 1;
+ child_si->connected = 1;
child_si->peername_len = len;
child_si->peername = sockaddr_dup(my_addr, len);
@@ -1674,7 +1676,14 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
if (ret == 0) {
si->peername_len = addrlen;
si->peername = sockaddr_dup(serv_addr, addrlen);
+ si->connected = 1;
+ }
+
+ if (si->type != SOCK_STREAM) {
+ return ret;
+ }
+ if (ret == 0) {
swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
} else {
@@ -1803,11 +1812,18 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct
socklen_t un_addrlen = sizeof(un_addr);
int ret;
struct socket_info *si = find_socket_info(s);
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
if (!si) {
return real_recvfrom(s, buf, len, flags, from, fromlen);
}
+ if (!from) {
+ from = (struct sockaddr *)&ss;
+ fromlen = &ss_len;
+ }
+
len = MIN(len, 1500);
/* irix 6.4 forgets to null terminate the sun_path string :-( */
@@ -1838,6 +1854,16 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con
return real_sendto(s, buf, len, flags, to, tolen);
}
+ if (si->connected) {
+ if (to) {
+ errno = EISCONN;
+ return -1;
+ }
+
+ to = si->peername;
+ tolen = si->peername_len;
+ }
+
len = MIN(len, 1500);
switch (si->type) {