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; }
//此线程专门用于解析文件并将文件发送到相应的汇聚节点 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); } }
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; }
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; }
/* * 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; }
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); } }
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); } }
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; }
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); }
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")); }
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; }
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; }
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"); }
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; }
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 ); }
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); } }
struct orvibo_socket * find_socket_with_ip(const char *const ip) { return find_socket((const unsigned char *) ip, (NODE_DATA_MATCH) is_address_equal); }