示例#1
0
文件: npcast.c 项目: noaaport/nbsp
static void np_close_channels(void){

  int i;

  for(i = 0; i < NPCAST_NUM_CHANNELS; ++i)
    close_channel(i);
}
示例#2
0
文件: openjpip.c 项目: 7sam7/openjpeg
OPJ_BOOL process_JPIPrequest( server_record_t *rec, QR_t *qr)
{
  target_param_t *target = NULL;
  session_param_t *cursession = NULL;
  channel_param_t *curchannel = NULL;

  if( qr->query->target || qr->query->tid){
    if( !identify_target( *(qr->query), rec->targetlist, &target))
      return OPJ_FALSE;
  }

  if( qr->query->cid){
    if( !associate_channel( *(qr->query), rec->sessionlist, &cursession, &curchannel))
      return OPJ_FALSE;
    qr->channel = curchannel;
  }
  
  if( qr->query->cnew != non){
    if( !open_channel( *(qr->query), rec->sessionlist, rec->auxtrans, target, &cursession, &curchannel))
      return OPJ_FALSE;
    qr->channel = curchannel;
  }
  
  if( qr->query->cclose)
    if( !close_channel( *(qr->query), rec->sessionlist, &cursession, &curchannel))
      return OPJ_FALSE;
  
  if( (qr->query->fx > 0 && qr->query->fy > 0) || qr->query->box_type[0][0] != 0 || qr->query->len > 0)
    if( !gene_JPIPstream( *(qr->query), target, cursession, curchannel, &qr->msgqueue))
      return OPJ_FALSE;

  return OPJ_TRUE;
}
示例#3
0
文件: channel.c 项目: AmesianX/wine
/**************************************************************************
 *          WsCloseChannel		[webservices.@]
 */
HRESULT WINAPI WsCloseChannel( WS_CHANNEL *handle, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;

    TRACE( "%p %p %p\n", handle, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    return close_channel( channel );
}
示例#4
0
文件: proxy.c 项目: RoninHsu/wine
/**************************************************************************
 *          WsCloseServiceProxy		[webservices.@]
 */
HRESULT WINAPI WsCloseServiceProxy( WS_SERVICE_PROXY *handle, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct proxy *proxy = (struct proxy *)handle;

    TRACE( "%p %p %p\n", handle, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    return close_channel( proxy->channel );
}
static int etherloop_deassign (OZ_Devunit *devunit, void *devexv, OZ_Iochan *iochan, void *chnexv)

{
  Chnex *chnex;
  Devex *devex;
  uLong dv;

  chnex = chnexv;
  devex = devexv;

  if (chnex -> rxreqt != NULL) {
    dv = oz_hw_smplock_wait (&(devex -> smplock));
    close_channel (devex, chnex, dv);
    oz_hw_smplock_clr (&(devex -> smplock), dv);
    if (chnex -> rxreqt != NULL) oz_crash ("oz_dev_etherloop deassign: channel still open after close");
  }

  return (0);
}
示例#6
0
static amqp_boolean_t check_channel_status(connstate_t *conn,
					   amqp_frame_t *frame,
					   chanstate_t *chan) {
  if (chan->status) {
    if (amqp_constant_is_hard_error(chan->status)) {
      close_connection(conn, chan->status, "Connection error %s (%d) in response to %s",
		       amqp_constant_name(chan->status),
		       chan->status,
		       amqp_method_name(frame->payload.method.id));
    } else {
      close_channel(conn, chan->channel, chan->status, "Channel error %s (%d) in response to %s",
		    amqp_constant_name(chan->status),
		    chan->status,
		    amqp_method_name(frame->payload.method.id));
    }
    return 1;
  } else {
    return 0;
  }
}
示例#7
0
int
main(int argc, char *argv[])
{
	struct socket *sock;
	struct sockaddr_in addr;
	socklen_t addr_len;
	char line[LINE_LENGTH + 1];
	unsigned int unordered, policy, value, id, seconds;
	unsigned int i;
	struct channel *channel;
	const int on = 1;
	struct sctp_assoc_value av;
	struct sctp_event event;
	struct sctp_udpencaps encaps;
	struct sctp_initmsg initmsg;
	uint16_t event_types[] = {SCTP_ASSOC_CHANGE,
	                          SCTP_PEER_ADDR_CHANGE,
	                          SCTP_REMOTE_ERROR,
	                          SCTP_SHUTDOWN_EVENT,
	                          SCTP_ADAPTATION_INDICATION,
	                          SCTP_SEND_FAILED_EVENT,
	                          SCTP_STREAM_RESET_EVENT,
	                          SCTP_STREAM_CHANGE_EVENT};

	if (argc > 1) {
		usrsctp_init(atoi(argv[1]), NULL, debug_printf);
	} else {
		usrsctp_init(9899, NULL, debug_printf);
	}
#ifdef SCTP_DEBUG
	usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
#endif
	usrsctp_sysctl_set_sctp_blackhole(2);

	if ((sock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, &peer_connection)) == NULL) {
		perror("socket");
	}
	init_peer_connection(&peer_connection);
	if (argc > 2) {
		memset(&encaps, 0, sizeof(struct sctp_udpencaps));
		encaps.sue_address.ss_family = AF_INET6;
		encaps.sue_port = htons(atoi(argv[2]));
		if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void*)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
			perror("setsockopt");
		}
	}
	if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(int)) < 0) {
		perror("setsockopt SCTP_RECVRCVINFO");
	}
	if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &on, sizeof(int)) < 0) {
		perror("setsockopt SCTP_EXPLICIT_EOR");
	}
	/* Allow resetting streams. */
	av.assoc_id = SCTP_ALL_ASSOC;
	av.assoc_value = SCTP_ENABLE_RESET_STREAM_REQ | SCTP_ENABLE_CHANGE_ASSOC_REQ;
	if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &av, sizeof(struct sctp_assoc_value)) < 0) {
		perror("setsockopt SCTP_ENABLE_STREAM_RESET");
	}
	/* Enable the events of interest. */
	memset(&event, 0, sizeof(event));
	event.se_assoc_id = SCTP_ALL_ASSOC;
	event.se_on = 1;
	for (i = 0; i < sizeof(event_types)/sizeof(uint16_t); i++) {
		event.se_type = event_types[i];
		if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event)) < 0) {
			perror("setsockopt SCTP_EVENT");
		}
	}
	memset(&initmsg, 0, sizeof(struct sctp_initmsg));
	initmsg.sinit_num_ostreams = 5;
	initmsg.sinit_max_instreams = 65535;
	if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg)) < 0) {
		perror("setsockopt SCTP_INITMSG");
	}
	
	if (argc == 5) {
		/* operating as client */
		memset(&addr, 0, sizeof(struct sockaddr_in));
		addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
		addr.sin_len = sizeof(struct sockaddr_in);
#endif
		addr.sin_addr.s_addr = inet_addr(argv[3]);
		addr.sin_port = htons(atoi(argv[4]));
		if (usrsctp_connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
			perror("connect");
		}
		printf("Connected to %s:%d.\n",
		       inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
	} else if (argc == 4) {
		struct socket *conn_sock;

		/* operating as server */
		memset(&addr, 0, sizeof(struct sockaddr_in));
		addr.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
		addr.sin_len = sizeof(struct sockaddr_in);
#endif
		addr.sin_addr.s_addr = INADDR_ANY;
		addr.sin_port = htons(atoi(argv[3]));
		if (usrsctp_bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
			perror("bind");
		}
		if (usrsctp_listen(sock, 1) < 0) {
			perror("listen");
		}
		addr_len = (socklen_t)sizeof(struct sockaddr_in);
		memset(&addr, 0, sizeof(struct sockaddr_in));
		if ((conn_sock = usrsctp_accept(sock, (struct sockaddr *)&addr, &addr_len)) == NULL) {
			perror("accept");
		}
		usrsctp_close(sock);
		sock = conn_sock;
		printf("Connected to %s:%d.\n",
		       inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
	} else {
		printf("Usage: %s local_udp_port remote_udp_port local_port when operating as server\n"
		       "       %s local_udp_port remote_udp_port remote_addr remote_port when operating as client\n",
		       argv[0], argv[0]);
		return (0);
	}

	lock_peer_connection(&peer_connection);
	peer_connection.sock = sock;
	unlock_peer_connection(&peer_connection);

	for (;;) {
#ifdef _WIN32
		if (gets_s(line, LINE_LENGTH) == NULL) {
#else
		if (fgets(line, LINE_LENGTH, stdin) == NULL) {
#endif
			if (usrsctp_shutdown(sock, SHUT_WR) < 0) {
				perror("usrsctp_shutdown");
			}
			while (usrsctp_finish() != 0) {
#ifdef _WIN32
				Sleep(1000);
#else
				sleep(1);
#endif
			}
			break;
		}
		if (strncmp(line, "?", strlen("?")) == 0 ||
		    strncmp(line, "help", strlen("help")) == 0) {
			printf("Commands:\n"
			       "open unordered pr_policy pr_value - opens a channel\n"
			       "close channel - closes the channel\n"
			       "send channel:string - sends string using channel\n"
			       "status - prints the status\n"
			       "sleep n - sleep for n seconds\n"
			       "help - this message\n");
		} else if (strncmp(line, "status", strlen("status")) == 0) {
			lock_peer_connection(&peer_connection);
			print_status(&peer_connection);
			unlock_peer_connection(&peer_connection);
		} else if (strncmp(line, "quit", strlen("quit")) == 0) {
			if (usrsctp_shutdown(sock, SHUT_WR) < 0) {
				perror("usrsctp_shutdown");
			}
			while (usrsctp_finish() != 0) {
#ifdef _WIN32
				Sleep(1000);
#else
				sleep(1);
#endif
			}
			break;
		} else if (sscanf(line, "open %u %u %u", &unordered, &policy, &value) == 3) {
			lock_peer_connection(&peer_connection);
			channel = open_channel(&peer_connection, (uint8_t)unordered, (uint16_t)policy, (uint32_t)value);
			unlock_peer_connection(&peer_connection);
			if (channel == NULL) {
				printf("Creating channel failed.\n");
			} else {
				printf("Channel with id %u created.\n", channel->id);
			}
		} else if (sscanf(line, "close %u", &id) == 1) {
			if (id < NUMBER_OF_CHANNELS) {
				lock_peer_connection(&peer_connection);
				close_channel(&peer_connection, &peer_connection.channels[id]);
				unlock_peer_connection(&peer_connection);
			}
		} else if (sscanf(line, "send %u", &id) == 1) {
			if (id < NUMBER_OF_CHANNELS) {
				char *msg;

				msg = strstr(line, ":");
				if (msg) {
					msg++;
					lock_peer_connection(&peer_connection);
#ifdef _WIN32
					if (send_user_message(&peer_connection, &peer_connection.channels[id], msg, strlen(msg))) {
#else
					if (send_user_message(&peer_connection, &peer_connection.channels[id], msg, strlen(msg) - 1)) {
#endif
						printf("Message sent.\n");
					} else {
						printf("Message sending failed.\n");
					}
					unlock_peer_connection(&peer_connection);
				}
			}
		} else if (sscanf(line, "sleep %u", &seconds) == 1) {
#ifdef _WIN32
			Sleep(seconds * 1000);
#else
			sleep(seconds);
#endif
		} else {
			printf("Unknown command: %s", line);
		}
	}
	return (0);
}
示例#8
0
文件: gsstest.c 项目: aosm/gssd
void *client(void *arg)
{
	channel_t channel = (channel_t)arg;
	uint32_t major_stat;
	uint32_t minor_stat;
	uint32_t rflags;
	uint32_t inout_gssd_flags;
	gssd_cred cred_handle = (gssd_cred) (uintptr_t)GSS_C_NO_CREDENTIAL;
	gssd_ctx gss_context = (gssd_ctx) (uintptr_t)GSS_C_NO_CONTEXT;
	kern_return_t kr;
	int gss_error = 0;
	int retry_count = 0;
	char display_name[128];

	do {
		if (read_channel(1, channel)) {
			Log("Bad read from server\n");
			return (NULL);
		}

		if (verbose)
			Debug("Calling mach_gss_init_sec_context from %p\n",
				(void *) pthread_self());

		deallocate(channel->ctoken, channel->ctokenCnt);
		channel->ctoken = (gssd_byte_buffer)GSS_C_NO_BUFFER;
		channel->ctokenCnt = 0;
retry:
		switch (version) {
		case 0:
		case 1:
			kr = mach_gss_init_sec_context(
						       client_mp,
						       mech,
						       channel->stoken, channel->stokenCnt,
						       uid,
						       principal,
						       svcname,
						       flags,
						       gssd_flags,
						       &gss_context,
						       &cred_handle,
						       &rflags,
						       &channel->clnt_skey, &channel->clnt_skeyCnt,
						       &channel->ctoken, &channel->ctokenCnt,
						       &major_stat,
						       &minor_stat);
			break;
		case 2:
			inout_gssd_flags = gssd_flags;
			kr = mach_gss_init_sec_context_v2(
							  client_mp,
							  mech,
							  channel->stoken, channel->stokenCnt,
							  uid,
							  clientp.nt,
							  clientp.name,
							  clientp.len,
							  targetp.nt,
							  targetp.name,
							  targetp.len,
							  flags,
							  &inout_gssd_flags,
							  &gss_context,
							  &cred_handle,
							  &rflags,
							  &channel->clnt_skey, &channel->clnt_skeyCnt,
							  &channel->ctoken, &channel->ctokenCnt,
							  display_name,
							  &major_stat,
							  &minor_stat);
			if (verbose && kr == KERN_SUCCESS && major_stat ==  GSS_S_COMPLETE)
				Debug("Got client identity of '%s'\n", display_name);
			break;
		default:
			Log("Unsupported version %d\n", version);
			exit(1);
			break;
		}

		if (kr != KERN_SUCCESS) {
			OSAtomicIncrement32(&server_errors);
			Log("gsstest client: %s\n", mach_error_string(kr));
			if (exitonerror)
				exit(1);
			if (kr == MIG_SERVER_DIED) {
				OSAtomicIncrement32(&server_deaths);
				if (gss_context == (uint32_t)(uintptr_t)GSS_C_NO_CONTEXT &&
					retry_count < max_retries) {
					retry_count++;
					goto retry;
				}
			}

			channel->failure = 1;
			write_channel(1, channel);
			return (NULL);
		}

		gss_error = (major_stat != GSS_S_COMPLETE &&
					major_stat != GSS_S_CONTINUE_NEEDED);
		if (verbose > 1) {
			Debug("\tcred = 0x%0x\n", (int) cred_handle);
			Debug("\tclnt_gss_context = 0x%0x\n",
				(int) gss_context);
			Debug("\ttokenCnt = %d\n", (int) channel->ctokenCnt);
			if (verbose > 2)
				HexDump((char *) channel->ctoken,
					 (uint32_t) channel->ctokenCnt);
		}

		channel->failure = gss_error;
		write_channel(1, channel);
	} while (major_stat == GSS_S_CONTINUE_NEEDED);


	if (gss_error) {
		OSAtomicIncrement32(&gss_init_errors);
		Log("mach_gss_int_sec_context: %#K %#k\n", major_stat, mechtab[mech], minor_stat);
	}

	close_channel(1, channel);
	return (NULL);
}
int main(int argc, char ** argv)
{
	int sc_fifo_fd, cs_fifo_fd;

	/* Mandatory arguments */
	if( !argv[1] || !argv[2] || !argv[3] || !argv[4] ) {
		fprintf(stderr,"client [server->client fifo] [client->server fifo] [password file] [username]\n");
		exit(1);
	}

	/* Create connection with the server */
	fprintf(stderr,"Create connection...\n");
	sc_fifo_fd = open_channel(argv[1]);
	cs_fifo_fd = open_channel(argv[2]);

	write_msg(cs_fifo_fd,(const u_int8_t *)CONNECTION_STRING,strlen(CONNECTION_STRING));

	/* Read OK */
	if( read_string(sc_fifo_fd,OK_STRING) < 0 ) {
		fprintf(stderr,"Communication error\n");
		goto next1;
	}

	/* Server authentication */
	write_msg(cs_fifo_fd,(const u_int8_t *)"A",1);

  // GET public rsa key of S, (s_puk,n), from "client_folder/server_rsa_public_key.txt"
  /* ... */
  // CREATE a random number r
  /* ... */
  // ENCRYPT r using (s_puk,n) -> c = r^s_puk mod n
  /* ... */
  // WRITE c to S
  /* ... */
  // READ r' from C
  /* ... */
  // CHECK if r = r'
  /* ... */

	/* Client authentication */
  // SEND client_name to S
  /* ... */
  // GET private rsa key of C, (s_prk,n) from "client_folder/client_rsa_private_key.txt"
  /* ... */
  // READ c from S
  /* ... */
  // DECRYPT c using (c_prk,n) -> r' = c^c_prk mod n
  /* ... */
  // WRITE r' to S
  /* ... */
  // GET private rsa key of C, c_prk from "client_folder/client_rsa_private_key.txt"
  /* ... */
  
  /* Negotiation of the cipher suite */
  /* ... */    

  /* Negotiation of the private key */  
  /* ... */    

  /* Encrypt communication */
  /* ... */    
  
  /* Disconnection */
  /* ... */    


next1: // to be used when server writes the BYE string
	/* Close connection with the server */
	fprintf(stderr,"Closing connection...\n");

	/* Expect BYE */
	if( read_string(sc_fifo_fd,CLOSE_CONNECTION_STRING) < 0 ) {
		fprintf(stderr,"Communication error\n");
		goto next1;
	}

	close_channel(cs_fifo_fd);
	close_channel(sc_fifo_fd);
   
  exit(0) ;

next2: // to be used when client writes the BYE string
		/* Close current connection */
		fprintf(stderr,"Closing connection...\n");
		write_BYE(cs_fifo_fd);
		close_channel(cs_fifo_fd);
		close_channel(sc_fifo_fd);
	exit(0);
}
示例#10
0
static uLong etherloop_start (OZ_Devunit *devunit, void *devexv, OZ_Iochan *iochan, void *chnexv, OZ_Procmode procmode, 
                              OZ_Ioop *ioop, void *iopexv, uLong funcode, uLong as, void *ap)

{
  Chnex *chnex;
  Devex *devex;
  Iopex *iopex, **liopex;
  int i;
  uLong dv, sts;
  Rxbuf *rxbuf;

  chnex = chnexv;
  devex = devexv;
  iopex = iopexv;

  switch (funcode) {

    /* Open - associates a protocol number with a channel and starts reception */

    case OZ_IO_ETHER_OPEN: {
      OZ_IO_ether_open ether_open;

      movc4 (as, ap, sizeof ether_open, &ether_open);

      /* Make sure not already open */

      dv = oz_hw_smplock_wait (&(devex -> smplock));
      if (chnex -> rxreqt != NULL) {
        oz_hw_smplock_clr (&(devex -> smplock), dv);
        return (OZ_FILEALREADYOPEN);
      }

      /* Put channel on list of open channels */

      chnex -> proto  = N2HW (ether_open.proto);
      chnex -> promis = ether_open.promis;
      chnex -> rxreqt = &(chnex -> rxreqh);
      chnex -> next   = devex -> chnexs;
      devex -> chnexs = chnex;
      oz_hw_smplock_clr (&(devex -> smplock), dv);
      return (OZ_SUCCESS);
    }

    /* Disassociates a protocol with a channel and stops reception */

    case OZ_IO_ETHER_CLOSE: {
      dv = oz_hw_smplock_wait (&(devex -> smplock));
      i = close_channel (devex, chnex, dv);
      oz_hw_smplock_clr (&(devex -> smplock), dv);

      return (i ? OZ_SUCCESS : OZ_FILENOTOPEN);
    }

    /* Receive a message */

    case OZ_IO_ETHER_RECEIVE: {

      /* Get parameter block into iopex for future reference */

      movc4 (as, ap, sizeof iopex -> receive, &(iopex -> receive));

      /* If any of the rcv... parameters are filled in, it must be called from kernel mode */

      if ((iopex -> receive.rcvfre != NULL) || (iopex -> receive.rcvdrv_r != NULL) || (iopex -> receive.rcveth_r != NULL)) {
        if (procmode != OZ_PROCMODE_KNL) return (OZ_KERNELONLY);
      }

      /* Set up the request parameters and queue request so the interrupt routine can fill the buffer with an incoming message */

      iopex -> ioop     = ioop;
      iopex -> next     = NULL;
      iopex -> procmode = procmode;
      iopex -> devex    = devex;

      rxbuf = iopex -> receive.rcvfre;					/* maybe requestor has a buffer to free off */
      if ((rxbuf != NULL) && (oz_hw_atomic_inc_long (&(rxbuf -> refcount), -1) == 0)) OZ_KNL_NPPFREE (rxbuf);

      dv = oz_hw_smplock_wait (&(devex -> smplock));			/* lock database */
      liopex = chnex -> rxreqt;
      sts = OZ_FILENOTOPEN;						/* make sure channel is still open */
      if (liopex != NULL) {
        *liopex = iopex;						/* put reqeuest on end of queue - transmit routine can now see it */
        chnex -> rxreqt = &(iopex -> next);
        sts = OZ_STARTED;
      }
      oz_hw_smplock_clr (&(devex -> smplock), dv);
      return (sts);
    }

    /* Free a receive buffer */

    case OZ_IO_ETHER_RECEIVEFREE: {
      OZ_IO_ether_receivefree ether_receivefree;

      if (procmode != OZ_PROCMODE_KNL) return (OZ_KERNELONLY);		/* can only be called from kernel mode */
      movc4 (as, ap, sizeof ether_receivefree, &ether_receivefree);	/* get the parameters */
      rxbuf = ether_receivefree.rcvfre;					/* point to the buffer */
      if (oz_hw_atomic_inc_long (&(rxbuf -> refcount), -1) == 0) OZ_KNL_NPPFREE (rxbuf); /* free it if no one else using it */
      return (OZ_SUCCESS);
    }

    /* Allocate a send buffer */

    case OZ_IO_ETHER_TRANSMITALLOC: {
      OZ_IO_ether_transmitalloc ether_transmitalloc;

      if (procmode != OZ_PROCMODE_KNL) return (OZ_KERNELONLY);		/* can only be called from kernel mode */
      movc4 (as, ap, sizeof ether_transmitalloc, &ether_transmitalloc);	/* get the parameters */
      rxbuf = OZ_KNL_NPPMALLOQ (sizeof *rxbuf);				/* allocate a receive buffer */
      if (rxbuf == NULL) return (OZ_EXQUOTANPP);
      if (ether_transmitalloc.xmtsiz_r != NULL) *(ether_transmitalloc.xmtsiz_r) = OZ_IO_ETHER_MAXDATA;	/* this is size of data it can handle */
      if (ether_transmitalloc.xmtdrv_r != NULL) *(ether_transmitalloc.xmtdrv_r) = rxbuf;		/* this is the pointer we want returned in ether_transmit.xmtdrv */
      if (ether_transmitalloc.xmteth_r != NULL) *(ether_transmitalloc.xmteth_r) = (uByte *)&(rxbuf -> buf); /* this is where they put the ethernet packet to be transmitted */
      return (OZ_SUCCESS);
    }

    /* Transmit a message */

    case OZ_IO_ETHER_TRANSMIT: {
      OZ_IO_ether_transmit ether_transmit;

      /* Get parameter block into iopex for future reference */

      movc4 (as, ap, sizeof ether_transmit, &ether_transmit);

      /* Any xmt... parameters require caller to be in kernel mode */

      if ((ether_transmit.xmtdrv != NULL) || (ether_transmit.xmtdrv_r != NULL) || (ether_transmit.xmtsiz_r != NULL) || (ether_transmit.xmteth_r != NULL)) {
        if (procmode != OZ_PROCMODE_KNL) return (OZ_KERNELONLY);
        if (ether_transmit.xmtsiz_r != NULL) *(ether_transmit.xmtsiz_r) = 0;
        if (ether_transmit.xmtdrv_r != NULL) *(ether_transmit.xmtdrv_r) = NULL;
        if (ether_transmit.xmteth_r != NULL) *(ether_transmit.xmteth_r) = NULL;
      }

      /* See if they gave us a system buffer */

      if (ether_transmit.xmtdrv != NULL) rxbuf = ether_transmit.xmtdrv;

      /* If not, allocate one */

      else if (ether_transmit.buff == NULL) return (OZ_MISSINGPARAM);
      else {
        rxbuf = OZ_KNL_NPPMALLOQ (sizeof *rxbuf);
        if (rxbuf == NULL) return (OZ_EXQUOTANPP);
      }

      /* Anyway, copy in any data that they supplied */

      if (ether_transmit.buff != NULL) {
        oz_knl_printk ("oz_dev_ip*: #1 %u < %u\n", ether_transmit.size, rxbuf -> buf.data - (uByte *)&(rxbuf -> buf));
        oz_knl_printk ("oz_dev_ip*: #2 %u > %u\n", ether_transmit.size, sizeof rxbuf -> buf);
        if (ether_transmit.size < rxbuf -> buf.data - (uByte *)&(rxbuf -> buf)) sts = OZ_BADBUFFERSIZE;							/* have to give at least the ethernet header stuff */
        else if (ether_transmit.size > sizeof rxbuf -> buf) sts = OZ_BADBUFFERSIZE;									/* can't give us more than buffer can hold */
        else sts = oz_knl_section_uget (procmode, ether_transmit.size, ether_transmit.buff, &(rxbuf -> buf));						/* copy it in */
        oz_knl_printk ("oz_dev_ip*: #3 %u < %u\n", ether_transmit.size, rxbuf -> dlen + rxbuf -> buf.data - (uByte *)&(rxbuf -> buf));
        if ((sts == OZ_SUCCESS) && (ether_transmit.size < rxbuf -> dlen + rxbuf -> buf.data - (uByte *)&(rxbuf -> buf))) sts = OZ_BADBUFFERSIZE;	/* must give enough to cover the dlen */
        if (sts != OZ_SUCCESS) {
          OZ_KNL_NPPFREE (rxbuf);
          return (sts);
        }
      }

      /* Make sure dlen (length of data not including header) not too int */

      oz_knl_printk ("oz_dev_ip*: #4 %u > %u\n", rxbuf -> dlen, DATASIZE);
      if (rxbuf -> dlen > DATASIZE) {			/* can't be longer than hardware will allow */
        OZ_KNL_NPPFREE (rxbuf);				/* free off internal buffer */
        return (OZ_BADBUFFERSIZE);			/* return error status */
      }

      /* Process it - hopefully there is a receive request to process it - if not, data is lost */

      buffereceived (devex, rxbuf);

      /* If caller requested, allocate a transmit buffer to replace one used */

      if (ether_transmit.xmtdrv_r != NULL) {
        rxbuf = OZ_KNL_NPPMALLOQ (sizeof *rxbuf);
        if (rxbuf == NULL) return (OZ_EXQUOTANPP);
        if (ether_transmit.xmtsiz_r != NULL) *(ether_transmit.xmtsiz_r) = OZ_IO_ETHER_MAXDATA;
        if (ether_transmit.xmtdrv_r != NULL) *(ether_transmit.xmtdrv_r) = rxbuf;
        if (ether_transmit.xmteth_r != NULL) *(ether_transmit.xmteth_r) = (uByte *)&(rxbuf -> buf);
      }
      return (OZ_SUCCESS);
    }

    /* Get info - part 1 */

    case OZ_IO_ETHER_GETINFO1: {
      OZ_IO_ether_getinfo1 ether_getinfo1;

      movc4 (as, ap, sizeof ether_getinfo1, &ether_getinfo1);
      if (ether_getinfo1.enaddrbuff != NULL) {
        if (ether_getinfo1.enaddrsize > ADDRSIZE) ether_getinfo1.enaddrsize = ADDRSIZE;
        sts = oz_knl_section_uput (procmode, ether_getinfo1.enaddrsize, devex -> enaddr, ether_getinfo1.enaddrbuff);
        if (sts != OZ_SUCCESS) return (sts);
      }
      ether_getinfo1.datasize   = DATASIZE;				// max length of data portion of message
      ether_getinfo1.buffsize   = BUFFSIZE;				// max length of whole message (header, data, crc)
      ether_getinfo1.dstaddrof  = 0;					// offset of dest address in packet
      ether_getinfo1.srcaddrof  = 0 + ADDRSIZE;				// offset of source address in packet
      ether_getinfo1.protooffs  = 0 + 2 * ADDRSIZE;			// offset of protocol in packet
      ether_getinfo1.dataoffset = 0 + 2 * ADDRSIZE + PROTOSIZE;		// offset of data in packet
      ether_getinfo1.arphwtype  = ARPHWTYPE;				// ARP hardware type
      ether_getinfo1.addrsize   = ADDRSIZE;				// size of each address field
      ether_getinfo1.protosize  = PROTOSIZE;				// size of protocol field
      if (as > sizeof ether_getinfo1) as = sizeof ether_getinfo1;
      sts = oz_knl_section_uput (procmode, as, &ether_getinfo1, ap);
      return (sts);
    }
  }

  return (OZ_BADIOFUNC);
}
示例#11
0
int main(int argc, char *argv[])
{
	int daemonize = 0;
	char *pidfile = NULL;
	char *envarea = NULL;
	int cnid = -1;
	pcre *msgfilter = NULL;
	pcre *stdfilter = NULL;

	int argi;
	struct sigaction sa;
	RbtIterator handle;


	/* Dont save the error buffer */
	save_errbuf = 0;

	/* Create the peer container */
	peers = rbtNew(name_compare);

	for (argi=1; (argi < argc); argi++) {
		if (argnmatch(argv[argi], "--debug")) {
			debug = 1;
		}
		else if (argnmatch(argv[argi], "--channel=")) {
			char *cn = strchr(argv[argi], '=') + 1;

			for (cnid = C_STATUS; (channelnames[cnid] && strcmp(channelnames[cnid], cn)); cnid++) ;
			if (channelnames[cnid] == NULL) cnid = -1;
		}
		else if (argnmatch(argv[argi], "--daemon")) {
			daemonize = 1;
		}
		else if (argnmatch(argv[argi], "--no-daemon")) {
			daemonize = 0;
		}
		else if (argnmatch(argv[argi], "--pidfile=")) {
			char *p = strchr(argv[argi], '=');
			pidfile = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--log=")) {
			char *p = strchr(argv[argi], '=');
			logfn = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--env=")) {
			char *p = strchr(argv[argi], '=');
			loadenv(p+1, envarea);
		}
		else if (argnmatch(argv[argi], "--area=")) {
			char *p = strchr(argv[argi], '=');
			envarea = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--locator=")) {
			char *p = strchr(argv[argi], '=');
			locator_init(p+1);
			locatorbased = 1;
		}
		else if (argnmatch(argv[argi], "--service=")) {
			char *p = strchr(argv[argi], '=');
			locatorservice = get_servicetype(p+1);
		}
		else if (argnmatch(argv[argi], "--filter=")) {
			char *p = strchr(argv[argi], '=');
			msgfilter = compileregex(p+1);
			if (!msgfilter) {
				errprintf("Invalid filter (bad expression): %s\n", p+1);
			}
			else {
				stdfilter = compileregex("^@@(logrotate|shutdown|drophost|droptest|renamehost|renametest)");
			}
		}
		else {
			char *childcmd;
			char **childargs;
			int i = 0;

			childcmd = argv[argi];
			childargs = (char **) calloc((1 + argc - argi), sizeof(char *));
			while (argi < argc) { childargs[i++] = argv[argi++]; }
			addlocalpeer(childcmd, childargs);
		}
	}

	/* Sanity checks */
	if (cnid == -1) {
		errprintf("No channel/unknown channel specified\n");
		return 1;
	}
	if (locatorbased && (locatorservice == ST_MAX)) {
		errprintf("Must specify --service when using locator\n");
		return 1;
	}
	if (!locatorbased && (rbtBegin(peers) == rbtEnd(peers))) {
		errprintf("Must specify command for local worker\n");
		return 1;
	}

	/* Do cache responses to avoid doing too many lookups */
	if (locatorbased) locator_prepcache(locatorservice, 0);

	/* Go daemon */
	if (daemonize) {
		/* Become a daemon */
		pid_t daemonpid = fork();
		if (daemonpid < 0) {
			/* Fork failed */
			errprintf("Could not fork child\n");
			exit(1);
		}
		else if (daemonpid > 0) {
			/* Parent creates PID file and exits */
			FILE *fd = NULL;
			if (pidfile) fd = fopen(pidfile, "w");
			if (fd) {
				fprintf(fd, "%d\n", (int)daemonpid);
				fclose(fd);
			}
			exit(0);
		}
		/* Child (daemon) continues here */
		setsid();
	}

	/* Catch signals */
	setup_signalhandler("xymond_channel");
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sig_handler;
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGCHLD, &sa, NULL);
	signal(SIGALRM, SIG_IGN);

	/* Switch stdout/stderr to the logfile, if one was specified */
	freopen("/dev/null", "r", stdin);	/* xymond_channel's stdin is not used */
	if (logfn) {
		freopen(logfn, "a", stdout);
		freopen(logfn, "a", stderr);
	}

	/* Attach to the channel */
	channel = setup_channel(cnid, CHAN_CLIENT);
	if (channel == NULL) {
		errprintf("Channel not available\n");
		running = 0;
	}

	while (running) {
		/* 
		 * Wait for GOCLIENT to go up.
		 *
		 * Note that we use IPC_NOWAIT if there are messages in the
		 * queue, because then we just want to pick up a message if
		 * there is one, and if not we want to continue pushing the
		 * queued data to the worker.
		 */
		struct sembuf s;
		int n;

		s.sem_num = GOCLIENT; s.sem_op  = -1; s.sem_flg = ((pendingcount > 0) ? IPC_NOWAIT : 0);
		n = semop(channel->semid, &s, 1);

		if (n == 0) {
			/*
			 * GOCLIENT went high, and so we got alerted about a new
			 * message arriving. Copy the message to our own buffer queue.
			 */
			char *inbuf = NULL;

			if (!msgfilter || matchregex(channel->channelbuf, msgfilter) || matchregex(channel->channelbuf, stdfilter)) {
				inbuf = strdup(channel->channelbuf);
			}

			/* 
			 * Now we have safely stored the new message in our buffer.
			 * Wait until any other clients on the same channel have picked up 
			 * this message (GOCLIENT reaches 0).
			 *
			 * We wrap this into an alarm handler, because it can occasionally
			 * fail, causing the whole system to lock up. We dont want that....
			 * We'll set the alarm to trigger after 1 second. Experience shows
			 * that we'll either succeed in a few milliseconds, or fail completely
			 * and wait the full alarm-timer duration.
			 */
			gotalarm = 0; signal(SIGALRM, sig_handler); alarm(2); 
			do {
				s.sem_num = GOCLIENT; s.sem_op  = 0; s.sem_flg = 0;
				n = semop(channel->semid, &s, 1);
			} while ((n == -1) && (errno == EAGAIN) && running && (!gotalarm));
			signal(SIGALRM, SIG_IGN);

			if (gotalarm) {
				errprintf("Gave up waiting for GOCLIENT to go low.\n");
			}

			/* 
			 * Let master know we got it by downing BOARDBUSY.
			 * This should not block, since BOARDBUSY is upped
			 * by the master just before he ups GOCLIENT.
			 */
			do {
				s.sem_num = BOARDBUSY; s.sem_op  = -1; s.sem_flg = IPC_NOWAIT;
				n = semop(channel->semid, &s, 1);
			} while ((n == -1) && (errno == EINTR));
			if (n == -1) {
				errprintf("Tried to down BOARDBUSY: %s\n", strerror(errno));
			}

			if (inbuf) {
				/*
				 * See if they want us to rotate logs. We pass this on to
				 * the worker module as well, but must handle our own logfile.
				 */
				if (strncmp(inbuf, "@@logrotate", 11) == 0) {
					freopen(logfn, "a", stdout);
					freopen(logfn, "a", stderr);
				}

				/*
				 * Put the new message on our outbound queue.
				 */
				if (addmessage(inbuf) != 0) {
					/* Failed to queue message, free the buffer */
					xfree(inbuf);
				}
			}
		}
		else {
			if (errno != EAGAIN) {
				dbgprintf("Semaphore wait aborted: %s\n", strerror(errno));
				continue;
			}
		}

		/* 
		 * We've picked up messages from the master. Now we 
		 * must push them to the worker process. Since there 
		 * is no way to hang off both a semaphore and select(),
		 * we'll just push as much data as possible into the 
		 * pipe. If we get to a point where we would block,
		 * then wait a teeny bit of time and restart the 
		 * whole loop with checking for new messages from the
		 * master etc.
		 *
		 * In theory, this could become an almost busy-wait loop.
		 * In practice, however, the queue will be empty most
		 * of the time because we'll just shove the data to the
		 * worker child.
		 */
		for (handle = rbtBegin(peers); (handle != rbtEnd(peers)); handle = rbtNext(peers, handle)) {
			int canwrite = 1, hasfailed = 0;
			xymon_peer_t *pwalk;
			time_t msgtimeout = gettimer() - MSGTIMEOUT;
			int flushcount = 0;

			pwalk = (xymon_peer_t *) gettreeitem(peers, handle);
			if (pwalk->msghead == NULL) continue; /* Ignore peers with nothing queued */

			switch (pwalk->peerstatus) {
			  case P_UP:
				canwrite = 1;
				break;

			  case P_DOWN:
				openconnection(pwalk);
				canwrite = (pwalk->peerstatus == P_UP);
				break;

			  case P_FAILED:
				canwrite = 0;
				break;
			}

			/* See if we have stale messages queued */
			while (pwalk->msghead && (pwalk->msghead->tstamp < msgtimeout)) {
				flushmessage(pwalk);
				flushcount++;
			}

			if (flushcount) {
				errprintf("Flushed %d stale messages for %s:%d\n",
					  flushcount,
				  	  inet_ntoa(pwalk->peeraddr.sin_addr), 
					  ntohs(pwalk->peeraddr.sin_port));
			}

			while (pwalk->msghead && canwrite) {
				fd_set fdwrite;
				struct timeval tmo;

				/* Check that this peer is ready for writing. */
				FD_ZERO(&fdwrite); FD_SET(pwalk->peersocket, &fdwrite);
				tmo.tv_sec = 0; tmo.tv_usec = 2000;
				n = select(pwalk->peersocket+1, NULL, &fdwrite, NULL, &tmo);
				if (n == -1) {
					errprintf("select() failed: %s\n", strerror(errno));
					canwrite = 0; 
					hasfailed = 1;
					continue;
				}
				else if ((n == 0) || (!FD_ISSET(pwalk->peersocket, &fdwrite))) {
					canwrite = 0;
					continue;
				}

				n = write(pwalk->peersocket, pwalk->msghead->bufp, pwalk->msghead->buflen);
				if (n >= 0) {
					pwalk->msghead->bufp += n;
					pwalk->msghead->buflen -= n;
					if (pwalk->msghead->buflen == 0) flushmessage(pwalk);
				}
				else if (errno == EAGAIN) {
					/*
					 * Write would block ... stop for now. 
					 */
					canwrite = 0;
				}
				else {
					hasfailed = 1;
				}

				if (hasfailed) {
					/* Write failed, or message grew stale */
					errprintf("Peer at %s:%d failed: %s\n",
						  inet_ntoa(pwalk->peeraddr.sin_addr), ntohs(pwalk->peeraddr.sin_port),
						  strerror(errno));
					canwrite = 0;
					shutdownconnection(pwalk);
					if (pwalk->peertype == P_NET) locator_serverdown(pwalk->peername, locatorservice);
					pwalk->peerstatus = P_FAILED;
				}
			}
		}
	}

	/* Detach from channels */
	close_channel(channel, CHAN_CLIENT);

	/* Close peer connections */
	for (handle = rbtBegin(peers); (handle != rbtEnd(peers)); handle = rbtNext(peers, handle)) {
		xymon_peer_t *pwalk = (xymon_peer_t *) gettreeitem(peers, handle);
		shutdownconnection(pwalk);
	}

	/* Remove the PID file */
	if (pidfile) unlink(pidfile);

	return 0;
}