Пример #1
0
EIF_INTEGER en_socket_datagram_rcv_from (EIF_INTEGER fd, EIF_INTEGER fd1, EIF_INTEGER *a_last_fd, EIF_POINTER buf, EIF_INTEGER len, EIF_INTEGER flags, EIF_INTEGER timeout, SOCKETADDRESS *him) {

	int nsockets = 0;
	int fduse = 0;
	int result;
	int lenn = sizeof(SOCKETADDRESS);
	int ipv6_supported = en_ipv6_available();

	if (fd > 0) {
		nsockets++;
	}
	if (fd1 > 0) {
		nsockets++;
	}
    	if (nsockets == 2) { /* need to choose one of them */
		int ret, t = (timeout == 0) ? -1: timeout;
		ret = net_timeout2 (fd, fd1, t, &fduse);
		if (ret == 2) {
			fduse = check_last_fd (a_last_fd, fd, fd1);
		} else if (ret == 0) {
			if (ret == 0) {
				eraise("Receive timed out", EN_PROG);
			} else {
				eraise("Receive error", EN_PROG);
			}
			return -1;
		}

	} else if (!ipv6_supported) {
		fduse = fd;
	} else if (fd >= 0) {
		/* ipv6 supported: and this socket bound to an IPV6 only address */
		fduse = fd1;
	} else {
		/* ipv6 supported: and this socket bound to an IPV4 only address */
		fduse = fd;
	}

	if (timeout && nsockets == 1) {
		int ret;
		ret = net_timeout(fduse, timeout);
		if (ret <= 0) {
			if (ret == 0) {
				eraise("Receive timed out", EN_PROG);
			} else {
				eraise("Receive error", EN_PROG);
			}
			return -1;
		}
	}

	result = recvfrom ((SOCKET) fduse, (char *) buf, (int) len, (int) flags, (struct sockaddr *) him, &lenn);
	eif_net_check (result);
	
	return (EIF_INTEGER) result;
}
Пример #2
0
/*
 * send a message
 * return non-zero if message not sent successful with completed
 * queue info for status and transport
 */
int ebxml_send (XML*xml, QUEUEROW *r, MIME *msg)
{
  DBUF *b;
  NETCON *conn;
  char host[MAX_PATH];	/* need buffers for redirect		*/
  char path[MAX_PATH];
  int port, route, timeout, delay, retry;
  SSL_CTX *ctx;
  char *rname, 		/* route name				*/
       *content, 	/* message content			*/
       buf[MAX_PATH];

  /* format up the message					*/
  if ((content = mime_format (msg)) == NULL)
  {
    queue_field_set (r, "PROCESSINGSTATUS", "done");
    queue_field_set (r, "TRANSPORTSTATUS", "failed");
    queue_field_set (r, "TRANSPORTERRORCODE", "failed formatting message");
    return (-1);
  }
  debug ("Send content:\n%s\n", content);

  /*
   * get connection info from the record route
   */
  if ((route = 
    cfg_route_index (xml, queue_field_get (r, "ROUTEINFO"))) < 0)
  {
    queue_field_set (r, "PROCESSINGSTATUS", "done");
    queue_field_set (r, "TRANSPORTSTATUS", "failed");
    queue_field_set (r, "TRANSPORTERRORCODE", "bad route");
    return (-1);
  }
  rname = cfg_route (xml, route, "Name");
  ctx = ebxml_route_ctx (xml, route);
  strcpy (host, cfg_route (xml, route, "Host"));
  port = atoi (cfg_route (xml, route, "Port"));
  if ((retry = atoi (cfg_route (xml, route, "Retry"))) == 0)
    retry = cfg_retries (xml);
  timeout = atoi (cfg_route (xml, route, "Timeout"));
  delay = cfg_delay (xml);
  strcpy (path, cfg_route (xml, route, "Path"));

sendmsg:

  info ("Sending ebXML %s:%d to %s\n", 
    r->queue->name, r->rowid, rname);
  debug ("opening connection socket on port=%d retrys=%d timeout=%d\n", 
    port, retry, timeout);
  if ((conn = net_open (host, port, 0, ctx)) == NULL)
  {
    error ("failed opening connection to %s:%d\n", host, port);
    goto retrysend;
  }
  				/* set read timeout if given	*/
  if (timeout)
  {
    net_timeout (conn, timeout * 1000);
    timeout <<= 1;		/* bump each try		*/
  }
  delay = 0;			/* connection OK, don't delay	*/
  queue_field_set (r, "MESSAGESENTTIME", ptime (NULL, buf));
  sprintf (buf, "POST %s HTTP/1.1\r\n", path);
  // ch = ebxml_beautify (ch);
  				/* all set... send the message	*/
  debug ("sending message...\n");
  net_write (conn, buf, strlen (buf));
  net_write (conn, content, strlen (content));
  debug ("reading response...\n");
  b = ebxml_receive (conn);
  debug ("closing socket...\n");
  net_close (conn);
  				/* no reply?			*/
  if (b == NULL)
  {
    warn ("Send response timed out or closed for %s\n", rname);

retrysend:			/* retry with a wait, or..	*/	
			
    if (retry-- && phineas_running ())
    {
      if (delay)
      {
	info ("Retrying send to %s in %d seconds\n", rname, delay);
        sleep (delay * 1000);
	delay <<= 1;
      }
      else			/* reset connection delay	*/
        delay = cfg_delay (xml);
      goto sendmsg;
    }
    if (ctx != NULL)		/* give up!			*/
      SSL_CTX_free (ctx);
    free (content);
    queue_field_set (r, "PROCESSINGSTATUS", "done");
    queue_field_set (r, "TRANSPORTSTATUS", "failed");
    queue_field_set (r, "TRANSPORTERRORCODE", "retries exhausted");
    return (-1);
  }
  debug ("reply was %d bytes\n%.*s\n", dbuf_size (b),
    dbuf_size (b), dbuf_getbuf (b));

  /*
   * handle redirects...
   * note this assumes the same SSL context should be used
   */
  if (ebxml_redirect (dbuf_getbuf (b), host, &port, path))
  {
    dbuf_free (b);
    goto sendmsg;
  }

  if (ctx != NULL)
    SSL_CTX_free (ctx);
  if (ebxml_parse_reply (dbuf_getbuf (b), r))
  {
    queue_field_set (r, "PROCESSINGSTATUS", "done");
    queue_field_set (r, "TRANSPORTSTATUS", "failed");
    queue_field_set (r, "TRANSPORTERRORCODE", "garbled reply");
  }
  debug ("send completed\n");
  dbuf_free (b);
  free (content);
  return (0);
}
Пример #3
0
EIF_INTEGER en_socket_stream_accept (EIF_INTEGER fd, EIF_INTEGER fd1, EIF_INTEGER *a_last_fd, SOCKETADDRESS *him, EIF_INTEGER timeout) {
	int len;
	SOCKET accepted;

	EIF_NET_INITIALIZE;

	if (fd != -1 && fd1 != -1) {
		fd_set rfds;
		struct timeval t, *tP=&t;
		int res, fd2;
		FD_ZERO(&rfds);
		FD_SET((SOCKET) fd,&rfds);
		FD_SET((SOCKET) fd1,&rfds);
		if (timeout) {
			t.tv_sec = timeout/1000;
			t.tv_usec = (timeout%1000)*1000;
		} else {
			tP = NULL;
		}
		res = select (fd, &rfds, NULL, NULL, tP);
		if (res == 0) {
			eraise("Accept timed out", EN_PROG);
			return -1;
		} else if (res == 1) {
			fd2 = FD_ISSET(fd, &rfds)? fd: fd1;
		} else if (res == 2) {
				/* avoid starvation */
			if (*a_last_fd != -1) {
				fd2 = *a_last_fd==fd? fd1: fd;
			} else {
				fd2 = fd;
			}
			*a_last_fd = fd2;
		} else {
			eraise("select failed", EN_PROG);
			return -1;
		}
		if (fd2 == fd) { /* v4 */
			len = sizeof (struct sockaddr_in);
		} else {
			len = sizeof (struct sockaddr_in6);
		}
		fd = fd2;
	} else {
		int ret;
		if (fd1 != -1) {
			fd = fd1;
			len = sizeof (struct sockaddr_in6);
		} else {
			len = sizeof (struct sockaddr_in);
		}
		if (timeout) {
			ret = net_timeout(fd, timeout);
			if (ret == 0) {
				eraise("Accept timed out", EN_PROG);
				return -1;
			} else if (ret == -1) {
				eraise("Socket closed", EN_PROG);
				return -1;
			} else if (ret == -2) {
				eraise("operation interrupted", EN_PROG);
				return -1;
			}
		}
	}

	accepted = check_socket_bounds(accept(fd, (struct sockaddr *)him, &len));
	if (accepted == INVALID_SOCKET) {
		eif_net_check ((int)accepted);
		return -1;
	} else {
		return (int)accepted;
	}
}