Subversion Repositories SvarDOS

Rev

Rev 333 | Rev 616 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
207 mateuszvis 1
/*
2
 * This file is part of the pkgnet package - the SvarDOS package manager.
3
 * Copyright (C) Mateusz Viste 2013-2021
4
 *
5
 * Provides all network functions used by pkgnet, wrapped around the
6
 * Watt-32 TCP/IP stack.
7
 */
8
 
9
#include <stdlib.h>
10
 
11
/* Watt32 */
12
#include <tcp.h>
13
 
14
#include "net.h" /* include self for control */
15
 
16
 
335 mateuszvis 17
/* if there is enough memory, net_connect() will try setting up a tcp window
18
 * larger than the WATT32's default of only 2K
19
 * on my system's DOSEMU install the relation between tcp buffer and download
20
 * speed were measured as follows (this is on a 4 Mbps ADSL link):
21
 *  2K = 20 KiB/s
22
 *  4K = 51 KiB/s
23
 *  8K = 67 KiB/s
24
 *  9K = 98 KiB/s
25
 * 10K = 98 KiB/s
26
 * 16K = 96 KiB/s
27
 * 32K = 98 KiB/s
28
 * 60K = 98 KiB/s
29
 */
30
#define TCPBUFF_SIZE (16 * 1024)
31
 
32
 
333 mateuszvis 33
struct net_tcpsocket {
34
  tcp_Socket *sock;
35
  tcp_Socket _sock; /* watt32 socket */
335 mateuszvis 36
  char tcpbuff[1];
333 mateuszvis 37
};
38
 
39
 
207 mateuszvis 40
int net_dnsresolve(char *ip, const char *name) {
41
  unsigned long ipnum;
42
  ipnum = resolve(name); /* I could use WatTCP's lookup_host() here to do all
43
                            the job for me, unfortunately lookup_host() issues
44
                            wild outs() calls putting garbage on screen... */
45
  if (ipnum == 0) return(-1);
46
  _inet_ntoa(ip, ipnum); /* convert to string */
47
  return(0);
48
}
49
 
50
 
51
static int dummy_printf(const char * format, ...) {
52
  if (format == NULL) return(-1);
53
  return(0);
54
}
55
 
56
 
57
/* must be called before using libtcp. returns 0 on success, or non-zero if network subsystem is not available. */
58
int net_init(void) {
59
  tzset();
60
  _printf = dummy_printf;  /* this is to avoid watt32 printing its stuff to console */
61
  return(sock_init());
62
}
63
 
64
 
65
struct net_tcpsocket *net_connect(const char *ipstr, unsigned short port) {
335 mateuszvis 66
  struct net_tcpsocket *resultsock, *resizsock;
207 mateuszvis 67
  unsigned long ipaddr;
68
 
69
  /* convert ip to value */
70
  ipaddr = _inet_addr(ipstr);
71
  if (ipaddr == 0) return(NULL);
72
 
333 mateuszvis 73
  resultsock = calloc(sizeof(struct net_tcpsocket), 1);
207 mateuszvis 74
  if (resultsock == NULL) return(NULL);
333 mateuszvis 75
  resultsock->sock = &(resultsock->_sock);
207 mateuszvis 76
 
77
  if (!tcp_open(resultsock->sock, 0, ipaddr, port, NULL)) {
78
    sock_abort(resultsock->sock);
79
    free(resultsock);
80
    return(NULL);
81
  }
82
 
335 mateuszvis 83
  /* set user-managed buffer if possible (watt32's default is only 2K)
84
   * this must be set AFTER tcp_open(), since the latter rewrites the tcp
85
   * rx buffer */
86
  resizsock = realloc(resultsock, sizeof(struct net_tcpsocket) + TCPBUFF_SIZE);
87
  if (resizsock != NULL) {
88
    resultsock = resizsock;
89
    sock_setbuf(resultsock->sock, resultsock->tcpbuff, TCPBUFF_SIZE);
90
  }
91
 
207 mateuszvis 92
  return(resultsock);
93
}
94
 
95
 
329 mateuszvis 96
int net_isconnected(struct net_tcpsocket *s) {
207 mateuszvis 97
  if (tcp_tick(s->sock) == 0) return(-1);
98
  if (sock_established(s->sock) == 0) return(0);
99
  return(1);
100
}
101
 
102
 
103
/* Sends data on socket 'socket'.
104
   Returns the number of bytes sent on success, and < 0 otherwise */
329 mateuszvis 105
int net_send(struct net_tcpsocket *socket, const void *line, long len) {
207 mateuszvis 106
  /* call this to let Watt-32 handle its internal stuff */
107
  if (tcp_tick(socket->sock) == 0) return(-1);
108
  /* send bytes */
329 mateuszvis 109
  return(sock_write(socket->sock, line, len));
207 mateuszvis 110
}
111
 
112
 
113
/* Reads data from socket 'sock' and write it into buffer 'buff', until end of connection. Will fall into error if the amount of data is bigger than 'maxlen' bytes.
114
Returns the amount of data read (in bytes) on success, or a negative value otherwise. The error code can be translated into a human error message via libtcp_strerr(). */
329 mateuszvis 115
int net_recv(struct net_tcpsocket *socket, void *buff, long maxlen) {
207 mateuszvis 116
  /* call this to let WatTCP handle its internal stuff */
117
  if (tcp_tick(socket->sock) == 0) return(-1);
329 mateuszvis 118
  return(sock_fastread(socket->sock, buff, maxlen));
207 mateuszvis 119
}
120
 
121
 
122
/* Close the 'sock' socket. */
123
void net_close(struct net_tcpsocket *socket) {
124
  /* I could use sock_close() and sock_wait_closed() if I'd want to be
125
   * friendly, but it's much easier on the tcp stack to send a single RST and
126
   * forget about the connection (esp. if the peer is misbehaving) */
127
  sock_abort(socket->sock);
128
  free(socket);
129
}
130
 
131
 
132
const char *net_engine(void) {
133
  return(wattcpVersion());
134
}