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 long ipwrite(Chan *ch, void *a, long n, vlong off) { Conv *c; Proto *x; char *p; Cmdbuf *cb; Fs *f; f = ipfs[ch->dev]; switch(TYPE(ch->qid)) { default: error(Eperm); case Qdata: x = f->p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(c->sfd < 0) error(Ehungup); qlock(&c->wlock); if(waserror()){ qunlock(&c->wlock); nexterror(); } if(c->headers) { if(n < c->headers) error(Eshort); p = a; n = so_send(c->sfd, p + c->headers, n - c->headers, p, c->headers); if(n >= 0) n += c->headers; } else n = so_send(c->sfd, a, n, nil, 0); poperror(); qunlock(&c->wlock); if(n < 0) oserror(); break; case Qarp: return arpwrite(a, n); case Qndb: if(off > strlen(f->ndb)) error(Eio); if(off+n >= sizeof(f->ndb)-1) error(Eio); memmove(f->ndb+off, a, n); f->ndb[off+n] = 0; f->ndbvers++; f->ndbmtime = seconds(); break; case Qctl: x = f->p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; cb = parsecmd(a, n); qlock(&c->l); if(waserror()){ qunlock(&c->l); free(cb); nexterror(); } if(cb->nf < 1) error("short control request"); if(strcmp(cb->f[0], "connect") == 0) connectctlmsg(x, c, cb); else if(strcmp(cb->f[0], "announce") == 0) announcectlmsg(x, c, cb); else if(strcmp(cb->f[0], "bind") == 0) bindctlmsg(x, c, cb); else if(strcmp(cb->f[0], "ttl") == 0){ /* ignored */ } else if(strcmp(cb->f[0], "tos") == 0){ /* ignored */ } else if(strcmp(cb->f[0], "ignoreadvice") == 0){ /* ignored */ } else if(strcmp(cb->f[0], "headers4") == 0){ if(c->p->stype != S_UDP) error(Enoctl); c->headers = OUdphdrlenv4; } else if(strcmp(cb->f[0], "oldheaders") == 0){ if(c->p->stype != S_UDP) error(Enoctl); c->headers = OUdphdrlen; } else if(strcmp(cb->f[0], "headers") == 0){ if(c->p->stype != S_UDP) error(Enoctl); c->headers = Udphdrlen; } else if(strcmp(cb->f[0], "hangup") == 0){ if(c->p->stype != S_TCP) error(Enoctl); qunlock(&c->l); if(waserror()){ qlock(&c->l); nexterror(); } /* TO DO: check fd status if socket close/hangup interrupted */ if(c->sfd >= 0 && so_hangup(c->sfd, 1) < 0) oserror(); qlock(&c->l); poperror(); c->sfd = -1; c->state = Hungup; } else if(strcmp(cb->f[0], "keepalive") == 0){ if(c->p->stype != S_TCP) error(Enoctl); if(c->sfd < 0) error("not connected"); so_keepalive(c->sfd, cb->nf>1? atoi(cb->f[1]): 0); } else error(Enoctl); poperror(); qunlock(&c->l); free(cb); break; } return n; }
int cg_socket_write(CgSocket *sock, char *cmd, int cmdLen) { int nSent; int nTotalSent = 0; int cmdPos = 0; int retryCnt = 0; cg_log_debug_l4("Entering...\n"); if (cmdLen <= 0) return 0; do { #if defined(CG_USE_OPENSSL) if (cg_socket_isssl(sock) == FALSE) { #endif #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) nSent = so_send(sock->id, (B*)(cmd + cmdPos), cmdLen, 0); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) nSent = ka_send(sock->id, (B*)(cmd + cmdPos), cmdLen, 0); #elif defined(ITRON) nSent = tcp_snd_dat(sock->id, cmd + cmdPos, cmdLen, TMO_FEVR); #else nSent = send(sock->id, cmd + cmdPos, cmdLen, 0); #endif #if defined(CG_USE_OPENSSL) } else { nSent = SSL_write(sock->ssl, cmd + cmdPos, cmdLen); } #endif /* Try to re-send in case sending has failed */ if (nSent <= 0) { retryCnt++; if (CG_NET_SOCKET_SEND_RETRY_CNT < retryCnt) { /* Must reset this because otherwise return value is interpreted as something else than fault and this function loops forever */ nTotalSent = 0; break; } cg_wait(CG_NET_SOCKET_SEND_RETRY_WAIT_MSEC); } else { nTotalSent += nSent; cmdPos += nSent; cmdLen -= nSent; retryCnt = 0; } } while (0 < cmdLen); #ifdef SOCKET_DEBUG cg_log_debug_s("w %d : %s\n", nTotalSent, ((cmd != NULL) ? cmd : "")); #endif cg_log_debug_l4("Leaving...\n"); return nTotalSent; }
long ipwrite(Chan *ch, void *a, long n, vlong offset) { Conv *c; Proto *x; int r, nf; char *p, *fields[3], buf[128]; switch(TYPE(ch->qid)) { default: error(Eperm); case Qcs: return cswrite(ch, a, n, offset); case Qctl: x = &proto[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(n > sizeof(buf)-1) n = sizeof(buf)-1; memmove(buf, a, n); buf[n] = '\0'; nf = tokenize(buf, fields, 3); if(strcmp(fields[0], "connect") == 0){ switch(nf) { default: error("bad args to connect"); case 2: p = setraddrport(c, fields[1]); if(p != 0) error(p); break; case 3: p = setraddrport(c, fields[1]); if(p != 0) error(p); c->lport = atoi(fields[2]); setlport(c); break; } so_connect(c->sfd, c->raddr, c->rport); setladdr(c); c->state = "Established"; return n; } if(strcmp(fields[0], "announce") == 0) { switch(nf){ default: error("bad args to announce"); case 2: setladdrport(c, fields[1]); break; } so_listen(c->sfd); c->state = "Announced"; return n; } if(strcmp(fields[0], "bind") == 0){ switch(nf){ default: error("bad args to bind"); case 2: c->lport = atoi(fields[1]); break; } setlport(c); return n; } error("bad control message"); case Qdata: x = &proto[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; r = so_send(c->sfd, a, n, 0); if(r < 0){ oserrstr(); nexterror(); } return r; } return n; }