static Conv* protoclone(Proto *p, char *user, int nfd) { Conv *c, **pp, **ep; c = 0; lock(&p->l); if(waserror()) { unlock(&p->l); nexterror(); } ep = &p->conv[p->maxconv]; for(pp = p->conv; pp < ep; pp++) { c = *pp; if(c == 0) { c = mallocz(sizeof(Conv), 1); if(c == 0) error(Enomem); lock(&c->r.lk); c->r.ref = 1; c->p = p; c->x = pp - p->conv; p->nc++; *pp = c; break; } lock(&c->r.lk); if(c->r.ref == 0) { c->r.ref++; break; } unlock(&c->r.lk); } if(pp >= ep) { unlock(&p->l); poperror(); return 0; } strcpy(c->owner, user); c->perm = 0660; c->state = "Closed"; c->restricted = 0; c->laddr = 0; c->raddr = 0; c->lport = 0; c->rport = 0; c->sfd = nfd; if(nfd == -1) c->sfd = so_socket(p->stype); unlock(&c->r.lk); unlock(&p->l); poperror(); return c; }
static void test_tcp_client(void) { int sd; int re; struct sockaddr_in sa; printf("[tcp(client)] start\n"); sd = so_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); DEBUG_PRINT(("so_socket = %d(%d, %d)\n", sd, MERCD(sd), SERCD(sd))); if ( sd < 0 ) { goto error2; } bzero(&sa, sizeof sa); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sa.sin_port = htons(12345); re = so_connect(sd, (struct sockaddr*)&sa, sizeof sa); printf("so_connect = %d(%d, %d)\n", re, MERCD(re), SERCD(re)); if ( re < 0 ) { goto error2; } re = so_write(sd, "1234", 4); DEBUG_PRINT(("so_write = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error2; } re = so_send(sd, "a", 1, MSG_OOB); DEBUG_PRINT(("so_send = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error2; } so_close(sd); tk_wai_sem(semid2, 1, TMO_FEVR); re = so_break(server_tskid); DEBUG_PRINT(("so_break = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error2; } printf("[tcp(client)] OK\n"); return; error2: if ( sd > 0 ) { so_close(sd); } so_break(server_tskid); printf("[tcp(client)] FAILED\n"); }
static void route_cmd(int cmd, in_addr_t dest, in_addr_t gate, in_addr_t mask, int index, int direct) { int i = 0; int sock; int re; struct { struct rt_msghdr rtm; struct sockaddr_in addr[3]; } buf; bzero(&buf, sizeof buf); buf.rtm.rtm_version = RTM_VERSION; buf.rtm.rtm_type = cmd; buf.rtm.rtm_index = index; buf.rtm.rtm_flags = RTF_STATIC; if ( direct ) { buf.rtm.rtm_flags |= RTF_HOST; } else { buf.rtm.rtm_flags |= RTF_GATEWAY; } buf.rtm.rtm_addrs = RTA_DST | RTA_NETMASK; if ( gate != 0 ) { buf.rtm.rtm_addrs |= RTA_GATEWAY; } buf.rtm.rtm_inits = RTV_HOPCOUNT; buf.rtm.rtm_rmx.rmx_hopcount = 1; buf.rtm.rtm_seq = 1; buf.addr[i].sin_len = sizeof(struct sockaddr_in); buf.addr[i].sin_family = AF_INET; buf.addr[i].sin_addr.s_addr = dest; i++; if ( gate != 0 ) { buf.addr[i].sin_len = sizeof(struct sockaddr_in); buf.addr[i].sin_family = AF_INET; buf.addr[i].sin_addr.s_addr = gate; i++; } buf.addr[i].sin_len = sizeof(struct sockaddr_in); buf.addr[i].sin_family = AF_INET; buf.addr[i].sin_addr.s_addr = mask; i++; buf.rtm.rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr) * i; sock = so_socket(AF_ROUTE, SOCK_RAW, 0); DEBUG_PRINT(("route_add: so_socket = %d(%d, %d)\n", sock, MERCD(sock), SERCD(sock))); so_shutdown(sock, SHUT_RD); re = so_write(sock, &buf, buf.rtm.rtm_msglen); DEBUG_PRINT(("route_add: so_write = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); so_close(sock); }
static Conv* protoclone(Proto *p, char *user, int nfd) { Conv *c, **pp, **ep, **np; int maxconv; c = 0; qlock(&p->l); if(waserror()) { qunlock(&p->l); nexterror(); } ep = &p->conv[p->nc]; for(pp = p->conv; pp < ep; pp++) { c = *pp; if(c == 0) { c = newconv(p, pp); break; } if(canqlock(&c->l)){ if(c->inuse == 0) break; qunlock(&c->l); } } if(pp >= ep) { if(p->nc >= MAXCONV) { qunlock(&p->l); poperror(); return 0; } maxconv = 2 * p->nc; if(maxconv > MAXCONV) maxconv = MAXCONV; np = realloc(p->conv, sizeof(Conv*) * maxconv); if(np == nil) error(Enomem); p->conv = np; pp = &p->conv[p->nc]; memset(pp, 0, sizeof(Conv*)*(maxconv - p->nc)); p->nc = maxconv; c = newconv(p, pp); } c->inuse = 1; kstrdup(&c->owner, user); c->perm = 0660; c->state = Idle; ipmove(c->laddr, IPnoaddr); ipmove(c->raddr, IPnoaddr); c->lport = 0; c->rport = 0; c->restricted = 0; c->headers = 0; c->sfd = nfd; if(nfd == -1) c->sfd = so_socket(p->stype); qunlock(&c->l); qunlock(&p->l); poperror(); return c; }
static Chan * ipopen(Chan *c, int omode) { Conv *cv, *nc; Proto *p; uchar raddr[IPaddrlen]; ushort rport; int perm, sfd; Fs *f; perm = m2p[omode&3]; f = ipfs[c->dev]; switch(TYPE(c->qid)) { default: break; case Qtopdir: case Qprotodir: case Qconvdir: case Qstatus: case Qremote: case Qlocal: case Qstats: /* case Qipselftab: */ if(omode != OREAD) error(Eperm); break; case Qndb: if(omode & (OWRITE|OTRUNC) && !iseve()) error(Eperm); if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC)){ f->ndb[0] = 0; f->ndbvers++; } break; case Qclone: p = f->p[PROTO(c->qid)]; cv = protoclone(p, up->env->user, -1); if(cv == 0) error(Enodev); mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE); break; case Qdata: case Qctl: p = f->p[PROTO(c->qid)]; qlock(&p->l); cv = p->conv[CONV(c->qid)]; qlock(&cv->l); if(waserror()){ qunlock(&cv->l); qunlock(&p->l); nexterror(); } if((perm & (cv->perm>>6)) != perm) { if(strcmp(up->env->user, cv->owner) != 0) error(Eperm); if((perm & cv->perm) != perm) error(Eperm); } cv->inuse++; if(cv->inuse == 1) { kstrdup(&cv->owner, up->env->user); cv->perm = 0660; if(cv->sfd < 0) cv->sfd = so_socket(p->stype); } poperror(); qunlock(&cv->l); qunlock(&p->l); break; case Qlisten: p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; if((perm & (cv->perm>>6)) != perm){ if(strcmp(up->env->user, cv->owner) != 0) error(Eperm); if((perm & cv->perm) != perm) error(Eperm); } if(cv->state != Announced) error("not announced"); qlock(&cv->listenq); if(waserror()){ qunlock(&cv->listenq); nexterror(); } sfd = so_accept(cv->sfd, raddr, &rport); nc = protoclone(p, up->env->user, sfd); if(nc == 0) { so_close(sfd); error(Enodev); } memmove(nc->raddr, raddr, IPaddrlen); nc->rport = rport; setladdr(nc); nc->state = Connected; mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE); poperror(); qunlock(&cv->listenq); break; } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; }
static void test_tcp_server(void) { int re; int sd; int reader = 0; char buf[5]; struct sockaddr_in sa; struct sockaddr_in sa2; socklen_t sa_len; printf("[tcp(server)] start\n"); sd = so_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if ( sd < 0 ) { goto error; } DEBUG_PRINT(("server_task: so_socket = %d(%d, %d)\n", sd, MERCD(sd), SERCD(sd))); bzero(&sa, sizeof sa); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(12345); re = so_bind(sd, (struct sockaddr*)&sa, sizeof sa); DEBUG_PRINT(("server_task: so_bind = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error; } re = so_listen(sd, 5); DEBUG_PRINT(("server_task: so_listen = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error; } tk_sig_sem(semid, 1); DEBUG_PRINT(("server_task: server semaphore signaled 1\n")); reader = so_accept(sd, (struct sockaddr*)&sa2, &sa_len); DEBUG_PRINT(("server_task: so_accept = %d(%d, %d)\n", reader, MERCD(reader), SERCD(reader))); if ( reader < 0 ) { goto error; } wait_data(reader); bzero(buf, sizeof buf); re = so_sockatmark(reader); DEBUG_PRINT(("server_task: so_sockatmark = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error; } re = so_read(reader, buf, 4); DEBUG_PRINT(("server_task: so_read = %d(%d, %d), buf = %s\n", re, MERCD(re), SERCD(re), buf)); if ( re < 0 || memcmp(buf, "1234", 4) != 0 ) { goto error; } wait_data(reader); bzero(buf, sizeof buf); re = so_sockatmark(reader); DEBUG_PRINT(("server_task: so_sockatmark = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error; } re = so_recv(reader, buf, 4, MSG_OOB); DEBUG_PRINT(("server_task: so_recv = %d(%d, %d), buf = %s\n", re, MERCD(re), SERCD(re), buf)); if ( re < 0 || buf[0] != 'a' ) { goto error; } tk_sig_sem(semid2, 1); DEBUG_PRINT(("server_task: server semaphore for break signaled 2\n")); DEBUG_PRINT(("server_task: pre-accept for break\n")); re = so_accept(sd, (struct sockaddr*)&sa2, &sa_len); DEBUG_PRINT(("server_task: so_accept = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re != EX_INTR ) { goto error; } so_close(reader); so_close(sd); printf("[tcp(server)] OK\n"); return; error: printf("[tcp(server)] FAILED\n"); if ( sd > 0 ) { so_close(sd); } if ( reader > 0 ) { so_close(reader); } tk_del_sem(semid2); return; }
int cg_socket_sendto(CgSocket *sock, char *addr, int port, char *data, int dataLen) { #if defined(BTRON) || defined(TENGINE) struct sockaddr_in sockaddr; #elif defined(ITRON) T_IPV4EP dstaddr; T_UDP_CCEP udpccep = { 0, { IPV4_ADDRANY, UDP_PORTANY }, (FP)cg_socket_udp_callback }; #else struct addrinfo *addrInfo; #endif int sentLen; BOOL isBoundFlag; cg_log_debug_l4("Entering...\n"); if (data == NULL) return 0; if (dataLen < 0) dataLen = cg_strlen(data); if (dataLen <= 0) return 0; isBoundFlag = cg_socket_isbound(sock); sentLen = -1; #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) if (cg_socket_tosockaddrin(addr, port, &sockaddr, TRUE) == FALSE) return -1; if (isBoundFlag == FALSE) cg_socket_setid(sock, so_socket(PF_INET, cg_socket_getrawtype(sock), 0)); if (0 <= sock->id) sentLen = so_sendto(sock->id, (B*)data, dataLen, 0, (SOCKADDR*)&sockaddr, sizeof(struct sockaddr_in)); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) if (cg_socket_tosockaddrin(addr, port, &sockaddr, TRUE) == FALSE) return -1; if (isBoundFlag == FALSE) { cg_socket_setid(sock, ka_socket(PF_INET, cg_socket_getrawtype(sock), cg_socket_getprototype(sock))); cg_socket_setmulticastinterface(sock, NULL); } if (0 <= sock->id) sentLen = ka_sendto(sock->id, data, dataLen, 0, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr_in)); #elif defined(ITRON) if (isBoundFlag == FALSE) { cg_socket_setid(sock, cg_socket_getavailableid(cg_socket_issocketstream(sock))); if (sock->id < 0) return FALSE; if (udp_cre_cep(sock->id, &udpccep) != E_OK) return FALSE; } dstaddr.ipaddr = ascii_to_ipaddr(addr); dstaddr.portno = htons(port); sentLen = udp_snd_dat(sock->id, &dstaddr, data, dataLen, TMO_FEVR); #else if (cg_socket_tosockaddrinfo(cg_socket_getrawtype(sock), addr, port, &addrInfo, TRUE) == FALSE) return -1; if (isBoundFlag == FALSE) cg_socket_setid(sock, socket(addrInfo->ai_family, addrInfo->ai_socktype, 0)); /* Setting multicast time to live in any case to default */ cg_socket_setmulticastttl(sock, CG_UPNP_SSDP_MULTICAST_DEFAULT_TTL); if (0 <= sock->id) sentLen = sendto(sock->id, data, dataLen, 0, addrInfo->ai_addr, addrInfo->ai_addrlen); freeaddrinfo(addrInfo); #endif if (isBoundFlag == FALSE) cg_socket_close(sock); #ifdef SOCKET_DEBUG cg_log_debug_s("sentLen : %d\n", sentLen); #endif cg_log_debug_l4("Leaving...\n"); return sentLen; }
BOOL cg_socket_connect(CgSocket *sock, char *addr, int port) { #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) ERR ret; struct sockaddr_in sockaddr; if (cg_socket_tosockaddrin(addr, port, &sockaddr, TRUE) == FALSE) return FALSE; if (cg_socket_isbound(sock) == FALSE) cg_socket_setid(sock, so_socket(PF_INET, cg_socket_getrawtype(sock), 0)); ret = so_connect(sock->id, (SOCKADDR *)&sockaddr, sizeof(struct sockaddr_in)); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) ERR ret; struct sockaddr_in sockaddr; if (cg_socket_tosockaddrin(addr, port, &sockaddr, TRUE) == FALSE) return FALSE; if (cg_socket_isbound(sock) == FALSE) cg_socket_setid(sock, ka_socket(PF_INET, cg_socket_getrawtype(sock), cg_socket_getprototype(sock))); ret = ka_connect(sock->id, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr_in)); #elif defined(ITRON) T_TCP_CCEP tcpccep = { 0, sock->sendWinBuf, CG_NET_SOCKET_WINDOW_BUFSIZE, sock->recvWinBuf, CG_NET_SOCKET_WINDOW_BUFSIZE, (FP)cg_socket_tcp_callback }; T_IPV4EP localAddr; T_IPV4EP dstAddr; ER ret; if (cg_socket_getavailablelocaladdress(&localAddr) == FALSE) return FALSE; if (cg_socket_isbound(sock) == FALSE) { cg_socket_initwindowbuffer(sock); cg_socket_setid(sock, cg_socket_getavailableid(cg_socket_issocketstream(sock))); if (tcp_cre_cep(sock->id, &tcpccep) != E_OK) return FALSE; } dstAddr.ipaddr = ascii_to_ipaddr(addr); dstAddr.portno = htons(port); ret = tcp_con_cep(sock->id, &localAddr, &dstAddr, TMO_FEVR); if (ret == E_OK) { cg_socket_setaddress(sock, ""/*ipaddr_to_ascii(localAddr.ipaddr)*/); cg_socket_setport(sock, ntohs(localAddr.portno)); ret = 0; } else ret = -1; #else struct addrinfo *toaddrInfo; int ret; if (cg_socket_tosockaddrinfo(cg_socket_getrawtype(sock), addr, port, &toaddrInfo, TRUE) == FALSE) return FALSE; if (cg_socket_isbound(sock) == FALSE) cg_socket_setid(sock, socket(toaddrInfo->ai_family, toaddrInfo->ai_socktype, 0)); ret = connect(sock->id, toaddrInfo->ai_addr, toaddrInfo->ai_addrlen); freeaddrinfo(toaddrInfo); #endif cg_log_debug_l4("Entering...\n"); cg_socket_setdirection(sock, CG_NET_SOCKET_CLIENT); #if defined(CG_USE_OPENSSL) if (cg_socket_isssl(sock) == TRUE) { sock->ctx = SSL_CTX_new( SSLv23_client_method()); sock->ssl = SSL_new(sock->ctx); if (SSL_set_fd(sock->ssl, cg_socket_getid(sock)) == 0) { cg_socket_close(sock); return FALSE; } if (SSL_connect(sock->ssl) < 1) { cg_socket_close(sock); return FALSE; } } #endif cg_log_debug_l4("Leaving...\n"); return (ret == 0) ? TRUE : FALSE; }
BOOL cg_socket_bind(CgSocket *sock, int bindPort, char *bindAddr, BOOL bindFlag, BOOL reuseFlag) { #if defined(BTRON) || defined(TENGINE) struct sockaddr_in sockaddr; ERR ret; #elif defined(ITRON) T_UDP_CCEP udpccep = { 0, { IPV4_ADDRANY, UDP_PORTANY }, (FP)cg_socket_udp_callback }; T_TCP_CREP tcpcrep = { 0, { IPV4_ADDRANY, 0 } }; T_TCP_CCEP tcpccep = { 0, sock->sendWinBuf, CG_NET_SOCKET_WINDOW_BUFSIZE, sock->recvWinBuf, CG_NET_SOCKET_WINDOW_BUFSIZE, (FP)cg_socket_tcp_callback }; #else struct addrinfo *addrInfo; int ret; #endif cg_log_debug_l4("Entering...\n"); if (bindPort <= 0 /* || bindAddr == NULL*/) return FALSE; #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) if (cg_socket_tosockaddrin(bindAddr, bindPort, &sockaddr, bindFlag) == FALSE) return FALSE; cg_socket_setid(sock, so_socket(PF_INET, cg_socket_getrawtype(sock), 0)); if (sock->id < 0) return FALSE; if (reuseFlag == TRUE) { if (cg_socket_setreuseaddress(sock, TRUE) == FALSE) { cg_socket_close(sock); return FALSE; } } ret = so_bind(sock->id, (SOCKADDR *)&sockaddr, sizeof(struct sockaddr_in)); if (ret < 0) { cg_socket_close(sock); return FALSE; } #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) if (cg_socket_tosockaddrin(bindAddr, bindPort, &sockaddr, bindFlag) == FALSE) return FALSE; cg_socket_setid(sock, ka_socket( PF_INET, cg_socket_getrawtype(sock), cg_socket_getprototype(sock))); if (sock->id < 0) return FALSE; /* if (cg_socket_setmulticastinterface(sock, bindAddr) == FALSE) return FALSE; */ if (reuseFlag == TRUE) { if (cg_socket_setreuseaddress(sock, TRUE) == FALSE) { cg_socket_close(sock); return FALSE; } } ret = ka_bind(sock->id, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr_in)); if (ret < 0) { cg_socket_close(sock); return FALSE; } #elif defined(ITRON) cg_socket_setid(sock, cg_socket_getavailableid(cg_socket_issocketstream(sock))); if (sock->id < 0) return FALSE; if (cg_socket_issocketstream(sock) == TRUE) { if (bindAddr != NULL) tcpcrep.myaddr.ipaddr = ascii_to_ipaddr(bindAddr); tcpcrep.myaddr.ipaddr = htons(bindPort); if (tcp_cre_rep(sock->id, &tcpcrep) != E_OK) { cg_socket_close(sock); return FALSE; } if (tcp_cre_cep(sock->id, &tcpccep) != E_OK) { cg_socket_close(sock); return FALSE; } } else { if (bindAddr != NULL) udpccep.myaddr.ipaddr = ascii_to_ipaddr(bindAddr); udpccep.myaddr.ipaddr = htons(bindPort); if (udp_cre_cep(sock->id, &udpccep) != E_OK) { cg_socket_close(sock); return FALSE; } } #else if (cg_socket_tosockaddrinfo(cg_socket_getrawtype(sock), bindAddr, bindPort, &addrInfo, bindFlag) == FALSE) return FALSE; cg_socket_setid(sock, socket(addrInfo->ai_family, addrInfo->ai_socktype, 0)); if (sock->id== -1) { cg_socket_close(sock); return FALSE; } if (reuseFlag == TRUE) { if (cg_socket_setreuseaddress(sock, TRUE) == FALSE) { cg_socket_close(sock); return FALSE; } } ret = bind(sock->id, addrInfo->ai_addr, addrInfo->ai_addrlen); freeaddrinfo(addrInfo); #endif #if !defined(ITRON) if (ret != 0) return FALSE; #endif cg_socket_setdirection(sock, CG_NET_SOCKET_SERVER); cg_socket_setaddress(sock, bindAddr); cg_socket_setport(sock, bindPort); cg_log_debug_l4("Leaving...\n"); return TRUE; }