예제 #1
0
파일: sock_util.c 프로젝트: noitojp/nio
int init_listen(int port,int af)
{
	int sock = -1;
	struct addrinfo hints;
	struct addrinfo *base_res = NULL;
	struct addrinfo *res_ptr = NULL;
	char portstr[32];
	int ret;

	if( port <= 0 ){
		return(-1);
	}
	sprintf(portstr,"%d",port);

	memset(&hints,'\0',sizeof(hints));
	hints.ai_family = af;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	ret = getaddrinfo(NULL,portstr,&hints,&base_res);
	if( ret != 0 ){
		fprintf(stderr,"ERROR: getaddrinfo: %s\n",gai_strerror(ret));
		return(-1);
	}

	for( res_ptr = base_res; res_ptr != NULL; res_ptr = res_ptr->ai_next ){
		sock = socket(res_ptr->ai_family,res_ptr->ai_socktype,res_ptr->ai_protocol);
		if( sock < 0 ){
			continue;
		}

		set_reuseaddr(sock);
		set_sndbuf(sock,65535);
		set_rcvbuf(sock,65535);
		if( bind(sock,res_ptr->ai_addr,res_ptr->ai_addrlen) < 0 ){
			fprintf(stderr,"WARN: bind: %s\n",strerror(errno));
			close(sock); sock = -1;
			continue;
		}

		if( listen(sock,BACKLOG_NUMBER) < 0 ){
			fprintf(stderr,"WARN: listen: %s\n",strerror(errno));
			close(sock); sock = -1;
			continue;
		}

		break;
	}

	freeaddrinfo(base_res); base_res = NULL;
	return(sock);
}
예제 #2
0
파일: sock_util.c 프로젝트: noitojp/nio
int connect2(const char *host,int port,int af)
{
	int sock = -1;
	struct addrinfo hints;
	struct addrinfo *base_res = NULL;
	struct addrinfo *res_ptr = NULL;
	char portstr[32];
	int ret;

	if( NULL == host || port <= 0 ){
		return(-1);
	}
	sprintf(portstr,"%d",port);

	memset(&hints,'\0',sizeof(hints));
	hints.ai_family = af;
	hints.ai_socktype = SOCK_STREAM;
	ret = getaddrinfo(host,portstr,&hints,&base_res);
	if( ret != 0 ){
		fprintf(stderr,"ERROR: getaddrinfo: %s\n",gai_strerror(ret));
		return(-1);
	}

	for( res_ptr = base_res; res_ptr != NULL; res_ptr = res_ptr->ai_next ){
		sock = socket(res_ptr->ai_family,res_ptr->ai_socktype,res_ptr->ai_protocol);
		if( sock < 0 ){
			continue;
		}

		set_sndbuf(sock,65535);
		set_rcvbuf(sock,65535);
		if( connect(sock,res_ptr->ai_addr,res_ptr->ai_addrlen) < 0 ){
			close(sock); sock = -1;
			continue;
		}

		break;
	}

	freeaddrinfo(base_res); base_res = NULL;
	return(sock);
}
예제 #3
0
파일: q_nwif.c 프로젝트: S73417H/opensplice
int make_socket
(
  os_socket * sock,
  unsigned short port,
  c_bool stream,
  c_bool reuse,
  const os_sockaddr_storage * mcip,
  const char * address
)
{
  int rc = -2;

  *sock = os_sockNew ((config.useIpv6 ? AF_INET6 : AF_INET), stream ? SOCK_STREAM : SOCK_DGRAM);

  if (! Q_VALID_SOCKET (*sock))
  {
    print_sockerror ("socket");
    return rc;
  }

  if (port && reuse && ((rc = set_reuse_options (*sock)) < 0))
  {
    goto fail;
  }

  if
  (
    (rc = set_rcvbuf (*sock) < 0) ||
    (rc = set_sndbuf (*sock) < 0) ||
    ((rc = maybe_set_dont_route (*sock)) < 0) ||
    ((rc = bind_socket (*sock, port, address)) < 0)
  )
  {
    goto fail;
  }

  if (! stream)
  {
    if ((rc = set_mc_options_transmit (*sock)) < 0)
    {
      goto fail;
    }
  }

  if (stream)
  {
#ifdef SO_NOSIGPIPE
    set_socket_nosigpipe (*sock);
#endif
#ifdef TCP_NODELAY
    if (config.tcp_nodelay)
    {
      set_socket_nodelay (*sock);
    }
#endif
  }

  if (mcip && ((rc = join_mcgroups (*sock, mcip)) < 0))
  {
    goto fail;
  }

  return 0;

fail:

  os_sockFree (*sock);
  *sock = Q_INVALID_SOCKET;
  return rc;
}
예제 #4
0
파일: io.c 프로젝트: ebichu/dd-wrt
static void accept_new(void)
{
    char buffer[MAX_ATM_ADDR_LEN+1];
    struct sockaddr_atmsvc addr;
    struct atm_qos qos;
    ENTRY *entry;
    VCC *vcc;
    int fd,error;
    socklen_t len,size;

    len = sizeof(addr);
    if ((fd = accept(incoming,(struct sockaddr *) &addr,&len)) < 0) {
	error = errno;
	diag(COMPONENT,DIAG_ERROR,"accept: %s",strerror(errno));
	if (error == EUNATCH) {
	    diag(COMPONENT,DIAG_WARN,"disabling SVCs");
	    (void) close(incoming);
	    incoming = -1;
	}
	return;
    }
    /* the following code probably belongs to arp.c ... */
    if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &addr,pretty) <
      0) strcpy(buffer,"<atm2text error>");
    diag(COMPONENT,DIAG_DEBUG,"Incoming call from %s",buffer);
    size = sizeof(qos);
    if (getsockopt(fd,SOL_ATM,SO_ATMQOS,&qos,&size) < 0)
	diag(COMPONENT,DIAG_FATAL,"getsockopt SO_ATMQOS: %s",strerror(errno));
    if (size != sizeof(qos))
	diag(COMPONENT,DIAG_FATAL,"SO_ATMQOS: size %d != %d",size,sizeof(qos));
    if (ioctl(fd,ATMARP_MKIP,qos.txtp.traffic_class == ATM_NONE ? 0 :
      CLIP_DEFAULT_IDLETIMER) < 0) {
        diag(COMPONENT,DIAG_ERROR,"ioctl ATMARP_MKIP: %s",strerror(errno));
        (void) do_close(fd);
        return;
    }
    vcc = alloc_t(VCC);
    vcc->active = 0;
    vcc->connecting = 0;
    vcc->fd = fd;
    if (qos.txtp.traffic_class == ATM_NONE) {
	vcc->entry = NULL;
	incoming_unidirectional(vcc);
	Q_INSERT_HEAD(unidirectional_vccs,vcc);
	return;
    }
    if (merge) {
	ITF *itf;

	for (itf = itfs; itf; itf = itf->next) {
	    entry = lookup_addr(itf,&addr);
	    if (entry) {
		vcc->entry = entry;
		Q_INSERT_HEAD(entry->vccs,vcc);
		if (entry->state == as_valid) {
		    if (set_ip(vcc->fd,entry->ip) < 0) {
			diag(COMPONENT,DIAG_ERROR,"set_ip: %s",
			  strerror(errno));
			disconnect_vcc(vcc);
		    }
		    else set_sndbuf(vcc);
		}
		return;
	    }
	}
    }
    entry = alloc_entry(1);
    entry->state = as_invalid;
    entry->addr = alloc_t(struct sockaddr_atmsvc);
    *entry->addr = addr;
    entry->flags = ATF_PUBL;
    Q_INSERT_HEAD(unknown_incoming,entry);
    vcc->entry = entry;
    Q_INSERT_HEAD(entry->vccs,vcc);
    incoming_call(vcc);
}
예제 #5
0
static int learn(VCC *vcc,uint32_t ip,struct sockaddr_atmsvc *addr)
{
    ENTRY *entry;
    ITF *itf;
    VCC *walk,*next;
    unsigned char *ipp;
    int result = 0;

    if (!ip) return 0;
    ipp = (unsigned char *) &ip;
    itf = lookup_itf_by_ip(ip);
    if (!itf) {
	diag(COMPONENT,DIAG_ERROR,"got unroutable IP address %d.%d.%d.%d",
	  ipp[0],ipp[1],ipp[2],ipp[3]);
	return 0;
    }
    entry = lookup_ip(itf,ip);
    assert(!vcc || vcc->entry);
    /*
     * If the entry on which we received the update isn't dangling but it
     * doesn't correspond to the one with the address, ...
     */
    if (entry && vcc && vcc->entry->itf && entry != vcc->entry) {
	diag(COMPONENT,DIAG_DEBUG,"collision on %d.%d.%d.%d",ipp[0],ipp[1],
	  ipp[2],ipp[3]);
	return 0;
    }
    /*
     * If the entry on which we received the update is dangling and we found
     * an entry that already describes that IP address, ...
     */
    if (entry && vcc && !vcc->entry->itf) {
	if (!entry->svc) {
	    diag(COMPONENT,DIAG_ERROR,"attempt to overwrite PVC for IP "
	      "%d.%d.%d.%d",ipp[0],ipp[1],ipp[2],ipp[3]);
	    return 0;
	}
	STOP_TIMER(vcc->entry);
	Q_REMOVE(unknown_incoming,vcc->entry);
	free(vcc->entry);
	vcc->entry = entry;
	Q_INSERT_HEAD(entry->vccs,vcc);
	set_sndbuf(vcc);
	entry->flags &= ~ATF_NOVC;
	assert(!vcc->connecting);
	if (set_ip(vcc->fd,ip) < 0) {
	    diag(COMPONENT,DIAG_ERROR,"set_ip: %s",strerror(errno));
	    disconnect_vcc(vcc);
	    vcc = NULL;
	    result = -1;
	}
    }
    /*
     * If we still don't have an entry, we try to use the entry that already
     * belongs to the VCC (InARP), or we create a new one (ARP).
     */
    if (!entry) {
	if (vcc) {
	    entry = vcc->entry;
	    if (!entry->itf) {
		Q_REMOVE(unknown_incoming,entry);
		entry->sndbuf = itf->sndbuf;
		set_sndbuf(vcc);
	    }
	    else if (entry->ip && entry->ip != ip && (entry->flags & ATF_PERM)
		  && !(entry->flags & ATF_ARPSRV)) {
		    diag(COMPONENT,DIAG_ERROR,"ignoring attempt to change IP "
		      "address of permanent entry (to %d.%d.%d.%d)",ipp[0],
		      ipp[1],ipp[2],ipp[3]);
		    return result;
		}
	}
	else {
	    entry = alloc_entry(1);
	    entry->flags = ATF_PUBL;
	}
    }
    if (!atmsvc_addr_in_use(*addr)) addr = NULL;
    if (entry->addr && addr && (entry->flags & ATF_PERM) &&
      !atm_equal((struct sockaddr *) entry->addr,(struct sockaddr *) addr,0,0))
      {
	diag(COMPONENT,DIAG_ERROR,"ignoring attempt to change ATM address of "
	  "permanent entry");
	return result;
    }
    if (entry->state == as_valid && entry->ip == ip && (!addr || (entry->addr
      && atm_equal((struct sockaddr *) entry->addr,(struct sockaddr *) addr,0,
      0)))) return result; /* no news */
    STOP_TIMER(entry);
    if (entry->ip != ip) send_notifications(entry,0);
    entry->ip = ip;
    if (!entry->itf) {
	entry->itf = itf;
	/* @@@
	 * Need to fix this is in case we allow entries without a valid IP
	 * address but with a pre-set QOS, e.g. a VC on a given PVC with an
	 * unknown remote end.
	 */
	entry->qos = entry->itf->qos;
	adjust_qos(entry->itf,&entry->qos,0);
	Q_INSERT_HEAD(itf->table,entry);
    }
    if (entry->itf != itf)
	diag(COMPONENT,DIAG_ERROR,"interesting, interface has changed ... "
	  "(%d -> %d)",entry->itf->number,itf->number);
    if (addr) {
	if (!entry->addr) entry->addr = alloc(sizeof(*addr));
	*entry->addr = *addr;
	if (merge) {
	    ENTRY *incoming;

	    while ((incoming = lookup_incoming(addr))) {
		STOP_TIMER(incoming);
		Q_REMOVE(unknown_incoming,incoming);
		incoming->vccs->entry = entry;
		Q_INSERT_HEAD(entry->vccs,incoming->vccs);
		set_sndbuf(incoming->vccs);
		free(incoming);
	    }
	}
    }
    for (walk = entry->vccs; walk; walk = next) {
	next = walk->next;
	if (!walk->connecting)
	    if (set_ip(walk->fd,ip) < 0) {
		diag(COMPONENT,DIAG_ERROR,"set_ip: %s",strerror(errno));
		disconnect_vcc(walk);
		if (walk == vcc) result = -1;
	    }
    }
    if (entry->state != as_valid) {
	if (!entry->vccs && itf->arp_srv && !(entry->flags & ATF_NOVC))
	    connect_me(entry);
	send_notifications(entry,1);
    }
    if ((entry->flags & ATF_ARPSRV) || !(entry->flags & ATF_PERM)) {
	if (entry->itf->arp_srv) START_TIMER(entry,CREVAL);
	else START_TIMER(entry,SREVAL);
    }
    entry->state = as_valid;
    return result;
}