Am Mittwoch 24 Januar 2007 19:50 schrieb Marcel Holtmann:
> > attached are 3 patches. The Win32 patchset is posted in a seperate mail
> > and depend on the patches below.
>
> sorry for any delay.

No problem. Working with the win32 patchset made 3 more patches practically a 
noop :)

> > soname.patch (essential!):
> >   a one-liner to fix a bug in CVS
>
> This one is in the CVS now.

Great.

> > debug-output.patch (optional):
> >   cleanup and "not-really-optional for win32"
>
> I committed this, too.

Even better :)

> > tcpobex.patch (needs testing):
> >   adds IPv6 support (with transparent IPv4 support)
> >   adds TcpOBEX_* and keeps InOBEX_* (as wrapper) for compatibility
> >   server part usuably as non-root user
>
> I need this split out in logical parts. So first to the needed changes
> internally for the API extension and IPv6 and then provide the
> additional API.

And here you go. I revised the ipv6 patch and tested it (IPv6 connection, 
default) with obex_test (after applying the tcpobex.patch).
Order:
  ipv6.patch
  tcpobex.patch

Server:
socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET6, sin6_port=htons(650), inet_pton(AF_INET6, "::", 
&sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
listen(3, 2)                            = 0
select(4, [3], NULL, NULL, {10, 0})     = 1 (in [3], left {7, 812000})
accept(3, {sa_family=AF_INET6, sin6_port=htons(4372), 
inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 
[28]) = 4
close(3)                                = 0
write(1, "OBEX_HandleInput() returned 1\n", 30OBEX_HandleInput() returned 1
) = 30
select(5, [4], NULL, NULL, {10, 0})     = 1 (in [4], left {9, 996000})
read(4, "\200\0\20", 3)                 = 3
read(4, "\20\0\4\0J\0\tLinux\0", 13)    = 13
write(1, "connect_server()\n", 17connect_server()
)      = 17
write(1, "Weeeha. I\'m talking to the coole"..., 44Weeeha. I'm talking to the 
coolest OS ever!
) = 44
write(4, "\240\0\7\20\0\4\0", 7)        = 7
write(1, "Server request finished!\n", 25Server request finished!
) = 25
write(1, "server_done() Command (00) has n"..., 44server_done() Command (00) 
has now finished
) = 44
write(1, "OBEX_HandleInput() returned 16\n", 31OBEX_HandleInput() returned 16
) = 31
select(5, [4], NULL, NULL, {10, 0})     = 0 (Timeout)

Client:
socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET6, sin6_port=htons(650), 
inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=1}, 
28) = 0
write(3, "\200\0\20\20\0\4\0J\0\tLinux\0", 16) = 16
select(4, [3], NULL, NULL, {10, 0})     = 1 (in [3], left {10, 0})
read(3, "\240\0\7", 3)                  = 3
read(3, "\20\0\4\0", 4)                 = 4
write(1, "Server request finished!\n", 25Server request finished!
) = 25
write(1, "server_done() Command (00) has n"..., 44server_done() Command (00) 
has now finished
) = 44


HS
Index: openobex-anoncvs/lib/inobex.c
===================================================================
--- openobex-anoncvs.orig/lib/inobex.c	2007-01-24 22:20:05.032936777 +0100
+++ openobex-anoncvs/lib/inobex.c	2007-01-24 22:25:12.600158527 +0100
@@ -43,12 +43,52 @@
 #include <netinet/in.h>
 #include <fcntl.h>
 #include <sys/socket.h>
+#include <arpa/inet.h>
 #endif /*_WIN32*/
 
 #include "obex_main.h"
 
 #define OBEX_PORT 650
 
+static
+void map_ip4to6 (struct sockaddr_in* in, struct sockaddr_in6* out)
+{
+	out->sin6_family = AF_INET6;
+	if (in->sin_port == 0)
+		out->sin6_port = htons(OBEX_PORT);
+	else
+		out->sin6_port = in->sin_port;
+	out->sin6_flowinfo = 0;
+
+	/* default, matches IN6ADDR_ANY */
+	memset(out->sin6_addr.s6_addr,0,sizeof(out->sin6_addr.s6_addr));
+	switch (in->sin_addr.s_addr) {
+	case INADDR_ANY:
+		/* does not work, so use IN6ADDR_ANY
+		 * which includes INADDR_ANY
+		 */
+		break;
+	default:
+		/* map the IPv4 address to [::FFFF:<ipv4>]
+		 * see RFC2373 and RFC2553 for details
+		 */
+		out->sin6_addr.s6_addr16[10/2] = 0xFFFF;
+		out->sin6_addr.s6_addr[12] = (in->sin_addr.s_addr >> 24) & 0xFF;
+		out->sin6_addr.s6_addr[13] = (in->sin_addr.s_addr >> 16) & 0xFF;
+		out->sin6_addr.s6_addr[14] = (in->sin_addr.s_addr >>  8) & 0xFF;
+		out->sin6_addr.s6_addr[15] = (in->sin_addr.s_addr >>  0) & 0xFF
+;
+		break;
+	}
+	{
+		unsigned int i = 0;
+		for (; i < 16; ++i) {
+			printf("%02x ",out->sin6_addr.s6_addr[i]);
+		}
+		printf("\n");
+	}
+}
+
 /*
  * Function inobex_prepare_connect (self, service)
  *
@@ -57,10 +97,30 @@
  */
 void inobex_prepare_connect(obex_t *self, struct sockaddr *saddr, int addrlen)
 {
-	memcpy(&self->trans.peer, saddr, addrlen);
-	/* Override to be safe... */
-	self->trans.peer.inet.sin_family = AF_INET;
-	self->trans.peer.inet.sin_port = htons(OBEX_PORT);
+	struct sockaddr_in6 addr = {
+		.sin6_family       = AF_INET6,
+		.sin6_port         = htons(OBEX_PORT),
+#ifdef _WIN32
+		.sin6_addr.s6_addr = IN6ADDR_LOOPBACK_INIT,
+#else
+		.sin6_addr         = IN6ADDR_LOOPBACK_INIT,
+#endif
+		.sin6_flowinfo     = 0
+	};
+	if (saddr == NULL)
+		saddr = (struct sockaddr*)(&addr);
+	else
+		switch (saddr->sa_family){
+		case AF_INET6:
+			break;
+		case AF_INET:
+			map_ip4to6((struct sockaddr_in*)saddr,&addr);
+			/* no break */
+		default:
+			saddr = (struct sockaddr*)(&addr);
+			break;
+	}
+	memcpy(&self->trans.peer.inet6, saddr, sizeof(self->trans.self.inet6));
 }
 
 /*
@@ -69,12 +129,33 @@
  *    Prepare for INET-listen
  *
  */
-void inobex_prepare_listen(obex_t *self)
+void inobex_prepare_listen(obex_t *self, struct sockaddr *saddr, int addrlen)
 {
+	struct sockaddr_in6 addr = {
+		.sin6_family       = AF_INET6,
+		.sin6_port         = htons(OBEX_PORT),
+#ifdef _WIN32
+		.sin6_addr.s6_addr = IN6ADDR_ANY_INIT,
+#else
+		.sin6_addr         = IN6ADDR_ANY_INIT,
+#endif
+		.sin6_flowinfo     = 0
+	};
 	/* Bind local service */
-	self->trans.self.inet.sin_family = AF_INET;
-	self->trans.self.inet.sin_port = htons(OBEX_PORT);
-	self->trans.self.inet.sin_addr.s_addr = INADDR_ANY;
+	if (saddr == NULL)
+		saddr = (struct sockaddr*)(&addr);
+	else
+		switch (saddr->sa_family) {
+		case AF_INET6:
+			break;
+		case AF_INET:
+			map_ip4to6((struct sockaddr_in*)saddr,&addr);
+			/* no break */
+		default:
+			saddr = (struct sockaddr*)(&addr);
+			break;
+		}
+	memcpy(&self->trans.self.inet6, saddr, sizeof(self->trans.self.inet6));
 }
 
 /*
@@ -87,7 +168,7 @@
 {
 	DEBUG(4, "\n");
 
-	self->serverfd = obex_create_socket(self, AF_INET);
+	self->serverfd = obex_create_socket(self, AF_INET6);
 	if(self->serverfd < 0) {
 		DEBUG(0, "Cannot create server-socket\n");
 		return -1;
@@ -95,9 +176,8 @@
 
 	//printf("TCP/IP listen %d %X\n", self->trans.self.inet.sin_port,
 	//       self->trans.self.inet.sin_addr.s_addr);
-	if (bind(self->serverfd, (struct sockaddr*) &self->trans.self.inet,
-		 sizeof(struct sockaddr_in))) 
-	{
+	if (bind(self->serverfd, (struct sockaddr*) &self->trans.self.inet6,
+		 sizeof(struct sockaddr_in6))) {
 		DEBUG(0, "bind() Failed\n");
 		return -1;
 	}
@@ -121,10 +201,11 @@
  */
 int inobex_accept(obex_t *self)
 {
-	socklen_t addrlen = sizeof(struct sockaddr_in);
+	socklen_t addrlen = sizeof(struct sockaddr_in6);
 
-	self->fd = accept(self->serverfd, (struct sockaddr *) 
-		&self->trans.peer.inet, &addrlen);
+	self->fd = accept(self->serverfd,
+			  (struct sockaddr *)&self->trans.peer.inet6,
+			  &addrlen);
 
 	if(self->fd < 0)
 		return -1;
@@ -143,26 +224,30 @@
  */
 int inobex_connect_request(obex_t *self)
 {
-	unsigned char *addr;
+	char addr[INET6_ADDRSTRLEN];
 	int ret;
 
-	self->fd = obex_create_socket(self, AF_INET);
+	self->fd = obex_create_socket(self, AF_INET6);
 	if(self->fd < 0)
 		return -1;
 
 	/* Set these just in case */
-	self->trans.peer.inet.sin_family = AF_INET;
-	if (self->trans.peer.inet.sin_port == 0)
-		self->trans.peer.inet.sin_port = htons(OBEX_PORT);
-
-	addr = (unsigned char *) &self->trans.peer.inet.sin_addr.s_addr;
-
-	DEBUG(2, "peer addr = %d.%d.%d.%d\n",
-		addr[0], addr[1], addr[2], addr[3]);
+	if (self->trans.peer.inet6.sin6_port == 0)
+		self->trans.peer.inet6.sin6_port = htons(OBEX_PORT);
 
+#ifndef _WIN32
+	if (!inet_ntop(AF_INET6,&self->trans.peer.inet6.sin6_addr,
+		       addr,sizeof(addr))) {
+		DEBUG(4, "Adress problem\n");
+		obex_delete_socket(self, self->fd);
+		self->fd = -1;
+		return -1;
+	}
+	DEBUG(2, "peer addr = [%s]:%u\n",addr,ntohs(self->trans.peer.inet6.sin6_port));
+#endif
 
-	ret = connect(self->fd, (struct sockaddr*) &self->trans.peer.inet, 
-		      sizeof(struct sockaddr_in));
+	ret = connect(self->fd, (struct sockaddr*) &self->trans.peer.inet6,
+		      sizeof(struct sockaddr_in6));
 	if (ret < 0) {
 		DEBUG(4, "Connect failed\n");
 		obex_delete_socket(self, self->fd);
Index: openobex-anoncvs/lib/obex_transport.h
===================================================================
--- openobex-anoncvs.orig/lib/obex_transport.h	2007-01-24 22:20:05.180946027 +0100
+++ openobex-anoncvs/lib/obex_transport.h	2007-01-24 22:25:12.608159027 +0100
@@ -32,6 +32,7 @@
 
 #ifdef _WIN32
 #include <winsock2.h>
+#include <ws2tcpip.h>
 #else
 #include <netinet/in.h>
 #endif
@@ -63,7 +64,7 @@
 #ifdef HAVE_IRDA
 	struct sockaddr_irda irda;
 #endif /*HAVE_IRDA*/
-	struct sockaddr_in   inet;
+	struct sockaddr_in6  inet6;
 #ifdef HAVE_BLUETOOTH
 #ifdef HAVE_BLUETOOTH_LINUX
 	struct sockaddr_rc   rfcomm;
Index: openobex-anoncvs/lib/inobex.h
===================================================================
--- openobex-anoncvs.orig/lib/inobex.h	2007-01-24 22:20:05.256950777 +0100
+++ openobex-anoncvs/lib/inobex.h	2007-01-24 22:25:12.628160277 +0100
@@ -31,7 +31,7 @@
 #define INOBEX_H
 
 void inobex_prepare_connect(obex_t *self, struct sockaddr *saddr, int addrlen);
-void inobex_prepare_listen(obex_t *self);
+void inobex_prepare_listen(obex_t *self, struct sockaddr *saddr, int addrlen);
 int inobex_listen(obex_t *self);
 int inobex_accept(obex_t *self);
 int inobex_connect_request(obex_t *self);
Index: openobex-anoncvs/lib/obex.c
===================================================================
--- openobex-anoncvs.orig/lib/obex.c	2007-01-24 22:25:37.429710277 +0100
+++ openobex-anoncvs/lib/obex.c	2007-01-24 22:26:03.455336777 +0100
@@ -954,7 +954,7 @@
 
 	obex_return_val_if_fail(self != NULL, -1);
 
-	inobex_prepare_listen(self);
+	inobex_prepare_listen(self,NULL,0);
 	return obex_transport_listen(self);
 }
 
Index: openobex-anoncvs/lib/obex.c
===================================================================
--- openobex-anoncvs.orig/lib/obex.c	2007-01-24 22:14:14.159008527 +0100
+++ openobex-anoncvs/lib/obex.c	2007-01-24 22:18:31.599097527 +0100
@@ -941,47 +941,100 @@
 }
 
 /**
- * InOBEX_ServerRegister - Start listening for incoming connections
+ * TcpOBEX_ServerRegister - Start listening for incoming TCP connections
  * @self: OBEX handle
+ * @addr: Address to bind to (*:650 if NULL)
+ * @addrlen: Length of address structure
  *
- * An easier server function to use for TCP/IP (InOBEX) only.
+ * An easier server function to use for TCP/IP (TcpOBEX) only.
+ * It supports IPv4 (AF_INET) and IPv6 (AF_INET6).
  *
  * Returns -1 on error.
  */
-int InOBEX_ServerRegister(obex_t *self)
+int TcpOBEX_ServerRegister(obex_t* self, struct sockaddr *addr, int addrlen)
 {
 	DEBUG(3, "\n");
 
+	errno = EINVAL;
 	obex_return_val_if_fail(self != NULL, -1);
 
-	inobex_prepare_listen(self,NULL,0);
+	inobex_prepare_listen(self,addr,addrlen);
 	return obex_transport_listen(self);
 }
 
 /**
- * InOBEX_TransportConnect - Connect Inet transport
+ * TcpOBEX_TransportConnect - Connect TCP transport
  * @self: OBEX handle
+ * @addr: Address to connect to (localhost:650 if NULL)
+ * @addrlen: Length of address structure
+ *
+ * An easier connect function to use for TCP/IP (TcpOBEX) only.
+ * It supports IPv4 (AF_INET) and IPv6 (AF_INET6).
+ *
+ * Returns -1 on error.
+ */
+int TcpOBEX_TransportConnect(obex_t *self, struct sockaddr *addr, int addrlen)
+{
+     	DEBUG(4, "\n");
+
+	errno = EINVAL;
+	obex_return_val_if_fail(self != NULL, -1);
+
+	if (self->object)	{
+		DEBUG(1, "We are busy.\n");
+		errno = EBUSY;
+		return -1;
+	}
+
+	inobex_prepare_connect(self, addr, addrlen);
+	return obex_transport_connect_request(self);
+}
+/**
+ * InOBEX_ServerRegister - Start listening for incoming connections
+ * @self: OBEX handle
+ *
+ * An easier server function to use for TCP/IP (InOBEX) only.
+ *
+ * This function is deprecated, use TcpOBEX_ServerRegister() instead.
+ *
+ * Returns -1 on error.
+ */
+int InOBEX_ServerRegister(obex_t *self)
+{
+	DEBUG(3, "\n");
+
+	return TcpOBEX_ServerRegister(self,NULL,0);
+}
+
+/**
+ * InOBEX_TransportConnect - Connect Inet transport (deprecated)
+ * @self: OBEX handle
+ * @saddr: Address to connect to
+ * @addrlen: Length of address
  *
  * An easier connect function to use for TCP/IP (InOBEX) only.
  *
- * Note : I would like feedback on this API to know which input
- * parameter make most sense. Thanks...
+ * This function is deprecated, use TcpOBEX_TransportConnect() instead.
+ *
+ * Returns -1 on error.
  */
 int InOBEX_TransportConnect(obex_t *self, struct sockaddr *saddr, int addrlen)
 {
      	DEBUG(4, "\n");
 
+	errno = EINVAL;
 	obex_return_val_if_fail(self != NULL, -1);
 
 	if (self->object)	{
 		DEBUG(1, "We are busy.\n");
-		return -EBUSY;
+		errno = EBUSY;
+		return -1;
 	}
 
+	errno = EINVAL;
 	obex_return_val_if_fail(saddr != NULL, -1);
 
-	inobex_prepare_connect(self, saddr, addrlen);
-	return obex_transport_connect_request(self);
+	return TcpOBEX_TransportConnect(self,saddr,addrlen);
 }
 
 /**
Index: openobex-anoncvs/include/obex.h
===================================================================
--- openobex-anoncvs.orig/include/obex.h	2007-01-24 22:14:14.343020027 +0100
+++ openobex-anoncvs/include/obex.h	2007-01-24 22:16:52.108879777 +0100
@@ -116,7 +116,13 @@
 char* OBEX_GetResponseMessage(obex_t *self, int rsp);
 
 /*
- * InOBEX API (TCP/IP)
+ * TcpOBEX API (IPv4/IPv6)
+ */
+ int TcpOBEX_ServerRegister(obex_t* self, struct sockaddr *addr, int addrlen);
+ int TcpOBEX_TransportConnect(obex_t *self, struct sockaddr *addr, int addrlen);
+
+/*
+ * InOBEX API (deprecated)
  */
  int InOBEX_ServerRegister(obex_t *self);
  int InOBEX_TransportConnect(obex_t *self, struct sockaddr *saddr, int addrlen);
Index: openobex-anoncvs/lib/obex.sym
===================================================================
--- openobex-anoncvs.orig/lib/obex.sym	2007-01-24 22:14:14.295017027 +0100
+++ openobex-anoncvs/lib/obex.sym	2007-01-24 22:16:22.103004527 +0100
@@ -33,6 +33,8 @@
 OBEX_CharToUnicode
 OBEX_ResponseToString
 OBEX_GetResponseMessage
+TcpOBEX_ServerRegister
+TcpOBEX_TransportConnect
 InOBEX_ServerRegister
 InOBEX_TransportConnect
 IrOBEX_ServerRegister
Index: openobex-anoncvs/apps/obex_test.c
===================================================================
--- openobex-anoncvs.orig/apps/obex_test.c	2007-01-24 22:14:14.395023277 +0100
+++ openobex-anoncvs/apps/obex_test.c	2007-01-24 22:16:22.171008777 +0100
@@ -359,7 +359,7 @@
 			case 'c':
 				/* First connect transport */
 				if(tcpobex) {
-					if(inet_connect(handle) < 0) {
+					if(TcpOBEX_TransportConnect(handle,NULL,0) < 0) {
 						printf("Transport connect error! (TCP)\n");
 						break;
 					}
@@ -405,7 +405,7 @@
 			case 's':
 				/* First register server */
 				if(tcpobex) {
-					if(InOBEX_ServerRegister(handle) < 0) {
+					if(TcpOBEX_ServerRegister(handle,NULL,0) < 0) {
 						printf("Server register error! (TCP)\n");
 						break;
 					}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Openobex-users mailing list
[email protected]
http://lists.sourceforge.net/lists/listinfo/openobex-users

Reply via email to