Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
74a39c71
Commit
74a39c71
authored
Aug 30, 2011
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntp_server: move code to udp_server.c
parent
19549633
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
219 additions
and
142 deletions
+219
-142
Makefile.am
Makefile.am
+3
-0
ntp_server.c
src/ntp_server.c
+25
-54
ntp_server.h
src/ntp_server.h
+3
-5
raop_output_plugin.c
src/output/raop_output_plugin.c
+1
-5
udp_server.c
src/udp_server.c
+130
-0
udp_server.h
src/udp_server.h
+52
-0
run_ntp_server.c
test/run_ntp_server.c
+5
-78
No files found.
Makefile.am
View file @
74a39c71
...
...
@@ -294,6 +294,7 @@ src_mpd_SOURCES = \
src/client_message.c
\
src/client_subscribe.h
\
src/client_subscribe.c
\
src/udp_server.c src/udp_server.h
\
src/server_socket.c
\
src/listen.c
\
src/log.c
\
...
...
@@ -1016,6 +1017,7 @@ test_run_ntp_server_LDADD = $(MPD_LIBS) \
test_run_ntp_server_SOURCES
=
test
/run_ntp_server.c
\
test
/signals.c
test
/signals.h
\
src/io_thread.c src/io_thread.h
\
src/udp_server.c src/udp_server.h
\
src/ntp_server.c src/ntp_server.h
test_run_filter_CPPFLAGS
=
$(AM_CPPFLAGS)
...
...
@@ -1122,6 +1124,7 @@ test_run_output_SOURCES = test/run_output.c \
test
/stdbin.h
\
src/conf.c src/tokenizer.c src/utils.c src/string_util.c src/log.c
\
src/io_thread.c src/io_thread.h
\
src/udp_server.c src/udp_server.h
\
src/audio_check.c
\
src/audio_format.c
\
src/audio_parser.c
\
...
...
src/ntp_server.c
View file @
74a39c71
...
...
@@ -18,7 +18,7 @@
*/
#include "ntp_server.h"
#include "
io_thread
.h"
#include "
udp_server
.h"
#include <glib.h>
#include <assert.h>
...
...
@@ -76,18 +76,18 @@ fill_time_buffer(unsigned char *buffer)
fill_time_buffer_with_time
(
buffer
,
&
current_time
);
}
static
bool
ntp_server_handle
(
struct
ntp_server
*
ntp
)
static
void
ntp_server_datagram
(
int
fd
,
const
void
*
data
,
size_t
num_bytes
,
const
struct
sockaddr
*
source_address
,
size_t
source_address_length
,
G_GNUC_UNUSED
void
*
ctx
)
{
unsigned
char
buf
[
32
];
struct
sockaddr
addr
;
int
iter
;
socklen_t
addr_len
=
sizeof
(
addr
);
ssize_t
num_bytes
=
recvfrom
(
ntp
->
fd
,
(
void
*
)
buf
,
sizeof
(
buf
),
0
,
&
addr
,
&
addr_len
);
if
(
num_bytes
==
0
)
{
return
false
;
}
if
(
num_bytes
>
sizeof
(
buf
))
num_bytes
=
sizeof
(
buf
);
memcpy
(
buf
,
data
,
num_bytes
);
fill_time_buffer
(
buf
+
16
);
// set to response
buf
[
1
]
=
0xd3
;
...
...
@@ -97,65 +97,36 @@ ntp_server_handle(struct ntp_server *ntp)
}
fill_time_buffer
(
buf
+
24
);
num_bytes
=
sendto
(
ntp
->
fd
,
(
void
*
)
buf
,
num_bytes
,
0
,
&
addr
,
addr_len
);
return
num_bytes
==
sizeof
(
buf
);
sendto
(
fd
,
(
void
*
)
buf
,
num_bytes
,
0
,
source_address
,
source_address_length
);
}
static
gboolean
ntp_in_event
(
G_GNUC_UNUSED
GIOChannel
*
source
,
G_GNUC_UNUSED
GIOCondition
condition
,
gpointer
data
)
{
struct
ntp_server
*
ntp
=
data
;
ntp_server_handle
(
ntp
);
return
true
;
}
static
const
struct
udp_server_handler
ntp_server_handler
=
{
.
datagram
=
ntp_server_datagram
,
};
void
ntp_server_init
(
struct
ntp_server
*
ntp
)
{
ntp
->
port
=
6002
;
ntp
->
fd
=
-
1
;
ntp
->
udp
=
NULL
;
}
void
ntp_server_open
(
struct
ntp_server
*
ntp
,
int
fd
)
bool
ntp_server_open
(
struct
ntp_server
*
ntp
,
GError
**
error_r
)
{
assert
(
ntp
->
fd
<
0
);
assert
(
fd
>=
0
);
assert
(
ntp
->
udp
==
NULL
);
ntp
->
fd
=
fd
;
#ifndef G_OS_WIN32
ntp
->
channel
=
g_io_channel_unix_new
(
fd
);
#else
ntp
->
channel
=
g_io_channel_win32_new_socket
(
fd
);
#endif
/* NULL encoding means the stream is binary safe */
g_io_channel_set_encoding
(
ntp
->
channel
,
NULL
,
NULL
);
/* no buffering */
g_io_channel_set_buffered
(
ntp
->
channel
,
false
);
ntp
->
source
=
g_io_create_watch
(
ntp
->
channel
,
G_IO_IN
);
g_source_set_callback
(
ntp
->
source
,
(
GSourceFunc
)
ntp_in_event
,
ntp
,
NULL
);
g_source_attach
(
ntp
->
source
,
io_thread_context
());
ntp
->
udp
=
udp_server_new
(
ntp
->
port
,
&
ntp_server_handler
,
ntp
,
error_r
);
return
ntp
->
udp
!=
NULL
;
}
void
ntp_server_close
(
struct
ntp_server
*
ntp
)
{
if
(
ntp
->
source
!=
NULL
)
{
g_source_destroy
(
ntp
->
source
);
g_source_unref
(
ntp
->
source
)
;
if
(
ntp
->
udp
!=
NULL
)
{
udp_server_free
(
ntp
->
udp
);
ntp
->
udp
=
NULL
;
}
if
(
ntp
->
channel
!=
NULL
)
g_io_channel_unref
(
ntp
->
channel
);
if
(
ntp
->
fd
>=
0
)
close
(
ntp
->
fd
);
}
src/ntp_server.h
View file @
74a39c71
...
...
@@ -28,17 +28,15 @@ struct timeval;
struct
ntp_server
{
unsigned
short
port
;
int
fd
;
GIOChannel
*
channel
;
GSource
*
source
;
struct
udp_server
*
udp
;
};
void
ntp_server_init
(
struct
ntp_server
*
ntp
);
void
ntp_server_open
(
struct
ntp_server
*
ntp
,
int
fd
);
bool
ntp_server_open
(
struct
ntp_server
*
ntp
,
GError
**
error_r
);
void
ntp_server_close
(
struct
ntp_server
*
ntp
);
...
...
src/output/raop_output_plugin.c
View file @
74a39c71
...
...
@@ -799,13 +799,9 @@ raop_output_open(void *data, struct audio_format *audio_format, GError **error_r
if
(
raop_session
->
data_fd
<
0
)
return
false
;
int
fd
=
open_udp_socket
(
NULL
,
&
raop_session
->
ntp
.
port
,
error_r
);
if
(
fd
<
0
)
if
(
!
ntp_server_open
(
&
raop_session
->
ntp
,
error_r
))
return
false
;
ntp_server_open
(
&
raop_session
->
ntp
,
fd
);
raop_session
->
ctrl
.
fd
=
open_udp_socket
(
NULL
,
&
raop_session
->
ctrl
.
port
,
error_r
);
...
...
src/udp_server.c
0 → 100644
View file @
74a39c71
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "udp_server.h"
#include "io_thread.h"
#include <glib.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#ifdef WIN32
#define WINVER 0x0501
#include <ws2tcpip.h>
#include <winsock.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#endif
struct
udp_server
{
const
struct
udp_server_handler
*
handler
;
void
*
handler_ctx
;
int
fd
;
GIOChannel
*
channel
;
GSource
*
source
;
char
buffer
[
8192
];
};
static
gboolean
udp_in_event
(
G_GNUC_UNUSED
GIOChannel
*
source
,
G_GNUC_UNUSED
GIOCondition
condition
,
gpointer
data
)
{
struct
udp_server
*
udp
=
data
;
struct
sockaddr_storage
address_storage
;
struct
sockaddr
*
address
=
(
struct
sockaddr
*
)
&
address_storage
;
socklen_t
address_length
=
sizeof
(
address_storage
);
ssize_t
nbytes
=
recvfrom
(
udp
->
fd
,
udp
->
buffer
,
sizeof
(
udp
->
buffer
),
MSG_DONTWAIT
,
address
,
&
address_length
);
if
(
nbytes
<=
0
)
return
true
;
udp
->
handler
->
datagram
(
udp
->
fd
,
udp
->
buffer
,
nbytes
,
address
,
address_length
,
udp
->
handler_ctx
);
return
true
;
}
struct
udp_server
*
udp_server_new
(
unsigned
port
,
const
struct
udp_server_handler
*
handler
,
void
*
ctx
,
GError
**
error_r
)
{
int
fd
=
socket
(
PF_INET
,
SOCK_DGRAM
,
0
);
if
(
fd
<
0
)
{
g_set_error
(
error_r
,
udp_server_quark
(),
errno
,
"failed to create UDP socket: %s"
,
g_strerror
(
errno
));
return
NULL
;
}
const
struct
sockaddr_in
address
=
{
.
sin_family
=
AF_INET
,
.
sin_addr
=
{
.
s_addr
=
htonl
(
INADDR_ANY
),
},
.
sin_port
=
htons
(
port
),
};
if
(
bind
(
fd
,
(
const
struct
sockaddr
*
)
&
address
,
sizeof
(
address
))
<
0
)
{
g_set_error
(
error_r
,
udp_server_quark
(),
errno
,
"failed to bind UDP port %u: %s"
,
port
,
g_strerror
(
errno
));
close
(
fd
);
return
NULL
;
}
struct
udp_server
*
udp
=
g_new
(
struct
udp_server
,
1
);
udp
->
handler
=
handler
;
udp
->
handler_ctx
=
ctx
;
udp
->
fd
=
fd
;
#ifndef G_OS_WIN32
udp
->
channel
=
g_io_channel_unix_new
(
fd
);
#else
udp
->
channel
=
g_io_channel_win32_new_socket
(
fd
);
#endif
/* NULL encoding means the stream is binary safe */
g_io_channel_set_encoding
(
udp
->
channel
,
NULL
,
NULL
);
/* no buffering */
g_io_channel_set_buffered
(
udp
->
channel
,
false
);
udp
->
source
=
g_io_create_watch
(
udp
->
channel
,
G_IO_IN
);
g_source_set_callback
(
udp
->
source
,
(
GSourceFunc
)
udp_in_event
,
udp
,
NULL
);
g_source_attach
(
udp
->
source
,
io_thread_context
());
return
udp
;
}
void
udp_server_free
(
struct
udp_server
*
udp
)
{
g_source_destroy
(
udp
->
source
);
g_source_unref
(
udp
->
source
);
g_io_channel_unref
(
udp
->
channel
);
close
(
udp
->
fd
);
g_free
(
udp
);
}
src/udp_server.h
0 → 100644
View file @
74a39c71
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_UDP_SERVER_H
#define MPD_UDP_SERVER_H
#include <glib.h>
#include <stddef.h>
struct
sockaddr
;
struct
udp_server_handler
{
/**
* A datagram was received.
*/
void
(
*
datagram
)(
int
fd
,
const
void
*
data
,
size_t
length
,
const
struct
sockaddr
*
source_address
,
size_t
source_address_length
,
void
*
ctx
);
};
static
inline
GQuark
udp_server_quark
(
void
)
{
return
g_quark_from_static_string
(
"udp_server"
);
}
struct
udp_server
*
udp_server_new
(
unsigned
port
,
const
struct
udp_server_handler
*
handler
,
void
*
ctx
,
GError
**
error_r
);
void
udp_server_free
(
struct
udp_server
*
udp
);
#endif
test/run_ntp_server.c
View file @
74a39c71
...
...
@@ -46,78 +46,6 @@ on_quit(void)
io_thread_quit
();
}
static
int
bind_host
(
int
sd
,
char
*
hostname
,
unsigned
long
ulAddr
,
unsigned
short
*
port
)
{
struct
sockaddr_in
my_addr
;
socklen_t
nlen
=
sizeof
(
struct
sockaddr
);
struct
hostent
*
h
;
memset
(
&
my_addr
,
0
,
sizeof
(
my_addr
));
/* use specified hostname */
if
(
hostname
)
{
/* get server IP address (no check if input is IP address or DNS name) */
h
=
gethostbyname
(
hostname
);
if
(
h
==
NULL
)
{
if
(
strstr
(
hostname
,
"255.255.255.255"
)
==
hostname
)
{
my_addr
.
sin_addr
.
s_addr
=-
1
;
}
else
{
if
((
my_addr
.
sin_addr
.
s_addr
=
inet_addr
(
hostname
))
==
0xFFFFFFFF
)
{
return
-
1
;
}
}
my_addr
.
sin_family
=
AF_INET
;
}
else
{
my_addr
.
sin_family
=
h
->
h_addrtype
;
memcpy
((
char
*
)
&
my_addr
.
sin_addr
.
s_addr
,
h
->
h_addr_list
[
0
],
h
->
h_length
);
}
}
else
{
// if hostname=NULL, use INADDR_ANY
if
(
ulAddr
)
my_addr
.
sin_addr
.
s_addr
=
ulAddr
;
else
my_addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
my_addr
.
sin_family
=
AF_INET
;
}
/* bind a specified port */
my_addr
.
sin_port
=
htons
(
*
port
);
if
(
bind
(
sd
,
(
struct
sockaddr
*
)
&
my_addr
,
sizeof
(
my_addr
))
<
0
)
{
return
-
1
;
}
if
(
*
port
==
0
)
{
getsockname
(
sd
,
(
struct
sockaddr
*
)
&
my_addr
,
&
nlen
);
*
port
=
ntohs
(
my_addr
.
sin_port
);
}
return
0
;
}
static
int
open_udp_socket
(
char
*
hostname
,
unsigned
short
*
port
)
{
int
sd
;
int
size
=
30000
;
/* socket creation */
sd
=
socket
(
PF_INET
,
SOCK_DGRAM
,
0
);
if
(
sd
<
0
)
{
return
-
1
;
}
if
(
setsockopt
(
sd
,
SOL_SOCKET
,
SO_SNDBUF
,
(
void
*
)
&
size
,
sizeof
(
size
))
<
0
)
{
return
-
1
;
}
if
(
bind_host
(
sd
,
hostname
,
0
,
port
))
{
close
(
sd
);
return
-
1
;
}
return
sd
;
}
int
main
(
G_GNUC_UNUSED
int
argc
,
G_GNUC_UNUSED
char
**
argv
)
{
...
...
@@ -128,15 +56,14 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
struct
ntp_server
ntp
;
ntp_server_init
(
&
ntp
);
int
fd
=
open_udp_socket
(
NULL
,
&
ntp
.
port
);
if
(
fd
<
0
)
{
g_printerr
(
"Failed to create UDP socket
\n
"
);
ntp_server_close
(
&
ntp
);
GError
*
error
=
NULL
;
if
(
!
ntp_server_open
(
&
ntp
,
&
error
))
{
io_thread_deinit
();
g_printerr
(
"%s
\n
"
,
error
->
message
);
g_error_free
(
error
);
return
EXIT_FAILURE
;
}
ntp_server_open
(
&
ntp
,
fd
);
io_thread_run
();
ntp_server_close
(
&
ntp
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment