Revision c12504ce nbd.c

b/nbd.c
107 107
    return offset;
108 108
}
109 109

  
110
int tcp_socket_outgoing(const char *address, uint16_t port)
110
static void combine_addr(char *buf, size_t len, const char* address,
111
                         uint16_t port)
111 112
{
112
    int s;
113
    struct in_addr in;
114
    struct sockaddr_in addr;
115

  
116
    s = socket(PF_INET, SOCK_STREAM, 0);
117
    if (s == -1) {
118
        return -1;
119
    }
120

  
121
    if (inet_aton(address, &in) == 0) {
122
        struct hostent *ent;
123

  
124
        ent = gethostbyname(address);
125
        if (ent == NULL) {
126
            goto error;
127
        }
128

  
129
        memcpy(&in, ent->h_addr, sizeof(in));
130
    }
131

  
132
    addr.sin_family = AF_INET;
133
    addr.sin_port = htons(port);
134
    memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
135

  
136
    if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
137
        goto error;
113
    /* If the address-part contains a colon, it's an IPv6 IP so needs [] */
114
    if (strstr(address, ":")) {
115
        snprintf(buf, len, "[%s]:%u", address, port);
116
    } else {
117
        snprintf(buf, len, "%s:%u", address, port);
138 118
    }
139

  
140
    return s;
141
error:
142
    closesocket(s);
143
    return -1;
144 119
}
145 120

  
146
int tcp_socket_incoming(const char *address, uint16_t port)
121
int tcp_socket_outgoing(const char *address, uint16_t port)
147 122
{
148
    int s;
149
    struct in_addr in;
150
    struct sockaddr_in addr;
151
    int opt;
152

  
153
    s = socket(PF_INET, SOCK_STREAM, 0);
154
    if (s == -1) {
155
        return -1;
156
    }
157

  
158
    if (inet_aton(address, &in) == 0) {
159
        struct hostent *ent;
160

  
161
        ent = gethostbyname(address);
162
        if (ent == NULL) {
163
            goto error;
164
        }
165

  
166
        memcpy(&in, ent->h_addr, sizeof(in));
167
    }
168

  
169
    addr.sin_family = AF_INET;
170
    addr.sin_port = htons(port);
171
    memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
172

  
173
    opt = 1;
174
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
175
                   (const void *) &opt, sizeof(opt)) == -1) {
176
        goto error;
177
    }
178

  
179
    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
180
        goto error;
181
    }
182

  
183
    if (listen(s, 128) == -1) {
184
        goto error;
185
    }
186

  
187
    return s;
188
error:
189
    closesocket(s);
190
    return -1;
123
    char address_and_port[128];
124
    combine_addr(address_and_port, 128, address, port);
125
    return tcp_socket_outgoing_spec(address_and_port);
191 126
}
192 127

  
193
#ifndef _WIN32
194
int unix_socket_incoming(const char *path)
128
int tcp_socket_outgoing_spec(const char *address_and_port)
195 129
{
196
    int s;
197
    struct sockaddr_un addr;
198

  
199
    s = socket(PF_UNIX, SOCK_STREAM, 0);
200
    if (s == -1) {
201
        return -1;
202
    }
203

  
204
    memset(&addr, 0, sizeof(addr));
205
    addr.sun_family = AF_UNIX;
206
    pstrcpy(addr.sun_path, sizeof(addr.sun_path), path);
207

  
208
    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
209
        goto error;
210
    }
211

  
212
    if (listen(s, 128) == -1) {
213
        goto error;
214
    }
215

  
216
    return s;
217
error:
218
    closesocket(s);
219
    return -1;
130
    return inet_connect(address_and_port, SOCK_STREAM);
220 131
}
221 132

  
222
int unix_socket_outgoing(const char *path)
133
int tcp_socket_incoming(const char *address, uint16_t port)
223 134
{
224
    int s;
225
    struct sockaddr_un addr;
226

  
227
    s = socket(PF_UNIX, SOCK_STREAM, 0);
228
    if (s == -1) {
229
        return -1;
230
    }
231

  
232
    memset(&addr, 0, sizeof(addr));
233
    addr.sun_family = AF_UNIX;
234
    pstrcpy(addr.sun_path, sizeof(addr.sun_path), path);
235

  
236
    if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
237
        goto error;
238
    }
135
    char address_and_port[128];
136
    combine_addr(address_and_port, 128, address, port);
137
    return tcp_socket_incoming_spec(address_and_port);
138
}
239 139

  
240
    return s;
241
error:
242
    closesocket(s);
243
    return -1;
140
int tcp_socket_incoming_spec(const char *address_and_port)
141
{
142
    char *ostr  = NULL;
143
    int olen = 0;
144
    return inet_listen(address_and_port, ostr, olen, SOCK_STREAM, 0);
244 145
}
245
#else
146

  
246 147
int unix_socket_incoming(const char *path)
247 148
{
248
    errno = ENOTSUP;
249
    return -1;
149
    char *ostr = NULL;
150
    int olen = 0;
151

  
152
    return unix_listen(path, ostr, olen);
250 153
}
251 154

  
252 155
int unix_socket_outgoing(const char *path)
253 156
{
254
    errno = ENOTSUP;
255
    return -1;
157
    return unix_connect(path);
256 158
}
257
#endif
258

  
259 159

  
260 160
/* Basic flow
261 161

  

Also available in: Unified diff