コード例 #1
3
ファイル: sserver_win32.cpp プロジェクト: acml/cvsnt
BOOL ClientAuthenticate(const char *name, const char *hostname)
{
	int rc, rcISC;
	SEC_WINNT_AUTH_IDENTITY nameAndPwd = {0};
	int bytesReceived = 0, bytesSent = 0;
	char myTokenSource[256];
	TimeStamp useBefore;
	DWORD ctxReq, ctxAttr;
	int dwRead,dwWritten;
	// input and output buffers
	SecBufferDesc obd, ibd;
	SecBuffer ob, ib[2];
	BOOL haveInbuffer = FALSE;
	BOOL haveContext = FALSE;
	SCHANNEL_CRED cred = {0};
	PCCERT_CONTEXT cert = NULL;

	HANDLE hMy = CertOpenSystemStore(0,"MY");
	if(!hMy)
	{
		rcISC = SEC_E_NO_CREDENTIALS;
		server_error(1,"[%08x] %s\n",rcISC,GetErrorString(rcISC));
		return FALSE;
    }

	if(name)
	{
		cert = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, (const wchar_t *)cvs::wide(name),	NULL);
		if(!cert)
		{
			rcISC = SEC_E_NO_CREDENTIALS;
			server_error(1,"No certificate for '%s': %s\n",name,GetErrorString(rcISC));
			return FALSE;
		}
	}

	cred.dwVersion = SCHANNEL_CRED_VERSION;
	cred.dwFlags = SCH_CRED_USE_DEFAULT_CREDS;

	if(cert)
	{
		cred.cCreds     = 1;
		cred.paCred     = &cert;
	}

	rc = AcquireCredentialsHandle( NULL, "SChannel", SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &credHandle, &useBefore );

	ctxReq = ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS;
	strncpy(myTokenSource,hostname,sizeof(myTokenSource));

	CertCloseStore(hMy,0);

	ib[0].pvBuffer = NULL;

	while ( 1 )
	{
		obd.ulVersion = SECBUFFER_VERSION;
		obd.cBuffers = 1;
		obd.pBuffers = &ob; // just one buffer
		ob.BufferType = SECBUFFER_TOKEN; // preping a token here
		ob.cbBuffer = secPackInfo->cbMaxToken;
		ob.pvBuffer = malloc(secPackInfo->cbMaxToken);

		rcISC = InitializeSecurityContext( &credHandle, haveContext? &contextHandle: NULL,
			myTokenSource, ctxReq, 0, SECURITY_NATIVE_DREP, haveInbuffer? &ibd: NULL,
			0, &contextHandle, &obd, &ctxAttr, &useBefore );

		if ( ib[0].pvBuffer != NULL )
		{
			free(ib[0].pvBuffer);
			ib[0].pvBuffer = NULL;
		}

		if ( rcISC == SEC_I_COMPLETE_AND_CONTINUE || rcISC == SEC_I_COMPLETE_NEEDED )
		{
			CompleteAuthToken( &contextHandle, &obd );
			if ( rcISC == SEC_I_COMPLETE_NEEDED )
				rcISC = SEC_E_OK;
			else if ( rcISC == SEC_I_COMPLETE_AND_CONTINUE )
				rcISC = SEC_I_CONTINUE_NEEDED;
		}

		if(rcISC<0)
		{
			server_error(1,"[%08x] %s\n",rcISC,GetErrorString(rcISC));
		}

		// send the output buffer off to the server
		if ( ob.cbBuffer != 0 )
		{
			if((dwWritten=tcp_write( (const char *) ob.pvBuffer, ob.cbBuffer))<=0)
				break;
			bytesSent += dwWritten;
		}
		free(ob.pvBuffer);
		ob.pvBuffer = NULL;
		ob.cbBuffer = 0;

		if ( rcISC != SEC_I_CONTINUE_NEEDED )
			break;

		// prepare to get the server's response
		ibd.ulVersion = SECBUFFER_VERSION;
		ibd.cBuffers = 2;
		ibd.pBuffers = ib; // just one buffer
		ib[0].BufferType = SECBUFFER_TOKEN; // preping a token here
		ib[0].cbBuffer = secPackInfo->cbMaxToken;
		ib[0].pvBuffer = malloc(secPackInfo->cbMaxToken);
		ib[1].cbBuffer = 0;
		ib[1].pvBuffer = NULL;
		ib[1].BufferType = SECBUFFER_EMPTY; // Spare stuff

		// receive the server's response
		if((dwRead=tcp_read(ib[0].pvBuffer,ib[0].cbBuffer))<=0)
			break;
		bytesReceived += dwRead;

		// by now we have an input buffer and a client context

		haveInbuffer = TRUE;
		haveContext = TRUE;
	}

	// we arrive here as soon as InitializeSecurityContext()
	// returns != SEC_I_CONTINUE_NEEDED.

	if ( rcISC != SEC_E_OK )
		haveContext = FALSE;
	else
		haveContext = TRUE; /* Looopback kerberos needs this */

	return haveContext;
}
コード例 #2
0
ファイル: inetsrv.c プロジェクト: M1cha/lk
static int echo_worker(void *socket)
{
    tcp_socket_t *s = socket;

    for (;;) {
        uint8_t buf[1024];

        ssize_t ret = tcp_read(s, buf, sizeof(buf));
        if (ret <= 0)
            break;

        tcp_write(s, buf, ret);
        if (ret <= 0)
            break;
    }

    TRACEF("echo worker exiting\n");
    tcp_close(s);

    return 0;
}
コード例 #3
0
ファイル: server.c プロジェクト: yallawalla/stm32
static void 
	TCP_send(struct tcp_pcb *tpcb, TCP *es) {
		struct pbuf *ptr;
		err_t wr_err = ERR_OK;	 
		while ((wr_err == ERR_OK) &&
					 (es->tx != NULL) && 
					 (es->tx->len <= tcp_sndbuf(tpcb)))
		{
			ptr=es->tx;																	/* get pointer on pbuf from es structure & enqueue data for transmission */
			wr_err=tcp_write(tpcb,ptr->payload,ptr->len, 1);
			if (wr_err == ERR_OK) {
				es->tx = ptr->next;
				if (es->tx != NULL) {
					pbuf_ref(es->tx); 											/* increment reference count for es->p */
				}
				pbuf_free(ptr);														/* free pbuf: will free pbufs up to es->p (because es->p has a reference count > 0) */
			} else if(wr_err == ERR_MEM) { 							/* we are low on memory, try later / harder, defer to poll */
				es->tx = ptr;
		 } else { }																		/* other problem ?? */
		}
	}
コード例 #4
0
ファイル: esp_mg_net_if.c プロジェクト: MrZANE42/smart.js
static int mg_lwip_tcp_write(struct tcp_pcb *tpcb, const void *data,
                             uint16_t len) {
  len = MIN(tpcb->mss, MIN(len, tpcb->snd_buf));
  if (len == 0) {
    DBG(("%p no buf avail %u %u %u %p %p", tpcb, tpcb->acked, tpcb->snd_buf,
         tpcb->snd_queuelen, tpcb->unsent, tpcb->unacked));
    tcp_output(tpcb);
    return 0;
  }
  err_t err = tcp_write(tpcb, data, len, TCP_WRITE_FLAG_COPY);
  tcp_output(tpcb);
  DBG(("%p tcp_write %u = %d", tpcb, len, err));
  if (err != ERR_OK) {
    /*
     * We ignore ERR_MEM because memory will be freed up when the data is sent
     * and we'll retry.
     */
    return err == ERR_MEM ? 0 : -1;
  }
  return len;
}
コード例 #5
0
ファイル: eth_client.c プロジェクト: AlexGeControl/tiva-c
//*****************************************************************************
//
// Send a request to the server
//
// \param pcRequest request to be sent
// \param ui32Size length of the request to be sent. this is usually the size
// of the request minus the termination character
//
// This function will send the request to the connected server
//
// \return the lwIP error code.
//
//*****************************************************************************
err_t
EthClientSend(char *pcRequest, uint32_t ui32Size)
{
    err_t eError;

    eError = tcp_write(g_sEnet.psTCP, pcRequest, ui32Size,
                       TCP_WRITE_FLAG_COPY);

    //
    //  Write data for sending (but does not send it immediately).
    //
    if(eError == ERR_OK)
    {
        //
        // Find out what we can send and send it
        //
        tcp_output(g_sEnet.psTCP);
    }

    return(eError);
}
コード例 #6
0
ファイル: iperf_server.c プロジェクト: neimanra/LwIp
static err_t sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
    struct iperf_state *is = (struct iperf_state *) arg;

    is->sent_bytes += len;

    if (is->amount > 0 && is->sent_bytes > is->amount) {
        finish_send(is, tpcb);
        return ERR_OK;
    } else if (is->amount < 0 && (rte_get_timer_cycles()-is->send_start_ticks) > -is->amount) {
        finish_send(is, tpcb);
        return ERR_OK;
    }

    int space;
    while ((space = tcp_sndbuf(tpcb)) >= sizeof(send_data)) {
        tcp_write(tpcb, send_data, sizeof(send_data), 0);
    }

    return ERR_OK;
}
コード例 #7
0
ファイル: bfscope.c プロジェクト: CoryXie/BarrelfishOS
/*
 * \brief This method should be called when a trace should be dumped on the network.
 */
static void bfscope_trace_dump_network(void)
{
    assert(bfscope_client != NULL);
    assert(trace_length > 0);

    printf("bfscope: sending %lu bytes to network...\n", trace_length);

    /* Send length field */
    char tmpbuf[10];
    int len;
    len = snprintf(tmpbuf, 9, "%08ld", trace_length);
    tcp_write(bfscope_client, tmpbuf, 8, TCP_WRITE_FLAG_COPY);

    /* Start to send the trace */
    timestamp_start = rdtsc();
    trace_sent = 0;

    bfscope_trace_send(bfscope_client);

    tcp_output(bfscope_client);
}
コード例 #8
0
ファイル: socket.c プロジェクト: donghengqaz/POSIX-RTOS
/**
  * read - the function will write bytes to the file
  *                    
  * @param fd    the file handle
  * @param buf   the sending buffer point
  * @param count the maximum bytes to be sent
  *
  * @return the result
  */
ssize_t _write(int fd, const void *buf, size_t count)
{
    struct socket *socket = (struct socket *)fd;
    ssize_t size = -1;
   
    if (SOCK_STREAM == socket->type)
    {
        size = tcp_write(socket->pcb, buf, count, TCP_WRITE_FLAG_COPY);
    }
    else if (SOCK_PACKET == socket->type)
    {
        struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, count, PBUF_POOL);
        
        if ((pbuf = ippkg_pack((os_u8 *)buf, count)) == NULL)
            return -1;
              
        size = udp_send(socket->pcb, pbuf);
    }
  
    return size;
}
コード例 #9
0
ファイル: http_response.c プロジェクト: hokim72/XIL_EDK
int do_http_post(struct tcp_pcb* pcb, char* req, int rlen)
{
	int BUFSIZE = 1024;
	unsigned char buf[BUFSIZE];
	int len, n;
	char* p;

	if (is_cmd_led(req)) {
		n = toggle_leds();
		len = generate_http_header((char*)buf, "js", 1);
		p = (char*)buf + len;
		*p++ = n ? '1':'0';
		*p = 0;
		len++;
		xil_printf("http POST: ledstatus: %x\r\n", n);
	} else if (is_cmd_switch(req)) {
		unsigned s = get_switch_state();
		int n_switches = 4;

		xil_printf("http POST: switch state: %x\r\n", s);
		len = generate_http_header((char*)buf, "js", n_switches);
		p = (char*)buf + len;
		for (n=0; n<n_switches; n++, p++) {
			*p = '0' + (s & 0x1);
			s >>= 1;
		}
		*p = 0;

		len += n_switches;
	}

	if (tcp_write(pcb, buf, len, 1) != ERR_OK) {
		xil_printf("error writing http POST response to socket\r\n");
		xil_printf("http header = %s\r\n", buf);
		return -1;
	}

	return 0;
}
コード例 #10
0
/**
 * Function: recvRemotePacket
 * Description: 当客户端收到服务器发送的数据时调用的回调函数
 * @param arg 回调时传递回来的参数
 * @param tpcb 当前连接的PCB
 * @param p  存放服务器发送过来的数据
 * @param err 回调时传递回来的错误码
 * @return err_t 类型的状态码
**/
err_t recvRemotePacket(void *arg, struct tcp_pcb *tpcb,struct pbuf *p, err_t err) {
    struct pbuf *temp;
    char *data;
    err_t error_status;
    int loc = 0;
    if ((err != ERR_OK) || (p == NULL)) {
        if(p != NULL) {
            tcp_recved(tpcb, p->tot_len);
            pbuf_free(p);
        }
        return ERR_OK;
    }
    if(p == NULL) {
        printf("recv data is empty\n\r");
    } else {
        data = (char*)malloc(p->tot_len);
        memset(data,0,p->tot_len);
        memset(data,0,p->tot_len);
        for(temp = p; temp ; temp = temp->next) {
            memcpy(&data[loc],temp->payload,temp->len);
            loc += temp->len;
        }
    }
    tcp_recved(tpcb, p->tot_len);

    if(p != NULL) {
        pbuf_free(p);
    }

    error_status = tcp_write(tpcb,data,p->len,1);
    if(error_status != ERR_OK) { //发送数据失败
        printf("data send failed\n\r");
        return ERR_MEM;
    }
	tcp_output(tpcb);
    free(data);
    data = NULL;
}
コード例 #11
0
ファイル: inetsrv.c プロジェクト: M1cha/lk
static int chargen_worker(void *socket)
{
    uint64_t count = 0;
    tcp_socket_t *s = socket;

/* enough buffer to hold an entire defacto chargen sequences */
#define CHARGEN_BUFSIZE (0x5f * 0x5f) // 9025 bytes

    uint8_t *buf = malloc(CHARGEN_BUFSIZE);
    if (!buf)
        return -1;

    /* generate the sequence */
    uint8_t c = '!';
    for (size_t i = 0; i < CHARGEN_BUFSIZE; i++) {
        buf[i] = c++;
        if (c == 0x7f)
            c = ' ';
    }

    lk_time_t t = current_time();
    for (;;) {
        ssize_t ret = tcp_write(s, buf, CHARGEN_BUFSIZE);
        //TRACEF("tcp_write returns %d\n", ret);
        if (ret < 0)
            break;

        count += ret;
    }
    t = current_time() - t;

    TRACEF("chargen worker exiting, wrote %llu bytes in %u msecs (%llu bytes/sec)\n",
        count, (uint32_t)t, count * 1000 / t);
    free(buf);
    tcp_close(s);

    return 0;
}
コード例 #12
0
ファイル: bfscope.c プロジェクト: CoryXie/BarrelfishOS
/*
 * \brief Send the next chunk of trace data down given TCP connection
 */
static void bfscope_trace_send(struct tcp_pcb *tpcb)
{
    char *bufptr;
    int len;

    //DEBUG("tcp_sndbuf=%d\n", tcp_sndbuf(tpcb));

    bufptr = trace_buf + trace_sent;
    len = trace_length - trace_sent;

    int more = 0;
    if (len > tcp_sndbuf(tpcb)) {
        len = tcp_sndbuf(tpcb);
        more = 1;
    }

    /* Give the data to LWIP until it runs out of buffer space */
    err_t lwip_err = tcp_write(tpcb, bufptr, len,
                      TCP_WRITE_FLAG_COPY | (more ? TCP_WRITE_FLAG_MORE : 0));

    //DEBUG("%d %ld+%d\n", r, trace_sent, len);

    if (lwip_err == ERR_MEM) {
        printf("bfscope: lwip: out of memory\n");
        return;
    }

    trace_sent += len;

    if (trace_sent >= trace_length) {
        /* No more events */
        uint64_t timestamp_stop = rdtsc();
        DEBUG("bfscope: done (%lu bytes) in %ld cycles\n",
               trace_sent, timestamp_stop - timestamp_start);

        bfscope_trace_dump_finished();
    }
}
コード例 #13
0
ファイル: echo-client.c プロジェクト: crazycoderx2/bitvisor
int
echo_client_send (void)
{
	err_t err;
	struct tcp_pcb *pcb = echo_client_pcb;
	int buflen;

	if (!echo_client_pcb) {
		printd ("No connection.\n");
		return -1;
	} else {
		printd ("Connection found.\n");
	}

	buflen = tcp_sndbuf (pcb);
	if (buflen >= strlen (send_buf)) {
		printd ("Space available: %d\n", buflen);
		err = tcp_write (pcb, send_buf, strlen (send_buf),
				 TCP_WRITE_FLAG_COPY);
		if (err == ERR_OK) {
			printd ("Enqueue succeeded.\n");
			err = tcp_output (pcb);
			if (err == ERR_OK) {
				printd ("Send succeeded.\n");
			} else {
				printd ("Send failed.\n");
				return -2;
			}
		} else {
			printd ("Enqueue failed.\n");
			return -3;
		}
	} else {
		printd ("Space unavailable: %d\n", buflen);
		return -4;
	}
	return 0;
}
コード例 #14
0
ファイル: point-stream.c プロジェクト: laserpic/j4cDAC
static int ps_send_deferred_acks(struct tcp_pcb *pcb) {

	int num = (ps_deferred_ack_produce + PS_DEFERRED_ACK_MAX
	           - ps_deferred_ack_consume) % PS_DEFERRED_ACK_MAX;
	if (num) {
		outputf("%d deferred acks\n", num);
	}

	int count = 0;
	int consume = ps_deferred_ack_consume;
	err_t err = 0;

	while (consume != ps_deferred_ack_produce) {
		struct dac_response response;
		response.response = ps_deferred_ack_queue[consume].resp;
		response.command = ps_deferred_ack_queue[consume].cmd;
		fill_status(&response.dac_status);

		err = tcp_write(pcb, &response, sizeof(response),
			TCP_WRITE_FLAG_COPY);

		if (err < 0)
			break;

		count++;
		consume = (consume + 1) % PS_DEFERRED_ACK_MAX;
	}

	ps_deferred_ack_consume = consume;

	if (err == ERR_MEM)
		err = 0;

	if (num)
		outputf("sent %d deferred acks, err %d", count, err);

	return err;
}
コード例 #15
0
ファイル: tcp_server.c プロジェクト: sdwuyawen/lwip_V1.3.2
//服务器连接成功后将要调用的函数
err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err){
		err_t ret_err;
		struct tcp_server_state* ts;
		
	  ts = mem_malloc(sizeof(struct tcp_server_state));	 //申请内存
		if(ts!=NULL){
				ts->state = ES_RECEIVED;							//可以接收数据了
			  lwip_flag |= LWIP_CONNECTED;				//已经连接上了
			  tcp_write(newpcb,respond,strlen(respond),1);  //回应信息
			
				tcp_arg(newpcb, ts);  				//将程序的协议控制块的状态传递给多有的回调函数

				tcp_recv(newpcb, tcp_server_recv);	//指定连接接收到新的数据之后将要调用的回调函数
				tcp_err(newpcb, tcp_server_error);	//指定连接出错将要调用的函数
				tcp_poll(newpcb, tcp_server_poll, 0); //指定轮询时将要调用的回调函数
				ret_err = ERR_OK;

		}else{
				ret_err = ERR_MEM;
		}
		return ret_err;
	
}
コード例 #16
0
// Sends the next chunk of data.
static void
send_data(struct tcp_pcb *pcb, struct http_state *hs)
{
    err_t err;
    u16_t len;
    
    CYG_TEST_INFO("Sending data");

    // We cannot send more data than space available in the send buffer
    len = tcp_sndbuf(pcb) < hs->left ? tcp_sndbuf(pcb) : hs->left;
    
    do {
        err = tcp_write(pcb, hs->file, len, 0);
        if (err == ERR_MEM) {
            len /= 2;
        }
    } while (err == ERR_MEM && len > 1);

    if (err == ERR_OK) {
        hs->file += len;
        hs->left -= len;
    }
}
コード例 #17
0
ファイル: usr_cpu.c プロジェクト: wangxubo1988/Center_System
/**
  * @brief  reply to the all user who is aliving. 
  * @param 
           *pcb: the poiter of the pcb struct. 
           *Cmd: the pointer of the 24byte date. 
  * @retval None
  */
static void Pcb_Write_ALL(const void *data)
{ 
  int try_times = 0; 
  int t = 0;
    	
  for(t = 0; t < 11; t++)
  {
    if(pad_info[t].user == TRUE && pad_info[t].pad_living>0) 
	{
	  if(pad_info[t].socket != sever_pcb)
	  {
	    while(tcp_write(pad_info[t].socket, data, 24, 1)!= ERR_OK && try_times < 500)
	    {
		    try_times++;
	  	  vTaskDelay(1);
	    }
	  }
    }
  }
  
  Pcb_Write_Sever(data);

}
コード例 #18
0
ファイル: EthernetClient.cpp プロジェクト: energia/tivac-core
size_t EthernetClient::write(const uint8_t *buf, size_t size) {
	uint32_t i = 0, inc = 0;
	boolean stuffed_buffer = false;

	struct tcp_pcb * cpcb = (tcp_pcb*)cs->cpcb; /* cs->cpcb may change to NULL during interrupt servicing */

	if (!cpcb)
		return 0;

	// Attempt to write in 1024-byte increments.
	while (i < size) {
		inc = (size - i) < 1024 ? size - i : 1024;
		err_t err = tcp_write(cpcb, buf + i, inc, TCP_WRITE_FLAG_COPY);
		if (err != ERR_MEM) {
			// Keep enqueueing the lwIP buffer until it's full...
			i += inc;
			stuffed_buffer = false;
		} else {
			if (!stuffed_buffer) {
				// Buffer full; force output
				if (cs->mode)
					tcp_output(cpcb);
				stuffed_buffer = true;
			} else {
				delay(1); // else wait a little bit for lwIP to flush its buffers
			}
		}
	}
	// flush any remaining queue contents
	if (!stuffed_buffer) {
		if (cs->mode)
			tcp_output(cpcb);
	}

	return size;
}
コード例 #19
0
ファイル: socket.c プロジェクト: eerimoq/simba
/**
 * This function is called when data has been acknowledged by the
 * remote endpoint.
 */
static err_t on_tcp_sent(void *arg_p,
                         struct tcp_pcb *pcb_p,
                         u16_t len)
{
    struct socket_t *socket_p = arg_p;
    struct send_to_args_t *args_p;
    size_t size;

    if (socket_p->output.cb.state == STATE_SENDTO) {
        args_p = socket_p->output.cb.args_p;
        size = MIN(args_p->extra.left,
                   tcp_sndbuf(((struct tcp_pcb *)socket_p->pcb_p)));

        if (tcp_write(socket_p->pcb_p,
                      args_p->buf_p,
                      size,
                      TCP_WRITE_FLAG_COPY) == ERR_OK) {
            args_p->buf_p += size;
            args_p->extra.left -= size;

            /* Resume if all data has been written. */
            if (args_p->extra.left == 0) {
                tcp_output(socket_p->pcb_p);
                socket_p->output.cb.state = STATE_IDLE;
                fs_counter_increment(&module.tcp_tx_bytes, args_p->size);
                resume_thrd(socket_p->output.cb.thrd_p, args_p->size);
            } else {
                socket_p->output.cb.state = STATE_SENDTO;
            }
        } else {
            resume_thrd(socket_p->output.cb.thrd_p, 0);
        }
    }

    return (ERR_OK);
}
コード例 #20
0
ファイル: lwipNetTcpSocket.cpp プロジェクト: TheGuv/Firmware
int /*if < 0 : NetTcpSocketErr*/ LwipNetTcpSocket::send(const char* buf, int len)
{
  if( !m_pPcb ) //Pcb doesn't exist (anymore)
    return NETTCPSOCKET_MEM;
  int outLen = MIN( len, tcp_sndbuf( (tcp_pcb*) m_pPcb) ); 
  //tcp_sndbuf() returns the number of bytes available in the output queue, so never go above it
  err_t err = tcp_write( (tcp_pcb*) m_pPcb, (void*) buf, outLen, TCP_WRITE_FLAG_COPY );
  //Flags are TCP_WRITE_FLAG_COPY & TCP_WRITE_FLAG_MORE (see tcp_out.c) :
  //If TCP_WRITE_FLAG_MORE is not set ask client to push buffered data to app
  if(err)
  {
    switch( err )
    {
    case ERR_CONN:
      return (int) NETTCPSOCKET_SETUP; //Not connected properly
    case ERR_ARG:
      return (int) NETTCPSOCKET_SETUP; //Wrong args ! (like buf pointing to NULL)
    case ERR_MEM:
    default:
      return (int) NETTCPSOCKET_MEM; //Not enough memory
    }
  }
  return outLen;
}
コード例 #21
0
static err_t
echo_recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
    /* do not read the packet if we are not in ESTABLISHED state */
    if (!p) {
        tcp_close(tpcb);
        tcp_recv(tpcb, NULL);
        return ERR_OK;
    }

    /* indicate that the packet has been received */
    tcp_recved(tpcb, p->len);

    /* echo back the payload */
    /* in this case, we assume that the payload is < TCP_SND_BUF */
    if (tcp_sndbuf(tpcb) > p->len) {
        err = tcp_write(tpcb, p->payload, p->len, 1);
    }

    /* free the received pbuf */
    pbuf_free(p);

    return ERR_OK;
}
コード例 #22
0
ファイル: telnetd.c プロジェクト: malooei/yeejoin-workspace
static void proc_rx_data(struct tcp_pcb * pcb, struct telnetio_dev *teldev, struct pbuf *p)
{
	struct pbuf *q;
	unsigned char *c;
	int num, i;

	TELNETD_DEBUG(("line:%d, %s()\n", __LINE__, __FUNCTION__));

	rt_sem_take(teldev->rx_rb_buf.rw_sem, RT_WAITING_FOREVER);
	for(q=p; NULL!=q; q=q->next) {
		c = q->payload;
		for(i=0; i<q->len; i++, c++)
			proc_rx_byte(pcb, teldev, *c);
	}
	rt_sem_release(teldev->rx_rb_buf.rw_sem);

	num = teldev->iac_index;
	if (0 != num) {
		tcp_write(pcb, teldev->iac_buf, num, TCP_WRITE_FLAG_COPY);
		teldev->iac_index = 0;
	}

	return;
}
コード例 #23
0
ファイル: device.c プロジェクト: ihipop/I-GNOKII
size_t device_write(const __ptr_t buf, size_t n, struct gn_statemachine *state)
{
	switch (state->device.type) {
	case GN_CT_DKU2:
	case GN_CT_Serial:
	case GN_CT_Infrared:
		return serial_write(state->device.fd, buf, n, state);
	case GN_CT_Irda:
		return irda_write(state->device.fd, buf, n, state);
	case GN_CT_Bluetooth:
		return bluetooth_write(state->device.fd, buf, n, state);
	case GN_CT_Tekram:
		return tekram_write(state->device.fd, buf, n, state);
	case GN_CT_TCP:
		return tcp_write(state->device.fd, buf, n, state);
	case GN_CT_DKU2LIBUSB:
		return fbusdku2usb_write(buf, n, state);
	case GN_CT_SOCKETPHONET:
		return socketphonet_write(state->device.fd, buf, n, state);
	default:
		break;
	}
	return 0;
}
コード例 #24
0
int TcpConnection::write(const char* data, int len, uint8_t apiflags /* = TCP_WRITE_FLAG_COPY*/)
{
   //int original = len;

   u16_t available = getAvailableWriteSize();
   if (available < len)
   {
	   if (available == 0)
		   return -1; // No memory
	   else
		   len = available;
   }

   err_t err = tcp_write(tcp, data, len, apiflags);

   if (err == ERR_OK)
   {
		debugf("TCP connection send: %d ", len);
		return len;
   } else {
		debugf("TCP connection failed with err %d ", err);
		return -1;
   }
}
コード例 #25
0
ファイル: api_msg.c プロジェクト: comrid1987/jb3500
/**
 * See if more data needs to be written from a previous call to netconn_write.
 * Called initially from do_write. If the first call can't send all data
 * (because of low memory or empty send-buffer), this function is called again
 * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the
 * blocking application thread (waiting in netconn_write) is released.
 *
 * @param conn netconn (that is currently in state NETCONN_WRITE) to process
 * @return ERR_OK
 *         ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
 */
static err_t
do_writemore(struct netconn *conn)
{
    err_t err;
    void *dataptr;
    u16_t len, available;
    u8_t write_finished = 0;
    size_t diff;
    u8_t dontblock = netconn_is_nonblocking(conn) ||
                     (conn->current_msg->msg.w.apiflags & NETCONN_DONTBLOCK);
    u8_t apiflags = conn->current_msg->msg.w.apiflags;

    LWIP_ASSERT("conn != NULL", conn != NULL);
    LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
    LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
    LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
    LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len",
                conn->write_offset < conn->current_msg->msg.w.len);

#if LWIP_SO_SNDTIMEO
    if ((conn->send_timeout != 0) &&
            ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
        write_finished = 1;
        if (conn->write_offset == 0) {
            /* nothing has been written */
            err = ERR_WOULDBLOCK;
            conn->current_msg->msg.w.len = 0;
        } else {
            /* partial write */
            err = ERR_OK;
            conn->current_msg->msg.w.len = conn->write_offset;
        }
    } else
#endif /* LWIP_SO_SNDTIMEO */
    {
        dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
        diff = conn->current_msg->msg.w.len - conn->write_offset;
        if (diff > 0xffffUL) { /* max_u16_t */
            len = 0xffff;
#if LWIP_TCPIP_CORE_LOCKING
            conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
#endif
            apiflags |= TCP_WRITE_FLAG_MORE;
        } else {
            len = (u16_t)diff;
        }
        available = tcp_sndbuf(conn->pcb.tcp);
        if (available < len) {
            /* don't try to write more than sendbuf */
            len = available;
            if (dontblock) {
                if (!len) {
                    err = ERR_WOULDBLOCK;
                    goto err_mem;
                }
            } else {
#if LWIP_TCPIP_CORE_LOCKING
                conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
#endif
                apiflags |= TCP_WRITE_FLAG_MORE;
            }
        }
        LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len));
        err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);
        /* if OK or memory error, check available space */
        if ((err == ERR_OK) || (err == ERR_MEM)) {
err_mem:
            if (dontblock && (len < conn->current_msg->msg.w.len)) {
                /* non-blocking write did not write everything: mark the pcb non-writable
                   and let poll_tcp check writable space to mark the pcb writable again */
                API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
                conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
            } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
                       (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
                /* The queued byte- or pbuf-count exceeds the configured low-water limit,
                   let select mark this pcb as non-writable. */
                API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
            }
        }

        if (err == ERR_OK) {
            conn->write_offset += len;
            if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) {
                /* return sent length */
                conn->current_msg->msg.w.len = conn->write_offset;
                /* everything was written */
                write_finished = 1;
                conn->write_offset = 0;
            }
            tcp_output(conn->pcb.tcp);
        } else if ((err == ERR_MEM) && !dontblock) {
            /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
               we do NOT return to the application thread, since ERR_MEM is
               only a temporary error! */

            /* tcp_write returned ERR_MEM, try tcp_output anyway */
            tcp_output(conn->pcb.tcp);

#if LWIP_TCPIP_CORE_LOCKING
            conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
#endif
        } else {
            /* On errors != ERR_MEM, we don't try writing any more but return
               the error to the application thread. */
            write_finished = 1;
            conn->current_msg->msg.w.len = 0;
        }
    }
    if (write_finished) {
        /* everything was written: set back connection state
           and back to application task */
        conn->current_msg->err = err;
        conn->current_msg = NULL;
        conn->state = NETCONN_NONE;
#if LWIP_TCPIP_CORE_LOCKING
        if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0)
#endif
        {
            sys_sem_signal(&conn->op_completed);
        }
    }
#if LWIP_TCPIP_CORE_LOCKING
    else
        return ERR_MEM;
#endif
    return ERR_OK;
}
コード例 #26
0
ファイル: stream_engine.cpp プロジェクト: HJoYer/libzmq
void zmq::stream_engine_t::out_event ()
{
    zmq_assert (!io_error);

    //  If write buffer is empty, try to read new data from the encoder.
    if (!outsize) {

        //  Even when we stop polling as soon as there is no
        //  data to send, the poller may invoke out_event one
        //  more time due to 'speculative write' optimisation.
        if (unlikely (encoder == NULL)) {
            zmq_assert (handshaking);
            return;
        }

        outpos = NULL;
        outsize = encoder->encode (&outpos, 0);

        while (outsize < out_batch_size) {
            if ((this->*next_msg) (&tx_msg) == -1)
                break;
            encoder->load_msg (&tx_msg);
            unsigned char *bufptr = outpos + outsize;
            size_t n = encoder->encode (&bufptr, out_batch_size - outsize);
            zmq_assert (n > 0);
            if (outpos == NULL)
                outpos = bufptr;
            outsize += n;
        }

        //  If there is no data to send, stop polling for output.
        if (outsize == 0) {
            output_stopped = true;
            reset_pollout (handle);
            return;
        }
    }

    //  If there are any data to write in write buffer, write as much as
    //  possible to the socket. Note that amount of data to write can be
    //  arbitrarily large. However, we assume that underlying TCP layer has
    //  limited transmission buffer and thus the actual number of bytes
    //  written should be reasonably modest.
    const int nbytes = tcp_write (s, outpos, outsize);

    //  IO error has occurred. We stop waiting for output events.
    //  The engine is not terminated until we detect input error;
    //  this is necessary to prevent losing incoming messages.
    if (nbytes == -1) {
        reset_pollout (handle);
        return;
    }

    outpos += nbytes;
    outsize -= nbytes;

    //  If we are still handshaking and there are no data
    //  to send, stop polling for output.
    if (unlikely (handshaking))
        if (outsize == 0)
            reset_pollout (handle);
}
コード例 #27
0
int transfer_data() {
    uint16_t data[1900];
    tcp_write(pcb, data, sizeof(data)/ sizeof(*data),0); // send some data
    return 0;
}
コード例 #28
0
ファイル: httpclient.c プロジェクト: sun182/therme
// lwip calls this function when the connection is established
static err_t hc_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
    struct hc_state *hcstate = arg;
    char  * headers;
 
    // error?
    if(err != ERR_OK)
    {
        hc_clearpcb(pcb);
 
        // Call return function
        (*hcstate->ReturnPage)(hcstate->Num, GEN_ERROR, NULL, 0);
 
        // Free wc hcstate
        free(hcstate->RecvData);
        free(hcstate);
 
        return(ERR_OK);
    }
 
    // Define Headers
    if(hcstate->PostVars == NULL)
    {	
        // GET headers (without page)(+ \0) = 19
        headers = malloc(19 + strlen(hcstate->Page));
        sprintf(headers,"GET /%s HTTP/1.0\r\n\r\n", hcstate->Page);
    }
    else
    {
        // POST headers (without PostVars or Page)(+ \0) = 91
        // Content-length: %d <== 						   ??? (max 10)
        headers = malloc(91 + strlen(hcstate->PostVars) + strlen(hcstate->Page) + 10);
        sprintf(headers, "POST /%s HTTP/1.0\r\nContent-type: application/x-www-form-urlencoded\r\nContent-length: %d\r\n\r\n%s\r\n\r\n", hcstate->Page, strlen(hcstate->PostVars), hcstate->PostVars);
    }
 
    // Check if we are nut running out of memory
    if(headers == NULL)
    {
        hc_clearpcb(pcb);
 
        // Call return function
        (*hcstate->ReturnPage)(hcstate->Num, OUT_MEM, NULL, 0);
 
        // Free wc hcstate
        free(hcstate->RecvData);
        free(hcstate);
 
        return(ERR_OK);
    }
 

 
    // Send data
    tcp_write(pcb, headers, strlen(headers), 1);
    tcp_output(pcb);
 
    // remove headers
    free(headers);
    free(hcstate->PostVars);			// postvars are send, so we don't need them anymore
    free(hcstate->Page);		    	        // page is requested, so we don't need it anymore
 
    return(ERR_OK);
}
コード例 #29
0
/**
 * See if more data needs to be written from a previous call to netconn_write.
 * Called initially from do_write. If the first call can't send all data
 * (because of low memory or empty send-buffer), this function is called again
 * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the
 * blocking application thread (waiting in netconn_write) is released.
 *
 * @param conn netconn (that is currently in state NETCONN_WRITE) to process
 * @return ERR_OK
 *         ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
 */
static err_t
do_writemore(struct netconn *conn)
{
  err_t err;
  void *dataptr;
  u16_t len, available;
  u8_t write_finished = 0;
  size_t diff;

  LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));

  dataptr = (u8_t*)conn->write_msg->msg.w.dataptr + conn->write_offset;
  diff = conn->write_msg->msg.w.len - conn->write_offset;
  if (diff > 0xffffUL) { /* max_u16_t */
    len = 0xffff;
#if LWIP_TCPIP_CORE_LOCKING
    conn->write_delayed = 1;
#endif
  } else {
    len = (u16_t)diff;
  }
  available = tcp_sndbuf(conn->pcb.tcp);
  if (available < len) {
    /* don't try to write more than sendbuf */
    len = available;
#if LWIP_TCPIP_CORE_LOCKING
    conn->write_delayed = 1;
#endif
  }

  err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags);
  LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len));
  if (err == ERR_OK) {
    conn->write_offset += len;
    if (conn->write_offset == conn->write_msg->msg.w.len) {
      /* everything was written */
      write_finished = 1;
      conn->write_msg = NULL;
      conn->write_offset = 0;
      /* API_EVENT might call tcp_tmr, so reset conn->state now */
      conn->state = NETCONN_NONE;
    }
    err = tcp_output_nagle(conn->pcb.tcp);
    conn->err = err;
    if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) {
      API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
    }
  } else if (err == ERR_MEM) {
    /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
       we do NOT return to the application thread, since ERR_MEM is
       only a temporary error! */

    /* tcp_enqueue returned ERR_MEM, try tcp_output anyway */
    err = tcp_output(conn->pcb.tcp);

    //[MS_CHANGE] - return failure on output
    conn->err = ERR_MEM;
    write_finished = 1;

#if LWIP_TCPIP_CORE_LOCKING
    conn->write_delayed = 1;
#endif
  } else {
    /* On errors != ERR_MEM, we don't try writing any more but return
       the error to the application thread. */
    conn->err = err;
    write_finished = 1;
  }

  if (write_finished) {
    /* everything was written: set back connection state
       and back to application task */
    conn->state = NETCONN_NONE;
#if LWIP_TCPIP_CORE_LOCKING
    if (conn->write_delayed != 0)
#endif
    {
      sys_sem_signal(conn->op_completed);
    }
  }
#if LWIP_TCPIP_CORE_LOCKING
  else
    return ERR_MEM;
#endif
  return ERR_OK;
}
コード例 #30
0
ファイル: cos_net.c プロジェクト: songjiguo/C3
int net_send(spdid_t spdid, net_connection_t nc, void *data, int sz)
{
	struct intern_connection *ic;
	u16_t tid = cos_get_thd_id();
	int ret = sz;

//	if (!cos_argreg_buff_intern(data, sz)) return -EFAULT;
	if (!net_conn_valid(nc)) return -EINVAL;
	if (sz > MAX_SEND) return -EMSGSIZE;

//	NET_LOCK_TAKE();
	ic = net_conn_get_internal(nc);
	if (NULL == ic) {
		ret = -EINVAL;
		goto err;
	}
	if (tid != ic->tid) {
		ret = -EPERM;
		goto err;
	}

	switch (ic->conn_type) {
	case UDP:
	{
		struct udp_pcb *up;
		struct pbuf *p;

		/* There's no blocking in the UDP case, so this is simple */
		up = ic->conn.up;
		p = pbuf_alloc(PBUF_TRANSPORT, sz, PBUF_ROM);
		if (NULL == p) {
			ret = -ENOMEM;
			goto err;
		}
		p->payload = data;

		if (ERR_OK != udp_send(up, p)) {
			pbuf_free(p);
			/* IP/port must not be set */
			ret = -ENOTCONN;
			goto err;
		}
		pbuf_free(p);
		break;
	}
	case TCP:
	{
		struct tcp_pcb *tp;
#define TCP_SEND_COPY
#ifdef TCP_SEND_COPY
		void *d;
		struct packet_queue *pq;
#endif
		tp = ic->conn.tp;
		if (tcp_sndbuf(tp) < sz) { 
			ret = 0;
			break;
		}
#ifdef TCP_SEND_COPY
		pq = malloc(sizeof(struct packet_queue) + sz);
		if (unlikely(NULL == pq)) {
			ret = -ENOMEM;
			goto err;
		}
#ifdef TEST_TIMING
		pq->ts_start = timing_record(APP_PROC, ic->ts_start);
#endif
		pq->headers = NULL;
		d = net_packet_data(pq);
		memcpy(d, data, sz);
		if (ERR_OK != (ret = tcp_write(tp, d, sz, 0))) {
#else
		if (ERR_OK != (ret = tcp_write(tp, data, sz, TCP_WRITE_FLAG_COPY))) {
#endif
			free(pq);
			printc("tcp_write returned %d (sz %d, tcp_sndbuf %d, ERR_MEM: %d)", 
			       ret, sz, tcp_sndbuf(tp), ERR_MEM);
			BUG();
		}
		/* No implementation of nagle's algorithm yet.  Send
		 * out the packet immediately if possible. */
		if (ERR_OK != (ret = tcp_output(tp))) {
			printc("tcp_output returned %d, ERR_MEM: %d", ret, ERR_MEM);
			BUG();
		}
		ret = sz;

		break;
	}
	case TCP_CLOSED:
		ret = -EPIPE;
		break;
	default:
		BUG();
	}
err:
//	NET_LOCK_RELEASE();
	return ret;
}

/************************ LWIP integration: **************************/

struct ip_addr ip, mask, gw;
struct netif   cos_if;

static void cos_net_interrupt(char *packet, int sz)
{
	void *d;
	int len;
	struct pbuf *p;
	struct ip_hdr *ih;
	struct packet_queue *pq;
#ifdef TEST_TIMING
	unsigned long long ts;
#endif
//	printc(">>> %d\n", net_lock.lock_id);
	NET_LOCK_TAKE();
//	printc("<<< %d\n", net_lock.lock_id);

	assert(packet);
	ih = (struct ip_hdr*)packet;
	if (unlikely(4 != IPH_V(ih))) goto done;
	len = ntohs(IPH_LEN(ih));
	if (unlikely(len != sz || len > MTU)) {
		printc("len %d != %d or > %d", len, sz, MTU);
		goto done;
	}

	p = pbuf_alloc(PBUF_IP, len, PBUF_ROM);
	if (unlikely(!p)) {
		prints("OOM in interrupt: allocation of pbuf failed.\n");
		goto done;
	}

	/* For now, we're going to do an additional copy.  Currently,
	 * packets should be small, so this shouldn't hurt that badly.
	 * This is done because 1) we are freeing the packet
	 * elsewhere, 2) we want to malloc some (small) packets to
	 * save space and free up the ring buffers, 3) it is difficult
	 * to know in (1) which deallocation method (free or return to
	 * ring buff) to use */
	pq = malloc(len + sizeof(struct packet_queue));
	if (unlikely(NULL == pq)) {
		printc("OOM in interrupt: allocation of packet data (%d bytes) failed.\n", len);
		pbuf_free(p);
		goto done;
	}
	pq->headers = d = net_packet_data(pq);
#ifdef TEST_TIMING
#ifdef TCP_SEND_COPY
	ts = pq->ts_start = timing_timestamp();
#endif	
#endif	
	memcpy(d, packet, len);
	p->payload = p->alloc_track = d;
	/* hand off packet ownership here... */
	if (ERR_OK != cos_if.input(p, &cos_if)) {
		prints("net: failure in IP input.");
		pbuf_free(p);
		goto done;
	}

#ifdef TEST_TIMING
	timing_record(UPCALL_PROC, ts);
#endif
done:
	NET_LOCK_RELEASE();
	return;
}