Author: ArcRiley
Date: 2009-01-30 23:23:14 -0500 (Fri, 30 Jan 2009)
New Revision: 1509

Modified:
   trunk/concordance/src/sockets/Client.c
   trunk/concordance/src/sockets/Socket.c
Log:
work in progress


Modified: trunk/concordance/src/sockets/Client.c
===================================================================
--- trunk/concordance/src/sockets/Client.c      2009-01-26 20:31:29 UTC (rev 
1508)
+++ trunk/concordance/src/sockets/Client.c      2009-01-31 04:23:14 UTC (rev 
1509)
@@ -33,7 +33,28 @@
 
     /* first inherit base type */
     self = (socketsClient_Object*) socketsSocket_new(type, args, kwds);
+    if (!self)
+      return NULL;
 
+    /* set default for client port
+
+       xmpp-client     5222/tcp                        # XMPP Client Connection
+
+       XEP-0035 (SSL/TLS Integration) :
+         Traditionally, Jabber servers has supported TLS by utilising a
+         "wrapper" around the standard protocol stream. This wrapper usually
+         listens on a port other than those listed in the IANA registry
+         (commonly 5223 for client-to-server communications and 5270 for
+         server-to-server communications). In the case of client-to-server
+         communications, clients must initiate a TLS session immediately after
+         connecting, before beginning the normal XML stream. This method of
+         utilising TLS is typical of many servers that implement stream-based
+         protocols, but has a number of flaws, which are outlined in section 7
+         of RFC 2595. Accordingly, the use of port 5223 and port 5270 for
+         secure sessions is deprecated.
+    */
+    self->port = 5222;
+
     /* return self */
     return (PyObject*) self;
   }

Modified: trunk/concordance/src/sockets/Socket.c
===================================================================
--- trunk/concordance/src/sockets/Socket.c      2009-01-26 20:31:29 UTC (rev 
1508)
+++ trunk/concordance/src/sockets/Socket.c      2009-01-31 04:23:14 UTC (rev 
1509)
@@ -33,8 +33,16 @@
   
     /* first inherit base type */
     self = (socketsSocket_Object*) PyType_GenericNew(type, args, kwds);
+    if (!self)
+      return NULL;
 
-    /* start with closed socket */
+    /* set addr, port, and sock to default values
+    
+       0.0.0.0 = listen to every available interface
+       port is overridden by child class
+    */
+    self->addr = "0.0.0.0";
+    self->port =  0;
     self->sock = -1;
 
     /* Get a reference to our local module
@@ -68,8 +76,149 @@
   socketsSocket_init(PyObject* s, PyObject* args, PyObject* kwds) {       /*\
     cdef :                                                                \*/
       socketsSocket_Object*      self = (socketsSocket_Object*) s;
-    
-    return 0;
+      int                        ret;
+      struct addrinfo*           resinfo = NULL;
+
+    /* parse arguments and keywords
+
+       From http://docs.python.org/3.0/c-api/arg.html :
+         |  Indicates that the remaining arguments in the Python argument list
+            are optional. The C variables corresponding to optional arguments
+            should be initialized to their default value — when an optional
+            argument is not specified, PyArg_ParseTuple does not touch the
+            contents of the corresponding C variable(s).
+         s  Convert a Python string or Unicode object to a C pointer to a
+            character string. You must not provide storage for the string
+            itself; a pointer to an existing string is stored into the
+            character pointer variable whose address you pass. The C string is
+            NUL-terminated. The Python string must not contain embedded NUL
+            bytes; if it does, a TypeError exception is raised. Unicode
+            objects are converted to C strings using the default encoding. If
+            this conversion fails, a UnicodeError is raised.
+         H  Convert a Python integer to a C unsigned short int, without
+            overflow checking.
+         :  The list of format units ends here; the string after the colon is
+            used as the function name in error messages (the “associated
+            value” of the exception that PyArg_ParseTuple raises).
+    */
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sH:Socket", kwlist,
+                                     &self->addr, &self->port))
+      return -1;
+
+    if (self->port == 0) {
+      PyErr_SetString(PyExc_AttributeError, "invalid port");
+      return -1;
+    }
+
+    /* Get address family and struct
+
+       int getaddrinfo(const char *node, const char *service,
+                       const struct addrinfo *hints,
+                       struct addrinfo **res);
+       getaddrinfo() returns  0  if it succeeds, or non-zero on failure.
+    */
+    ret = getaddrinfo(self->addr, NULL, NULL, &resinfo);
+    if (ret != 0) {
+      switch (ret) {
+        case EAI_AGAIN : {
+          /* EAI_AGAIN
+              The  name  server  returned a temporary failure indication.
+              Try again later. */
+          PyErr_SetString(PyExc_OSError, "temporary dns failure");
+          break;
+        }
+        case EAI_FAIL : {
+          /* EAI_FAIL
+              The name server returned a permanent failure indication. */
+          PyErr_SetString(PyExc_OSError, "permanent dns failure");
+          break;
+        }
+        case EAI_FAMILY : {
+          /* EAI_FAMILY
+              The requested address family is not supported. */
+          PyErr_SetString(PyExc_OSError, "address family not supported");
+          break;
+        }
+        case EAI_MEMORY : {
+          /* EAI_MEMORY
+              Out of memory. */
+          PyErr_SetString(PyExc_MemoryError, "out of memory on getaddrinfo");
+          break;
+        }
+        case EAI_NODATA : {
+          /* EAI_NODATA
+              The specified network host exists, but does not have any
+              network addresses defined. */
+          PyErr_SetString(PyExc_AttributeError, "host lacks IP address");
+          break;
+        }
+        default : {
+          PyErr_SetString(PyExc_AttributeError, "invalid address/hostname");
+          break;
+        }
+      }
+      return -1;
+    }
+
+    /* Copy port into sockaddr struct
+
+       uint16_t htons(uint16_t hostshort);
+         The htons() function converts the unsigned short integer hostshort
+         from host byte order to network byte order.
+    */
+    ((struct sockaddr_in*) resinfo->ai_addr)->sin_port = htons(self->port);
+
+    /* Open new socket of the appropriate family (AF_INET or AF_INET6)
+
+       int socket(int domain, int type, int protocol);
+    */
+    self->sock = socket(resinfo->ai_family, SOCK_STREAM, 0);
+
+    /* If successful continue to bind/listen, else set error message */
+    if (self->sock > -1) {
+      /* Bind and Listen to opened socket
+
+         int bind(int fd, const struct sockaddr *addr,
+                  socklen_t addrlen);
+           On success, zero is returned.  On error, -1 is returned.
+
+         int listen(int fd, int backlog);
+           On  success,  zero is returned.  On error, -1 is returned.
+      */
+      if (bind(self->sock, resinfo->ai_addr, resinfo->ai_addrlen) == 0 &&
+          listen(self->sock, 16) == 0 ) {
+
+        /* create channel and add it to our context watchlist
+
+           GIOChannel*  concordAddSocket         (gint fd,
+                                                  GIOCondition condition,
+                                                  GSourceFunc callback,
+                                                  gpointer data,
+                                                  GMainContext* context);
+        */
+        self->chan = concordAddSocket(self->sock, G_IO_IN,
+                                      (GSourceFunc) concordCore_listenNew,
+                                      (gpointer) self, self->context);
+        ret = 0;
+      }
+      else {
+        PyErr_SetString(PyExc_OSError, "unable to bind listening socket");
+        ret = -1;
+      }
+    }
+    else {
+      PyErr_SetString(PyExc_OSError, "unable to bind listening socket");
+      ret = -1;
+    }
+
+    /* before returning, free the previously created resinfo struct
+
+       void freeaddrinfo(struct addrinfo *res);
+    */
+    if (resinfo)
+      freeaddrinfo(resinfo);
+
+    return ret;
   }
 
 

_______________________________________________
PySoy-SVN mailing list
PySoy-SVN@pysoy.org
http://www.pysoy.org/mailman/listinfo/pysoy-svn

Reply via email to