source: mainline/uspace/app/nterm/conn.c@ 80d9d83

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 80d9d83 was 0aa70f4, checked in by Martin Decky <martin@…>, 12 years ago

support for IPv6 DNS name resolution (AAAA)
if the desired address family of the DNS query is not explicitly specified, then IPv6 addresses take precendece over IPv4 addresses

  • Property mode set to 100644
File size: 3.7 KB
RevLine 
[01a7aa1]1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup nterm
30 * @{
31 */
32/** @file
33 */
34
[287d729]35#include <byteorder.h>
[3e6a98c5]36#include <stdbool.h>
[01a7aa1]37#include <errno.h>
38#include <fibril.h>
[287d729]39#include <inet/dnsr.h>
[01a7aa1]40#include <net/socket.h>
41#include <stdio.h>
[7c912b6]42#include <str_error.h>
[01a7aa1]43#include <sys/types.h>
44
45#include "conn.h"
46#include "nterm.h"
47
48static int conn_fd;
49static fid_t rcv_fid;
50
[7c912b6]51#define RECV_BUF_SIZE 1024
[01a7aa1]52static uint8_t recv_buf[RECV_BUF_SIZE];
53
54static int rcv_fibril(void *arg)
55{
56 ssize_t nr;
57
58 while (true) {
59 nr = recv(conn_fd, recv_buf, RECV_BUF_SIZE, 0);
60 if (nr < 0)
61 break;
62
63 nterm_received(recv_buf, nr);
64 }
65
[7c912b6]66 if (nr == ENOTCONN)
67 printf("\n[Other side has closed the connection]\n");
68 else
69 printf("'\n[Receive errror (%s)]\n", str_error(nr));
[01a7aa1]70
[0d67e16]71 exit(0);
[01a7aa1]72 return 0;
73}
74
75int conn_open(const char *addr_s, const char *port_s)
76{
[02a09ed]77 int conn_fd = -1;
78
79 /* Interpret as address */
80 inet_addr_t addr_addr;
81 int rc = inet_addr_parse(addr_s, &addr_addr);
82
[01a7aa1]83 if (rc != EOK) {
[02a09ed]84 /* Interpret as a host name */
85 dnsr_hostinfo_t *hinfo = NULL;
[0aa70f4]86 rc = dnsr_name2host(addr_s, &hinfo, 0);
[02a09ed]87
[287d729]88 if (rc != EOK) {
89 printf("Error resolving host '%s'.\n", addr_s);
90 goto error;
91 }
[3e66428]92
[02a09ed]93 addr_addr = hinfo->addr;
[01a7aa1]94 }
[02a09ed]95
96 struct sockaddr_in addr;
97 struct sockaddr_in6 addr6;
98 uint16_t af = inet_addr_sockaddr_in(&addr_addr, &addr, &addr6);
99
100 char *endptr;
101 uint16_t port = strtol(port_s, &endptr, 10);
[01a7aa1]102 if (*endptr != '\0') {
103 printf("Invalid port number %s\n", port_s);
[287d729]104 goto error;
[01a7aa1]105 }
[b5cf742a]106
[02a09ed]107 printf("Connecting to host %s port %u\n", addr_s, port);
108
[01a7aa1]109 conn_fd = socket(PF_INET, SOCK_STREAM, 0);
110 if (conn_fd < 0)
111 goto error;
[b5cf742a]112
[02a09ed]113 switch (af) {
114 case AF_INET:
115 addr.sin_port = htons(port);
116 rc = connect(conn_fd, (struct sockaddr *) &addr, sizeof(addr));
117 break;
118 case AF_INET6:
119 addr6.sin6_port = htons(port);
120 rc = connect(conn_fd, (struct sockaddr *) &addr6, sizeof(addr6));
121 break;
122 default:
123 printf("Unknown address family.\n");
124 goto error;
125 }
[b5cf742a]126
[01a7aa1]127 if (rc != EOK)
128 goto error;
[b5cf742a]129
[01a7aa1]130 rcv_fid = fibril_create(rcv_fibril, NULL);
131 if (rcv_fid == 0)
132 goto error;
[b5cf742a]133
[01a7aa1]134 fibril_add_ready(rcv_fid);
[b5cf742a]135
[01a7aa1]136 return EOK;
[b5cf742a]137
[01a7aa1]138error:
139 if (conn_fd >= 0) {
140 closesocket(conn_fd);
141 conn_fd = -1;
142 }
[b5cf742a]143
[01a7aa1]144 return EIO;
145}
146
147int conn_send(void *data, size_t size)
148{
[b5cf742a]149 int rc = send(conn_fd, data, size, 0);
[01a7aa1]150 if (rc != EOK)
151 return EIO;
[b5cf742a]152
[01a7aa1]153 return EOK;
154}
155
156/** @}
157 */
Note: See TracBrowser for help on using the repository browser.