예제 #1
0
파일: ciao_zmq_ll.c 프로젝트: AtnNn/ciao
void 
ciao_zmq_socket(char *socket_atom, char *type_atom) {

  // .. Check if the socket exists .................................
  if(find_socket(socket_atom)!=NULL) {
    report_error(EINVAL, "socket_already_exists", socket_atom);
    return;
  }

  // .. Fetch the socket type ......................................
  ciao_zmq_atom_option *type_option= find_option(socket_options, 
						   type_atom);
  if(type_option==NULL) {
    report_error(EINVAL, "invalid_socket_type", socket_atom);
    return;
  }

  // .. Create the new socket ......................................

  ciao_zmq_state *state= get_state();
  void *newsocket= zmq_socket(state->zmq_context, type_option->value);
  if(newsocket==NULL) {
    report_error(errno, "error_creating_socket", socket_atom);
    return;
  }

  // .. Add the new socket record ..................................
  ciao_zmq_socket_assoc *assoc= malloc(sizeof(ciao_zmq_socket_assoc));
  assoc->next= state->socket_list;
  assoc->zmq_socket= newsocket;
  strncpy(assoc->socket_atom_chars, socket_atom, CIAO_ZMQ_MAX_ATOM_LEN);
  state->socket_list= assoc;
}
예제 #2
0
//此线程专门用于解析文件并将文件发送到相应的汇聚节点
void  *parse_file_send()
{
	char	filename[50];
	int	fd;
	int	filelen;

	while(1)
	{
		pthread_mutex_lock(&ListLock);
		while(L->next != NULL)
		{
			Lnode   *s;
			s = L->next;

			memset(filename, 0, sizeof(filename));
			sprintf(filename, s->filename);
			filelen = s->st_size;

			fd = find_socket(filename);
			if(fd < 0)
			{
				printf("find_socket error\n");
			}

			send_file(filename, fd);

			L->next = s->next;
			free(s);
		}

		pthread_mutex_unlock(&ListLock);

		sleep(3);
	}
}
예제 #3
0
static int send_message(char *sig, char *message, int length)
{
	int sock;
	int len;
	struct sockaddr_un remote;

	sock = socket(AF_UNIX, SOCK_STREAM, 0);
	if (-1 == sock) {
		perror("Unable to create socket");
		return 1;
	}


	remote.sun_family = AF_UNIX;
	if (find_socket(sig, remote.sun_path, sizeof(remote.sun_path))) {
		fprintf(stderr, "Unable to locate socket: File not found\n");
		close(sock);
		return 1;
	}
	len = strlen(remote.sun_path) + sizeof(remote.sun_family);


	if (connect(sock, (struct sockaddr *)&remote, len) == -1) {
		perror("Unable to conncet to socket");
		close(sock);
		return 1;
	}

	send(sock, message, length, 0);

	close(sock);
	return 0;
}
예제 #4
0
파일: svc.c 프로젝트: xiandaicxsj/copyKvm
static int make_socks(struct svc_serv *serv, int proto)
{
	/* Make any sockets that are needed but not present.
	 * If nlm_udpport or nlm_tcpport were set as module
	 * options, make those sockets unconditionally
	 */
	static int		warned;
	int err = 0;
	if (proto == IPPROTO_UDP || nlm_udpport)
		if (!find_socket(serv, IPPROTO_UDP))
			err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport);
	if (err == 0 && (proto == IPPROTO_TCP || nlm_tcpport))
		if (!find_socket(serv, IPPROTO_TCP))
			err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport);
	if (!err)
		warned = 0;
	else if (warned++ == 0)
		printk(KERN_WARNING
		       "lockd_up: makesock failed, error=%d\n", err);
	return err;
}
예제 #5
0
파일: svc.c 프로젝트: PennPanda/linux-repo
/*
 * Make any sockets that are needed but not present.
 * If nlm_udpport or nlm_tcpport were set as module
 * options, make those sockets unconditionally
 */
static int make_socks(struct svc_serv *serv, int proto)
{
	static int warned;
	int err = 0;

	if (proto == IPPROTO_UDP || nlm_udpport)
		if (!find_socket(serv, IPPROTO_UDP))
			err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport,
						SVC_SOCK_DEFAULTS);
	if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport))
		if (!find_socket(serv, IPPROTO_TCP))
			err = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport,
						SVC_SOCK_DEFAULTS);

	if (err >= 0) {
		warned = 0;
		err = 0;
	} else if (warned++ == 0)
		printk(KERN_WARNING
		       "lockd_up: makesock failed, error=%d\n", err);
	return err;
}
예제 #6
0
파일: ciao_zmq_ll.c 프로젝트: AtnNn/ciao
void
ciao_zmq_connect(char *socket_atom, char *endpoint) {

  // .. Find the socket ............................................
  ciao_zmq_socket_assoc *assoc= find_socket(socket_atom);
  if(assoc==NULL) {
    report_error(EINVAL, "socket_not_found", socket_atom);
    return;
  } 

  // .. Make connection ............................................
  if(zmq_connect(assoc->zmq_socket, endpoint)) {
    report_error(errno, "error_connecting_socket", socket_atom);
  }
}
예제 #7
0
파일: ciao_zmq_ll.c 프로젝트: AtnNn/ciao
void
ciao_zmq_bind(char *socket_atom, char *endpoint) {

  // .. Find the socket ............................................
  ciao_zmq_socket_assoc *assoc= find_socket(socket_atom);
  if(assoc==NULL) {
    report_error(EINVAL, "socket_not_found", socket_atom);
    return;
  } 

  // .. Perform binding ............................................
  if(zmq_bind(assoc->zmq_socket, endpoint)) {
    report_error(errno, "error_binding_socket", socket_atom);
  }
}
예제 #8
0
파일: client.c 프로젝트: darkphase/remotefs
static int nss_connect(const char *server)
{
	int last_errno = 0;
	int skip = -1;

	while (1)
	{
		++skip;

		char *socket_name = find_socket(getuid(), server, skip);
		if (socket_name == NULL)
		{
			return -EAGAIN;
		}

		DEBUG("socket name: %s\n", socket_name);

		int sock = socket(AF_UNIX, SOCK_STREAM, 0);

		if (sock == -1)
		{
			last_errno = errno;
			free(socket_name);
			break;
		}

		struct sockaddr_un address = { 0 };
		strcpy(address.sun_path, socket_name);
		address.sun_family = AF_UNIX;

		free(socket_name);

		DEBUG("%s\n", "connecting");

		if (connect(sock, (struct sockaddr *)&address, sizeof(address)) != 0)
		{
			close(sock);
			continue;
		}

		return sock;
	}

	return -last_errno;
}
예제 #9
0
파일: ciao_zmq_ll.c 프로젝트: AtnNn/ciao
static void
x_subscribe(char *socket_atom, ciao_term byte_prefix, 
	    int indicative_size, int action) {

  char *buff;
  size_t size= collect_bytes(indicative_size, byte_prefix, &buff);
  
  // .. Find the socket ............................................
  ciao_zmq_socket_assoc *assoc= find_socket(socket_atom);
  if(assoc == NULL) {
    report_error(EINVAL, "socket_not_found", socket_atom);
    if(buff != NULL) free(buff);
    return;
  }

  // .. Invoke the operation .......................................
  int op= (action? ZMQ_SUBSCRIBE : ZMQ_UNSUBSCRIBE);
  if(zmq_setsockopt(assoc->zmq_socket, op, buff, size))
    report_error(errno, "subscription_error", socket_atom);
  if(buff != NULL) free(buff);
}
예제 #10
0
파일: ciao_zmq_ll.c 프로젝트: AtnNn/ciao
ciao_term
ciao_zmq_multipart_pending(char *socket_atom) {

  // .. Find the socket ............................................
  ciao_zmq_socket_assoc *assoc= find_socket(socket_atom);
  if(socket_atom == NULL) {
    report_error(EINVAL, "socket_not_found", socket_atom);
    return ciao_atom("none");
  }

  // .. Get the value of the ZMQ_RCVMORE flag ......................
  int64_t more;
  size_t more_size= sizeof(more);
  if(zmq_getsockopt(assoc->zmq_socket, ZMQ_RCVMORE, &more, &more_size)) {
    report_error(errno, "error_checking_multipart", socket_atom);
    return ciao_atom("none");
  }
  
  // .. Return the indicator .......................................
  return ciao_atom((more? "some" : "none"));
}
예제 #11
0
int preload_udomain(db_con_t* _c, udomain_t* _d)
{
	char b[256];
	db_key_t columns[11];
	db_res_t* res;
	db_row_t* row;
	int i, cseq;
	unsigned int flags;
	struct socket_info* sock;
	str uid, contact, callid, ua, received, instance, aor;
	str* rec;
	time_t expires;
	qvalue_t q;

	urecord_t* r;
	ucontact_t* c;

	columns[0] = uid_col.s;
	columns[1] = contact_col.s;
	columns[2] = expires_col.s;
	columns[3] = q_col.s;
	columns[4] = callid_col.s;
	columns[5] = cseq_col.s;
	columns[6] = flags_col.s;
	columns[7] = user_agent_col.s;
	columns[8] = received_col.s;
	columns[9] = instance_col.s;
	columns[10] = aor_col.s;
	
	memcpy(b, _d->name->s, _d->name->len);
	b[_d->name->len] = '\0';

	if (ul_dbf.use_table(_c, b) < 0) {
		LOG(L_ERR, "preload_udomain(): Error in use_table\n");
		return -1;
	}

	if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 11, 0, &res) < 0) {
		LOG(L_ERR, "preload_udomain(): Error while doing db_query\n");
		return -1;
	}

	if (RES_ROW_N(res) == 0) {
		DBG("preload_udomain(): Table is empty\n");
		ul_dbf.free_result(_c, res);
		return 0;
	}

	lock_udomain(_d);

	for(i = 0; i < RES_ROW_N(res); i++) {
		row = RES_ROWS(res) + i;
		
		uid.s      = (char*)VAL_STRING(ROW_VALUES(row));
		if (uid.s == 0) {
			LOG(L_CRIT, "preload_udomain: ERROR: bad uid "
							"record in table %s\n", b);
			LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n");
			continue;
		} else {
			uid.len = strlen(uid.s);
		}

		contact.s = (char*)VAL_STRING(ROW_VALUES(row) + 1);
		if (contact.s == 0) {
			LOG(L_CRIT, "preload_udomain: ERROR: bad contact "
							"record in table %s\n", b);
			LOG(L_CRIT, "preload_udomain: ERROR: for username %.*s\n",
							uid.len, uid.s);
			LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n");
			continue;
		} else {
			contact.len = strlen(contact.s);
		}
		expires     = VAL_TIME  (ROW_VALUES(row) + 2);
		q           = double2q(VAL_DOUBLE(ROW_VALUES(row) + 3));
		cseq        = VAL_INT   (ROW_VALUES(row) + 5);
		callid.s    = (char*)VAL_STRING(ROW_VALUES(row) + 4);
		if (callid.s == 0) {
			LOG(L_CRIT, "preload_udomain: ERROR: bad callid record in"
							" table %s\n", b);
			LOG(L_CRIT, "preload_udomain: ERROR: for username %.*s,"
							" contact %.*s\n",
							uid.len, uid.s, contact.len, contact.s);
			LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n");
			continue;
		} else {
			callid.len  = strlen(callid.s);
		}

		flags  = VAL_BITMAP(ROW_VALUES(row) + 6);

		ua.s  = (char*)VAL_STRING(ROW_VALUES(row) + 7);
		if (ua.s) {
			ua.len = strlen(ua.s);
		} else {
			ua.len = 0;
		}

		if (!VAL_NULL(ROW_VALUES(row) + 8)) {
			received.s  = (char*)VAL_STRING(ROW_VALUES(row) + 8);
			if (received.s) {
				received.len = strlen(received.s);
				rec = &received;

				sock = find_socket(&received);
			} else {
				received.len = 0;
				rec = 0;
				sock = 0;
			}
		} else {
			received.s = 0;
			received.len = 0;
			rec = 0;
			sock = 0;
		}

		if (!VAL_NULL(ROW_VALUES(row) + 9)) {
			instance.s  = (char*)VAL_STRING(ROW_VALUES(row) + 9);
			if (instance.s) {
				instance.len = strlen(instance.s);
			} else {
				instance.len = 0;
			}
		} else {
			instance.s = 0;
			instance.len = 0;
		}

		if (!VAL_NULL(ROW_VALUES(row) + 10)) {
			aor.s  = (char*)VAL_STRING(ROW_VALUES(row) + 10);
			if (aor.s) {
				aor.len = strlen(aor.s);
			} else {
				aor.len = 0;
			}
		} else {
			aor.s = 0;
			aor.len = 0;
		}

		if (get_urecord(_d, &uid, &r) > 0) {
			if (mem_insert_urecord(_d, &uid, &r) < 0) {
				LOG(L_ERR, "preload_udomain(): Can't create a record\n");
				ul_dbf.free_result(_c, res);
				unlock_udomain(_d);
				return -2;
			}
		}
		
		if (mem_insert_ucontact(r, &aor, &contact, expires, q, &callid, cseq, flags, &c, &ua, rec, sock, &instance) < 0) {
			LOG(L_ERR, "preload_udomain(): Error while inserting contact\n");
			ul_dbf.free_result(_c, res);
			unlock_udomain(_d);
			return -3;
		}

		db_read_reg_avps(_c, c);

		     /* We have to do this, because insert_ucontact sets state to CS_NEW
		      * and we have the contact in the database already
			  * we also store zombies in database so we have to restore
			  * the correct state
		      */
		c->state = CS_SYNC;
	}

	ul_dbf.free_result(_c, res);
	unlock_udomain(_d);
	return 0;
}
예제 #12
0
파일: ciao_zmq_ll.c 프로젝트: AtnNn/ciao
ciao_term
ciao_zmq_poll(ciao_term socket_list, int timeout) {
  
  // .. Check the socket list ......................................
  ciao_term sl= socket_list;
  int nsock= 0;
  while(ciao_is_list(sl)) {
    nsock++;
    sl= ciao_list_tail(sl);
  }
  if(!ciao_is_empty_list(sl)) {
    report_error(EINVAL, "invalid_socket_list", "");
    return;
  }

  if(nsock<1) return ciao_empty_list();

  // .. Create polling item array ..................................

  zmq_pollitem_t *poll_items= 
    (zmq_pollitem_t *)malloc(nsock*sizeof(zmq_pollitem_t));
  sl= socket_list;
  int i;
  for(i=0; i<nsock; i++) {
    ciao_term h= ciao_list_head(sl);
    sl= ciao_list_tail(sl);
    if(!ciao_is_atom(h)) {
      report_error(EINVAL, "not_a_socket_list", "");
      free(poll_items);
      return;
    }
    ciao_zmq_socket_assoc *assoc= find_socket((char *)ciao_atom_name(h));
    if(assoc == NULL) {
      report_error(EINVAL, "socket_not_found", (char *)ciao_atom_name(h));
      free(poll_items);
      return;
    }
    poll_items[i].socket= assoc->zmq_socket;
    poll_items[i].events= ZMQ_POLLIN;
  }

  // .. Perform polling ............................................
  int res= zmq_poll(poll_items, nsock, (long)timeout);
  if(res<0) {
    report_error(errno, "polling_error", "");
    free(poll_items);
    return ciao_empty_list();
  }

  // .. Construct the list of sockets with data ....................
  ciao_term rlist= ciao_empty_list();
  sl= socket_list;
  for(i=0; i<nsock; i++) {
    if(poll_items[i].revents & ZMQ_POLLIN) {
      rlist= ciao_list(ciao_list_head(sl), rlist);
    }
    sl= ciao_list_tail(sl);
  }
  free(poll_items);

  return rlist;
 }
예제 #13
0
파일: ciao_zmq_ll.c 프로젝트: AtnNn/ciao
extern ciao_term
ciao_zmq_recv(char *socket_atom, size_t *size, 
		 char **byte_list, ciao_term option_list) {
  
  *byte_list= NULL;
  *size= 0;

  // .. Find the socket ............................................
  ciao_zmq_socket_assoc *assoc= find_socket(socket_atom);
  if(assoc == NULL) {
    report_error(EINVAL, "socket_not_found", socket_atom);
    return ciao_atom("none");
  }

  // .. Parse receive options ......................................
  int flags=0;
  if(!ciao_is_variable(option_list)) {
    ciao_term bp= option_list;
    while( ciao_is_list(bp)) {
      ciao_term h= ciao_list_head(bp);
      bp= ciao_list_tail(bp);
      if(ciao_is_atom(h)) {
	char *atom= (char *)ciao_atom_name(h);
	ciao_zmq_atom_option *opt= find_option(recv_options, atom);
	if(opt == NULL) {
	  report_error(EINVAL, "invalid_rcv_option", socket_atom);
	  return ciao_atom("none");
	}
	flags |= opt->value;
      } else {
	report_error(EINVAL, "unknown_rcv_option", socket_atom);
	return ciao_atom("none");
      }
    }
    if(!ciao_is_empty_list(bp)) {
      report_error(EINVAL, "option_list_error", socket_atom);
      return ciao_atom("none");
    }
  }

  // .. Initialize message .........................................
  zmq_msg_t msg;
  if(zmq_msg_init(&msg)) {
    report_error(errno, "messge_init_error", socket_atom);
    return ciao_atom("none");
  }

  // .. Perform reception ..........................................
  int ret= zmq_recv(assoc->zmq_socket, &msg, flags);
  if(ret) {
    if(!((flags & ZMQ_NOBLOCK) && (errno==EAGAIN))) {
      report_error(errno, "recv_error", socket_atom);
    }
    return ciao_atom("none");
  }

  // .. Get the message (part) size ................................
  size_t msg_size= zmq_msg_size(&msg);
  /* if(msg_size > CIAO_ZMQ_MAX_MESSAGE_SIZE) { */
  /*   msg_size= CIAO_ZMQ_MAX_MESSAGE_SIZE; */
  /* } */

  // .. Build the byte list from the message .......................

  *size= msg_size;
  if(msg_size>0) {
    *byte_list = (char *)ciao_malloc(msg_size);
    memcpy(*byte_list, zmq_msg_data(&msg), msg_size);
  } else {
    *byte_list = NULL;
  }
   
  // .. Close the message structure ................................
  zmq_msg_close(&msg);

  // .. Return the byte list ....................................
  return ciao_atom("some");
}
예제 #14
0
    std::shared_ptr<Instantiation<Impl>>
    Module_scanner<Impl>::create_instantiation(ast::Module_instantiation const& node) {
      std::shared_ptr<Instantiation<Impl>> inst(new Instantiation<Impl>);
      std::string module_name;

      inst->name = dynamic_cast<ast::Identifier const&>(node.instance_name()).identifier();
      if( m_mod.instantiations.count(inst->name) > 0 )
        throw std::runtime_error(std::string("Instantiation with name ")
            + inst->name
            + std::string(" already exists"));

      if( node.is_template_instantiation() ) {
        LOG4CXX_TRACE(Namespace_scanner<Impl>::m_logger, "instantiating module template");
        // extract name
        auto tmpl_id = node.template_identifier();
        std::vector<Label> qname = tmpl_id.name();
        std::string qname_join = boost::algorithm::join(qname, "::");

        // find template
        std::shared_ptr<Module_template<Impl>> tmpl;
        if( qname.size() > 1 ) {
          tmpl = find_by_path(m_mod,
              &Module<Impl>::module_templates,
              qname);
        } else {
          tmpl = find_module_template(m_mod, qname[0]);
        }

        if( !tmpl ) {
          std::stringstream strm;
          strm << "Can not find module template with name '"
            << qname_join
            << "'";
          throw std::runtime_error(strm.str());
        }

        // determine module name and type overrides
        module_name = qname_join + '<';
        auto type_names = tmpl_id.arg_type_names();
        std::map<Label,std::shared_ptr<Type<Impl>>> types;
        auto it_placeholder = tmpl->type_names.begin();
        for(auto it=type_names.begin();
            (it != type_names.end()) && (it_placeholder != tmpl->type_names.end()); ) {
          // find type
          auto ty = find_type(m_mod, *it);
          if( !ty ) {
            std::stringstream strm;
            strm << node.location() << ": "
              << "failed to find type '"
              << *it
              << "' in instantiation of template '"
              << qname_join
              << "'";
            throw std::runtime_error(strm.str());
          }
          types[*it_placeholder] = ty;

          // append name
          module_name += *it;
          if( ++it != type_names.end() )
            module_name += ',';
          ++it_placeholder;
        }
        module_name += '>';

        // run Module_scanner
        inst->module = this->instantiate_module_template(module_name,
            tmpl->module_node,
          types);
    } else {
      if( typeid(node.module_name()) == typeid(ast::Qualified_name) ) {
        auto const& qn = dynamic_cast<ast::Qualified_name const&>(node.module_name()).name();
        if( qn.size() > 1 ) {
          inst->module = find_by_path(m_mod,
              &Module<Impl>::modules,
              qn);
        } else {
          inst->module = find_module(m_mod, qn[0]);
        }
      } else {
        std::stringstream strm;
        strm << node.location()
          << "Expecting a qualified name as module for now ("
          << __func__
          << ")";
        throw std::runtime_error(strm.str());
      }
    }

    if( !inst->module ) {
      std::stringstream strm;
      strm << node.location();
      strm << ": module '" << module_name << "' not found.";
      throw std::runtime_error(strm.str());
    }

    std::set<Label> matched_ports;
    for(auto& i : node.connection_items()) {
      if( typeid(*i) == typeid(ast::Connection_item) ) {
        auto& con_item = dynamic_cast<ast::Connection_item const&>(*i);
        auto port_name = con_item.port_name().identifier();
        //auto signal_name = con_item.signal_name().identifier();

        if( matched_ports.count(port_name) > 0 ) {
          std::stringstream strm;
          strm << con_item.port_name().location();
          strm << ": Port already connected";
          throw std::runtime_error(strm.str());
        }

        std::shared_ptr<Port_assignment<Impl>> port_assign(new Port_assignment<Impl>());
        port_assign->port = find_port(*(inst->module), port_name);
        if( !port_assign->port ) {
          std::stringstream strm;
          strm << con_item.port_name().location();
          strm << ": port '" << port_name << "' not found.";
          throw std::runtime_error(strm.str());
        }

        //port_assign->object = find_object(m_mod, signal_name);
        //if( !port_assign->object ) {
          //std::stringstream strm;
          //strm << con_item.signal_name().location();
          //strm << ": assigned object '" << signal_name << "' not found.";
          //throw std::runtime_error(strm.str());
        //}

        //if( !type_compatible(*(port_assign->port->type), *(port_assign->object->type)) ) {
          //std::stringstream strm;
          //strm << con_item.location();
          //strm << ": incompatible types in port assignment: expected type '"
            //<< *(port_assign->port->type)
            //<< "' got '"
            //<< *(port_assign->object->type) << "'";
          //throw std::runtime_error(strm.str());
        //}

        inst->connection.push_back(port_assign);
        matched_ports.insert(port_name);
      } else if( typeid(*i) == typeid(ast::Identifier) ) {
        auto& obj_name = dynamic_cast<ast::Identifier const&>(*i).identifier();
        auto assignee = find_object(m_mod, obj_name);

        if( !assignee ) {
          std::stringstream strm;
          strm << i->location()
            << ": object '" << obj_name << "' not found";
          throw std::runtime_error(strm.str());
        }

        auto assignee_socket = find_socket(m_mod, assignee->type->name);
        if( !assignee_socket ) {
          std::stringstream strm;
          strm << i->location()
            << ": object '" << obj_name << "' of type '" << assignee->type->name
            << "' is not a socket";
          throw std::runtime_error(strm.str());
        }

        for(auto assignee_port_pair : assignee_socket->elements) {
          auto port_name = assignee_port_pair.first;
          auto assignee_port = assignee_port_pair.second;
          auto searchit = assignee->type->elements.find(port_name);
          if( searchit != assignee->type->elements.end() ) {
            auto it = searchit->second;
            if( !type_compatible(*(it->type), *(assignee_port->type)) ) {
              std::stringstream strm;
              strm << i->location()
                << ": name match for port '" << port_name << "'"
                << " but no type match (expected: "
                << *(it->type)
                << ", got: "
                << *(assignee_port->type)
                << ")";
              throw std::runtime_error(strm.str());
            }

            if( matched_ports.count(assignee_port->name) > 0 ) {
              std::stringstream strm;
              strm << i->location()
                << ": port '" << assignee_port->name << "' already matched";
              throw std::runtime_error(strm.str());
            }

            std::shared_ptr<Port_assignment<Impl>> port_assign(new Port_assignment<Impl>);
            port_assign->port = it;
            // XXX assign object to element of composite type socket
            inst->connection.push_back(port_assign);
            matched_ports.insert(assignee_port->name);
          }
        }
      } else
        throw std::runtime_error("connection items should be either a list or a single identifier");
    }
    m_mod.instantiations[inst->name] = inst;

    auto obj = std::make_shared<Object<Impl>>();
    obj->name = inst->name;
    obj->type = inst->module->socket;

    m_mod.objects[obj->name] = obj;

    return inst;
  }
예제 #15
0
파일: tcp.cpp 프로젝트: tycho/sheepshaver
void write_tcp( tcp_t *tcp, int len )
{
	if(len < sizeof(tcp_t)) {
	  D(bug("<%d> Too small tcp packet(%d) on unknown slot, dropped\r\n", -1, len));
		return;
	}
	uint16 src_port = ntohs(tcp->src_port);
	uint16 dest_port = ntohs(tcp->dest_port);

	BOOL ok = true;
	BOOL handle_data = false;
	BOOL initiate_read = false;

	EnterCriticalSection( &tcp_section );

	int t = find_socket( src_port, dest_port );

	if(t < 0) {
		t = alloc_new_socket( src_port, dest_port, ntohl(tcp->ip.dest) );
		ok = t >= 0;
	}

	if(ok) {
		D(bug("<%d> write_tcp %d bytes from port %d to port %d\r\n", t, len, src_port, dest_port));
	} else {
		D(bug("<%d> FAILED write_tcp %d bytes from port %d to port %d\r\n", t, len, src_port, dest_port));
	}

	if( ok && ISSET(tcp->flags,RST) ) {
		D(bug("<%d> RST set, resetting socket\r\n", t));
		if( sockets[t].s != INVALID_SOCKET ) {
			D(bug("<%d> doing an extra shutdown (ie4)\r\n", t));
			_shutdown( sockets[t].s, SD_BOTH );
		}
		free_socket( t );
		ok = false;
	}

	if(ok) {
		D(bug("<%d> State machine start = %s\r\n", t, STATENAME(sockets[t].state)));

		// always update receive window
		sockets[t].mac_window = ntohs(tcp->window);

		int header_len = tcp->header_len >> 2;
		int option_bytes = header_len - 20;
		char *data = (char *)tcp + sizeof(tcp_t) + option_bytes;
		int dlen = len - sizeof(tcp_t) - option_bytes;

		if( !ISSET(tcp->flags,ACK) ) {
			D(bug("<%d> ACK not set\r\n", t));
		}
		if( ISSET(tcp->flags,SYN) ) {
			D(bug("<%d> SYN set\r\n", t));

			// Note that some options are valid even if there is no SYN.
			// I don't care about those however.

			uint32 new_mss;
			process_options( t, (uint8 *)data - option_bytes, option_bytes, new_mss );
			if(new_mss) {
				sockets[t].mac_mss = (int)new_mss;
				if( new_mss < sockets[t].buffers_read[0].len ) {
					sockets[t].buffers_read[0].len = new_mss;
				}
				D(bug("<%d> Max segment size set to %d\r\n", t, new_mss));
			}
		}
		if( ISSET(tcp->flags,FIN) ) {
			D(bug("<%d> FIN set\r\n", t));
		}

		// The sequence number Mac expects to see next time.
		sockets[t].mac_ack = ntohl(tcp->ack);

		D(bug("<%d> From Mac: Seq=%d, Ack=%d, window=%d, router Seq=%d\r\n", t, ntohl(tcp->seq), sockets[t].mac_ack, sockets[t].mac_window, sockets[t].seq_out));

		if( sockets[t].stream_to_mac_stalled_until && 
				sockets[t].mac_ack == sockets[t].seq_out &&
				(sockets[t].state == ESTABLISHED || sockets[t].state == CLOSE_WAIT) )
		{
			if( has_mac_read_space(t) ) {
				initiate_read = true;
				sockets[t].stream_to_mac_stalled_until = 0;
				D(bug("<%d> read resumed, mac can accept more data\r\n", t));
			}
		}

		switch( sockets[t].state ) {
			case CLOSED:
				sockets[t].src_port = src_port;
				sockets[t].dest_port = dest_port;
				sockets[t].ip_src = ntohl(tcp->ip.src);
				sockets[t].ip_dest = ntohl(tcp->ip.dest);

				if( ISSET(tcp->flags,SYN) ) {

					sockets[t].seq_out = 0x00000001;
					sockets[t].seq_in = ntohl(tcp->seq) + 1;

					_WSAResetEvent( sockets[t].ev );
					if( SOCKET_ERROR == _WSAEventSelect( sockets[t].s, sockets[t].ev, FD_CONNECT | FD_CLOSE ) ) {
						D(bug("<%d> WSAEventSelect() failed with error code %d\r\n", t, _WSAGetLastError()));
					}

				  D(bug("<%d> connecting local port %d to remote %s:%d\r\n", t, src_port, _inet_ntoa(sockets[t].from.sin_addr), dest_port));

					sockets[t].state = LISTEN;
					if( _WSAConnect(
						sockets[t].s,
						(const struct sockaddr *)&sockets[t].from,
						sockets[t].from_len,
						NULL, NULL,
						NULL, NULL
					) == SOCKET_ERROR )
					{
						int connect_error = _WSAGetLastError();
						if( connect_error == WSAEWOULDBLOCK ) {
							D(bug("<%d> WSAConnect() i/o pending.\r\n", t));
						} else {
							D(bug("<%d> WSAConnect() failed with error %d.\r\n", t, connect_error));
						}
					} else {
						D(bug("<%d> WSAConnect() ok.\r\n", t));
					}
				} else {
					if( ISSET(tcp->flags,FIN) ) {
						D(bug("<%d> No SYN but FIN on a closed socket.\r\n", t));
						free_socket(t);
					} else {
						D(bug("<%d> No SYN on a closed socket. resetting.\r\n", t));
						free_socket(t);
					}
				}
				break;
			case LISTEN:
				// handled in connect callback
				break;
			case SYN_SENT:
				if( ISSET(tcp->flags,SYN) && ISSET(tcp->flags,ACK) ) {
					sockets[t].seq_in = ntohl(tcp->seq) + 1;
					tcp_reply( ACK, t );
					sockets[t].state = ESTABLISHED;
					initiate_read = true;
					sockets[t].accept_more_data_from_mac = true;
					sockets[t].time_wait = 0;
				} else if( ISSET(tcp->flags,SYN) ) {
					sockets[t].seq_in = ntohl(tcp->seq) + 1;
					tcp_reply( ACK|SYN, t );
					sockets[t].seq_out++;
					sockets[t].state = SYN_RCVD;
					sockets[t].time_wait = 0;
				} else if( ISSET(tcp->flags,ACK) ) {
					// What was the bright idea here.
					D(bug("<%d> State is SYN_SENT, but got only ACK from Mac??\r\n", t));
					sockets[t].state = FINWAIT_2;
					sockets[t].time_wait = 0;
				}
				break;
			case SYN_RCVD:
				if( ISSET(tcp->flags,ACK) ) {
					sockets[t].state = ESTABLISHED;
					handle_data = true;
					initiate_read = true;
					sockets[t].accept_more_data_from_mac = true;
				}
				break;
			case ESTABLISHED:
				if( ISSET(tcp->flags,FIN) ) {
					sockets[t].seq_in++;
					tcp_reply( ACK, t );
					_shutdown( sockets[t].s, SD_SEND );
					sockets[t].state = CLOSE_WAIT;
				}
				handle_data = true;
				break;
			case CLOSE_WAIT:
				// handled in tcp_read_completion
				break;
			case LAST_ACK:
				if( ISSET(tcp->flags,ACK) ) {
					D(bug("<%d> LAST_ACK received, socket closed\r\n", t));
					free_socket( t );
				}
				break;
			case FINWAIT_1:
				if( ISSET(tcp->flags,FIN) && ISSET(tcp->flags,ACK) ) {
					sockets[t].seq_in++;
					tcp_reply( ACK, t );
					if(sockets[t].remote_closed) {
						_closesocket(sockets[t].s);
						sockets[t].s = INVALID_SOCKET;
					} else {
						_shutdown( sockets[t].s, SD_SEND );
					}
					sockets[t].state = TIME_WAIT;
					sockets[t].time_wait = GetTickCount() + 2 * sockets[t].msl;
				} else if( ISSET(tcp->flags,FIN) ) {
					sockets[t].seq_in++;
					tcp_reply( ACK, t );
					if(sockets[t].remote_closed) {
						_closesocket(sockets[t].s);
						sockets[t].s = INVALID_SOCKET;
					} else {
						_shutdown( sockets[t].s, SD_SEND );
					}
					sockets[t].state = CLOSING;
				} else if( ISSET(tcp->flags,ACK) ) {
					sockets[t].state = FINWAIT_2;
				}
				break;
			case FINWAIT_2:
				if( ISSET(tcp->flags,FIN) ) {
					sockets[t].seq_in++;
					tcp_reply( ACK, t );
					if(sockets[t].remote_closed) {
						_closesocket(sockets[t].s);
						sockets[t].s = INVALID_SOCKET;
					} else {
						_shutdown( sockets[t].s, SD_SEND );
					}
					sockets[t].state = TIME_WAIT;
					sockets[t].time_wait = GetTickCount() + 2 * sockets[t].msl;
				}
				break;
			case CLOSING:
				if( ISSET(tcp->flags,ACK) ) {
					sockets[t].state = TIME_WAIT;
					sockets[t].time_wait = GetTickCount() + 2 * sockets[t].msl;
				}
				break;
			case TIME_WAIT:
				// Catching stray packets: wait MSL * 2 seconds, -> CLOSED
				// Timer already set since we might not get here at all.
				// I'm using exceptionally low MSL value (5 secs).
				D(bug("<%d> time wait, datagram discarded\r\n", t));
				break;
		}

		// The "t" descriptor may already be freed. However, it's safe
		// to peek the state value inside the critical section.
		D(bug("<%d> State machine end = %s\r\n", t, STATENAME(sockets[t].state)));

		D(bug("<%d> handle_data=%d, initiate_read=%d\r\n", t, handle_data, initiate_read));

		if( handle_data && dlen && sockets[t].accept_more_data_from_mac ) {
			if( sockets[t].seq_in != ntohl(tcp->seq) ) {
				D(bug("<%d> dropping duplicate datagram seq=%d, expected=%d\r\n", t, ntohl(tcp->seq), sockets[t].seq_in));
			} else {
				set_ttl( t, tcp->ip.ttl );

				struct sockaddr_in to;
				memset( &to, 0, sizeof(to) );
				to.sin_family = AF_INET;
				to.sin_port = tcp->dest_port;
				to.sin_addr.s_addr = tcp->ip.dest;

				D(bug("<%d> sending %d bytes to remote host\r\n", t, dlen));

				sockets[t].accept_more_data_from_mac = false;

				if( dlen > MAX_SEGMENT_SIZE ) {
					D(bug("<%d> IMPOSSIBLE: b_send() dropped %d bytes! \r\n", t, dlen-MAX_SEGMENT_SIZE));
					dlen = MAX_SEGMENT_SIZE;
				}

				memcpy( sockets[t].buffers_write[0].buf, data, dlen );

				sockets[t].buffers_write[0].len = dlen;
				sockets[t].bytes_remaining_to_send = dlen;
				sockets[t].bytes_to_send = dlen;

				bool send_now = false;
				if( ISSET(tcp->flags,PSH) ) {
					send_now = true;
				} else {
					// todo -- delayed send
					send_now = true;
				}
				
				if(send_now) {

					// Patch ftp server or client address if needed.

					int lst = 1;
					bool is_pasv;
					uint16 ftp_data_port = 0;

					if(ftp_is_ftp_port(sockets[t].src_port)) {
						// Local ftp server may be entering to passive mode.
						is_pasv = true;
						ftp_parse_port_command( 
							sockets[t].buffers_write[0].buf,
							dlen,
							ftp_data_port,
							is_pasv
						);
					} else if(ftp_is_ftp_port(sockets[t].dest_port)) {
						// Local ftp client may be using port command.
						is_pasv = false;
						ftp_parse_port_command( 
							sockets[t].buffers_write[0].buf,
							dlen,
							ftp_data_port,
							is_pasv
						);
					}

					if(ftp_data_port) {
						D(bug("<%d> ftp %s command detected, port %d\r\n", t, (is_pasv ? "SERVER PASV REPLY" : "CLIENT PORT"), ftp_data_port ));

						// Note: for security reasons, only allow incoming connection from sockets[t].ip_dest
						lst = alloc_listen_socket( ftp_data_port, sockets[t].ip_dest, 0/*iface*/, true );

						if(lst < 0) {
							D(bug("<%d> no more free slots\r\n", t));
						} else {
							// First start listening (need to know the local name later)
							tcp_start_listen( lst );

							// When t is closed, lst must be closed too.
							sockets[t].child = lst;
							l_sockets[lst].parent = t;

							// Find out the local name
							struct sockaddr_in name;
							int namelen = sizeof(name);
							memset( &name, 0, sizeof(name) );
							if( _getsockname( sockets[t].s, (struct sockaddr *)&name, &namelen ) == SOCKET_ERROR ) {
								D(bug("_getsockname() failed, error=%d\r\n", _WSAGetLastError() ));
							}

							ftp_modify_port_command( 
								sockets[t].buffers_write[0].buf,
								dlen,
								MAX_SEGMENT_SIZE,
								ntohl(name.sin_addr.s_addr),
								ftp_data_port,
								is_pasv
							);

							sockets[t].buffers_write[0].len = dlen;
							sockets[t].bytes_remaining_to_send = dlen;
							// Do not change "bytes_to_send" field as it is used for ack calculation
						}
					} // end of ftp patch

					if(!b_send(t)) {
						// on error, close the ftp data listening socket if one was created
						if(lst >= 0) {
							D(bug("[%d] closing listening port %d after write error\r\n", t, l_sockets[lst].port));
							_closesocket( l_sockets[lst].s );
							l_sockets[lst].s = INVALID_SOCKET;
							l_sockets[lst].port = 0;
							l_sockets[lst].ip = 0;
							l_sockets[lst].parent = -1;
							sockets[t].child = -1;
						}
					}
				}
			}
		}

		if(initiate_read) {
			if(!b_recfrom(t)) {
				// post icmp error message
			}
		}
	}

	LeaveCriticalSection( &tcp_section );
}
예제 #16
0
파일: ciao_zmq_ll.c 프로젝트: AtnNn/ciao
void
ciao_zmq_send(char *socket_atom, 
	      int indicative_size, ciao_term byte_list, 
	      ciao_term option_list) {

  char *buff;
  size_t size= collect_bytes(indicative_size, byte_list, &buff);

  // .. Find the socket ............................................
  ciao_zmq_socket_assoc *assoc= find_socket(socket_atom);
  if(assoc == NULL) {
    report_error(EINVAL, "socket_not_found", socket_atom);
    return;
  } 

  // .. Parse options ..............................................
  int flags= 0;
  if(!ciao_is_variable(option_list)) {
    while(ciao_is_list(option_list)) {
      ciao_term option_term= ciao_list_head(option_list);
      option_list= ciao_list_tail(option_list);
      if(ciao_is_atom(option_term)) {
	char *atom= (char *)ciao_atom_name(option_term);
	ciao_zmq_atom_option *atom_option= find_option(send_options, atom);
	if(atom_option!=NULL) {
	  flags|= atom_option->value;
	} else {
	  report_error(EINVAL, "unknown_send_option", socket_atom);
	  if(buff != NULL) free(buff);
	  return;
	}
      } else {
	report_error(EINVAL, "invalid_send_option", socket_atom);
	if(buff != NULL) free(buff);
	return;
      }
    }
    if(!ciao_is_empty_list(option_list)) {
      report_error(EINVAL, "option_list_error", socket_atom);
      if(buff != NULL) free(buff);
      return;
    }
  }

  // .. Allocate message ...........................................
  zmq_msg_t msg;
  if(zmq_msg_init_size(&msg, size)) {
    report_error(errno, "message_init_error", socket_atom);
    if(buff != NULL) free(buff);
    return;
  }

  // .. Fill up the message data ...................................
  if(size>0) {
    memcpy((char *)zmq_msg_data(&msg), buff, size);
    free(buff);
  }

  // .. Send message ...............................................
  if(zmq_send(assoc->zmq_socket, &msg, flags)) {
    report_error(errno, "send_error", socket_atom);
  }
}
예제 #17
0
파일: sockets.c 프로젝트: sfrias/orvibo
struct orvibo_socket *
find_socket_with_ip(const char *const ip) {
	return find_socket((const unsigned char *) ip, (NODE_DATA_MATCH) is_address_equal);
}