unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Initial SCTP support for the upcoming 1.6.5 release
@ 2004-08-10 18:26 Michael Tuexen
  2004-08-11 12:29 ` Michael Tuexen
  0 siblings, 1 reply; 25+ messages in thread
From: Michael Tuexen @ 2004-08-10 18:26 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 1565 bytes --]

Dear all,

it would be very helpful for me (and some others) if the 1.6.5 release
could have some support for SCTP.

To see what kind of change this requires I'm appending the diff files
for libguile/socket.[ch].

What are the changes (for socket.h)?

- add to prototypes for sctp-recvmsg and sctp-sendmsg.
   These changes are #ifdefed.

What are the changes (for socket.c)?

- include <netinet/sctp.h> if available. #ifdefed.
- add two line of code to initialize socket structures to zero.
   (If you do not like these two changes, take them out. They helped
    for some SCTP implementations not doing this in the kernel. At
    least one of them is fixed now).
- add sctp-recvmsg and sctp-sendmsg wrapper functions. These are 
#ifdefed.
- add some constants, if they are available. #ifdefed.

What is still missing (configure.in)?

- A check for the existence of netinet/sctp.h. If yes, define 
HAVE_NETINET_SCTP_H
- A check if sctp_sendmsg is contained in libsctp. If yes, define 
HAVE_SCTP_SENDMSG
   an add libsctp to the list of libraries to be used.
- A check if sctp_recvmsg is contained in libsctp. If yes, define 
HAVE_SCTP_RECVMSG
   an add libsctp to the list of libraries to be used.

(libsctp is located on some platforms in /usr/lib, /usr/local/lib and 
/usr/local/v6/lib)
This can be done by adding some lines to configure.in.

I will test the configure.in changes and send a patch for configure.in 
later
this week.

Please let me know if these patches can be included in the upcoming 
1.6.5 release.

Thank you very much.

Best regards
Michael


[-- Attachment #2: socket.c.diff --]
[-- Type: application/octet-stream, Size: 7735 bytes --]

--- guile-core-20040808/libguile/socket.c	Fri Mar 15 10:23:19 2002
+++ guile-core-mod/libguile/socket.c	Tue Aug 10 20:23:56 2004
@@ -71,6 +71,9 @@
 #include <netinet/in.h>
 #include <netdb.h>
 #include <arpa/inet.h>
+#ifdef HAVE_NETINET_SCTP_H
+#include <netinet/sctp.h>
+#endif
 #endif
 
 #if defined (HAVE_UNIX_DOMAIN_SOCKETS) && !defined (SUN_LEN)
@@ -706,6 +709,7 @@
 	  scm_memory_error (proc);
 	/* 4.4BSD-style interface includes sin_len member and defines SIN_LEN,
 	   4.3BSD  does not.  */
+	memset((void *)soka, 0, sizeof(struct sockaddr_in));
 #ifdef SIN_LEN
 	soka->sin_len = sizeof (struct sockaddr_in);
 #endif
@@ -742,6 +746,7 @@
 	soka = (struct sockaddr_in6 *) malloc (sizeof (struct sockaddr_in6));
 	if (!soka)
 	  scm_memory_error (proc);
+	memset((void *)soka, 0, sizeof(struct sockaddr_in6));
 #ifdef SIN_LEN6
 	soka->sin6_len = sizeof (struct sockaddr_in6);
 #endif
@@ -1202,6 +1207,72 @@
 }
 #undef FUNC_NAME
 
+#ifdef HAVE_SCTP_RECVMSG
+
+SCM_DEFINE (scm_sctp_recvmsg, "sctp-recvmsg!", 2, 2, 0,
+            (SCM sock, SCM str, SCM start, SCM end),
+	    "Return data from the socket port @var{sock} and also\n"
+	    "information about where the data was received from.\n"
+	    "@var{sock} must already be bound to the address from which\n"
+	    "data is to be received.  @code{str}, is a string into which the\n"
+	    "data will be written.  The size of @var{str} limits the amount\n"
+	    "of data which can be received: in the case of packet protocols,\n"
+	    "if a packet larger than this limit is encountered then some\n"
+	    "data will be irrevocably lost.\n\n"
+	    "The value returned is a list containing:\n"
+	    "- the number of bytes read from the socket\n"
+	    "- an address object in the same form as returned by @code{accept}\n"
+	    "- the flags returned by the sctp_recvmsg call\n"
+	    "- a list containing the SID, SSN, PPID, TSN and CUM_TSN\n"
+	    "The @var{start} and @var{end} arguments specify a substring of\n"
+	    "@var{str} to which the data should be written.\n\n"
+	    "Note that the data is read directly from the socket file\n"
+	    "descriptor: any unread buffered port data is ignored.")
+#define FUNC_NAME s_scm_sctp_recvmsg
+{
+  int rv;
+  int fd;
+  int flg;
+  char *buf;
+  int offset;
+  int cend;
+  SCM address, s_sinfo;
+  int addr_size = MAX_ADDR_SIZE;
+  char max_addr[MAX_ADDR_SIZE];
+  struct sockaddr *addr = (struct sockaddr *) max_addr;
+  struct sctp_sndrcvinfo sinfo;
+  
+  SCM_VALIDATE_OPFPORT (1, sock);
+  fd = SCM_FPORT_FDES (sock);
+  SCM_VALIDATE_SUBSTRING_SPEC_COPY (2, str, buf, 3, start, offset,
+				    4, end, cend);
+
+  addr->sa_family = AF_UNSPEC;
+  flg = 0;
+  SCM_SYSCALL (rv = sctp_recvmsg (fd, buf + offset,
+			          cend - offset,
+			          addr, &addr_size,
+			          &sinfo,
+			          &flg));
+  if (rv == -1)
+    SCM_SYSERROR;
+  if (addr->sa_family != AF_UNSPEC)
+    address = scm_addr_vector (addr, FUNC_NAME);
+  else
+    address = SCM_BOOL_F;
+
+  s_sinfo = scm_list_5(scm_ushort2num(sinfo.sinfo_stream),
+                       scm_ushort2num(sinfo.sinfo_ssn),
+                       scm_uint2num(ntohl(sinfo.sinfo_ppid)),
+                       scm_uint2num(sinfo.sinfo_tsn),
+                       scm_uint2num(sinfo.sinfo_cumtsn));
+                       
+  return scm_list_4 (SCM_MAKINUM (rv), address, SCM_MAKINUM (flg), s_sinfo); 
+}
+#undef FUNC_NAME
+
+#endif
+
 SCM_DEFINE (scm_sendto, "sendto", 4, 0, 1,
             (SCM sock, SCM message, SCM fam, SCM address, SCM args_and_flags),
 	    "Transmit the string @var{message} on the socket port\n"
@@ -1257,7 +1328,70 @@
   return SCM_MAKINUM (rv);
 }
 #undef FUNC_NAME
-\f
+
+#ifdef HAVE_SCTP_SENDMSG
+\fSCM_DEFINE (scm_sctp_sendmsg, "sctp-sendmsg", 8, 0, 1,
+            (SCM sock, SCM message, SCM ppid, SCM stream_no, SCM ttl, SCM context, SCM fam, SCM address, SCM args_and_flags),
+	    "Transmit the string @var{message} on the socket port\n"
+	    "@var{sock}.  The\n"
+	    "parameters @var{ppid}, @var{stream_no}, @var{ttl} and  @var{context}\n"
+	    "are the corresponding SCTP parameters. The\n"
+	    "destination address is specified using the @var{fam},\n"
+	    "@var{address} and\n"
+	    "@var{args_and_flags} arguments, in a similar way to the\n"
+	    "@code{connect} procedure.  @var{args_and_flags} contains\n"
+	    "the usual connection arguments optionally followed by\n"
+	    "a flags argument, which is a value or\n"
+	    "bitwise OR of MSG_UNORDERED, MSG_ABORT, MSG_EOF etc.\n\n"
+	    "The value returned is the number of bytes transmitted\n"
+	    "Note that the data is written directly to the socket\n"
+	    "file descriptor:\n"
+	    "any unflushed buffered port data is ignored.")
+#define FUNC_NAME s_scm_sctp_sendmsg
+{
+  int rv;
+  int fd;
+  int flg;
+  struct sockaddr *soka;
+  int size;
+  uint16_t c_stream_no;
+  uint32_t c_ppid, c_ttl, c_context;
+
+  sock = SCM_COERCE_OUTPORT (sock);
+  SCM_VALIDATE_FPORT (1, sock);
+  SCM_VALIDATE_STRING (2, message);
+  c_ppid      = htonl(SCM_NUM2ULONG(3, ppid));
+  c_stream_no = SCM_NUM2USHORT(4, stream_no);
+  c_ttl       = SCM_NUM2ULONG(5, ttl);
+  c_context   = SCM_NUM2ULONG(6, context);
+  SCM_VALIDATE_INUM (7, fam);
+  fd = SCM_FPORT_FDES (sock);
+  soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args_and_flags, 8, FUNC_NAME, &size);
+  if (SCM_NULLP (args_and_flags))
+    flg = 0;
+  else {
+      SCM_VALIDATE_CONS (9,args_and_flags);
+      flg = SCM_NUM2ULONG (9, SCM_CAR (args_and_flags));
+    }
+
+  SCM_SYSCALL (rv = sctp_sendmsg (fd,  SCM_STRING_CHARS (message), SCM_STRING_LENGTH (message),
+			          soka, size,
+				  c_ppid,
+				  flg,
+				  c_stream_no,
+				  c_ttl,
+				  c_context));
+  if (rv == -1) {
+      int save_errno = errno;
+      free (soka);
+      errno = save_errno;
+      SCM_SYSERROR;
+  }
+  free (soka);
+  return SCM_MAKINUM (rv);
+}
+#undef FUNC_NAME
+\f#endif
 
 
 void
@@ -1311,10 +1445,26 @@
 #ifdef SOCK_DGRAM
   scm_c_define ("SOCK_DGRAM", SCM_MAKINUM (SOCK_DGRAM));
 #endif
+#ifdef SOCK_SEQPACKET
+  scm_c_define ("SOCK_SEQPACKET", SCM_MAKINUM (SOCK_SEQPACKET));
+#endif
 #ifdef SOCK_RAW
   scm_c_define ("SOCK_RAW", SCM_MAKINUM (SOCK_RAW));
 #endif
 
+  /* protocol numbers */
+#ifdef IPPROTO_SCTP
+  scm_c_define ("IPPROTO_SCTP", SCM_MAKINUM (IPPROTO_SCTP));
+#endif
+
+#ifdef IPPROTO_TCP
+  scm_c_define ("IPPROTO_TCP", SCM_MAKINUM (IPPROTO_TCP));
+#endif
+
+#ifdef IPPROTO_UDP
+  scm_c_define ("IPPROTO_UDP", SCM_MAKINUM (IPPROTO_UDP));
+#endif
+
   /* setsockopt level.  */
 #ifdef SOL_SOCKET
   scm_c_define ("SOL_SOCKET", SCM_MAKINUM (SOL_SOCKET));
@@ -1382,6 +1532,30 @@
 #endif
 #ifdef MSG_DONTROUTE
   scm_c_define ("MSG_DONTROUTE", SCM_MAKINUM (MSG_DONTROUTE));
+#endif
+#ifdef MSG_UNORDERED
+  scm_c_define ("MSG_UNORDERED", SCM_MAKINUM (MSG_UNORDERED));
+#endif
+#ifdef MSG_ADDR_OVER
+  scm_c_define ("MSG_ADDR_OVER", SCM_MAKINUM (MSG_ADDR_OVER));
+#endif
+#ifdef MSG_ABORT
+  scm_c_define("MSG_ABORT", SCM_MAKINUM (MSG_ABORT));
+#endif
+#ifdef MSG_EOF
+  scm_c_define ("MSG_EOF", SCM_MAKINUM (MSG_EOF));
+#endif
+#ifdef MSG_EOR
+  scm_c_define ("MSG_EOR", SCM_MAKINUM (MSG_EOR));
+#endif
+#ifdef MSG_NOTIFICATION
+  scm_c_define ("MSG_NOTIFICATION", SCM_MAKINUM (MSG_NOTIFICATION));
+#endif
+#ifdef MSG_PR_SCTP_TTL
+  scm_c_define ("MSG_PR_SCTP_TTL", SCM_MAKINUM (MSG_PR_SCTP_TTL));
+#endif
+#ifdef MSG_PR_SCTP_BUF
+  scm_c_define ("MSG_PR_SCTP_BUF", SCM_MAKINUM (MSG_PR_SCTP_BUF));
 #endif
 
   scm_add_feature ("socket");

[-- Attachment #3: socket.h.diff --]
[-- Type: application/octet-stream, Size: 819 bytes --]

--- guile-core-20040808/libguile/socket.h	Sun Apr 22 18:05:21 2001
+++ guile-core-mod/libguile/socket.h	Tue Aug 10 19:28:49 2004
@@ -74,7 +74,13 @@
 extern SCM scm_recv (SCM sockfd, SCM buff_or_size, SCM flags);
 extern SCM scm_send (SCM sockfd, SCM message, SCM flags);
 extern SCM scm_recvfrom (SCM sockfd, SCM buff_or_size, SCM flags, SCM offset, SCM length);
+#ifdef HAVE_SCTP_RECVMSG
+extern SCM scm_sctp_recvmsg (SCM sockfd, SCM buff_or_size, SCM offset, SCM length);
+#endif
 extern SCM scm_sendto (SCM sockfd, SCM message, SCM fam, SCM address, SCM args_and_flags);
+#ifdef HAVE_SCTP_SENDMSG
+extern SCM scm_sctp_sendmsg (SCM sockfd, SCM message, SCM ppid, SCM stream_no, SCM ttl, SCM context, SCM fam, SCM address, SCM args_and_flags);
+#endif
 extern void scm_init_socket (void);
 
 #endif  /* SCM_SOCKETH */

[-- Attachment #4: Type: text/plain, Size: 1 bytes --]



[-- Attachment #5: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2004-09-08 15:34 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-10 18:26 Initial SCTP support for the upcoming 1.6.5 release Michael Tuexen
2004-08-11 12:29 ` Michael Tuexen
2004-08-13 13:40   ` Marius Vollmer
2004-08-13 20:27     ` Michael Tuexen
2004-08-24 14:15       ` Marius Vollmer
2004-08-24 17:35         ` Michael Tuexen
2004-09-08 15:03           ` Marius Vollmer
2004-09-08 15:34             ` Michael Tuexen
2004-08-14  9:59     ` Michael Tuexen
2004-08-16  0:40       ` Kevin Ryde
2004-08-16 10:42         ` Michael Tuexen
2004-08-17 23:46           ` Kevin Ryde
2004-08-19 18:34             ` Michael Tuexen
2004-08-20  1:13               ` Kevin Ryde
2004-08-20  7:57                 ` Michael Tuexen
2004-08-16 17:02       ` Michael Tuexen
2004-08-16 18:44         ` Rob Browning
2004-08-20 18:18           ` Michael Tuexen
2004-08-23  0:58             ` Kevin Ryde
2004-08-23 19:54               ` Michael Tuexen
2004-08-24  0:57                 ` Kevin Ryde
2004-08-24 11:27                   ` Michael Tuexen
2004-08-24 12:46                     ` Michael Tuexen
2004-08-24 14:24                       ` Marius Vollmer
2004-08-24 18:22                         ` Michael Tuexen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).