Hi,
This is my 3rd email on this issue.. Please, help me with it.
I am having the problem with SUBSCRIBE requests in ser 0.9.3. I am not
using PA module,
because my PA and Watcher are located on the client side.
Whenever I try to subscribe to a presence with any entity OTHER than
myself, SER seems to receive the SUBSCRIBE request, however, it does
not forward it. Instead my application keeps on retransmitting
SUBSCRIBEs until SER replies with 408 Timeout... The same things
happen with NOTIFYs.
I must also mention that it is NOT all the time that SER replies with
timeout... Just most of the times. And only sometimes it lets the
SUBSCRIBE through (for that, I have to restart my app. again and
again, until I get the right result).
I included ser.cfg + traces. I've tried to use stateless forwarding (
forward(uri:host, uri:port) ) instead of stateful (as shown in my
ser.cfg), but it didnt work either.
Please, tell me what is wrong, because I'm out of ideas here... I
would settle even for reinstalling SER, if it's necessary.
Here's ser.cfg:
# ----------- global configuration parameters ------------------------
debug=3 # debug level (cmd line: -dddddddddd)
fork=yes
log_stderror=no # (cmd line: -E)
/* Uncomment these lines to enter debugging mode
fork=no
log_stderror=yes
*/
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
#port=5060
#children=4
fifo="/tmp/ser_fifo"
fifo_mode=0766
sip_warning=yes
server_signature=yes
alias=sip.interlab.ait.ac.th
# ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database
loadmodule "/usr/local/lib/ser/modules/mysql.so"
loadmodule "/usr/local/lib/ser/modules/sl.so"
loadmodule "/usr/local/lib/ser/modules/tm.so"
loadmodule "/usr/local/lib/ser/modules/rr.so"
loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
loadmodule "/usr/local/lib/ser/modules/usrloc.so"
loadmodule "/usr/local/lib/ser/modules/registrar.so"
loadmodule "/usr/local/lib/ser/modules/textops.so"
loadmodule "/usr/local/lib/ser/modules/auth.so"
loadmodule "/usr/local/lib/ser/modules/auth_db.so"
loadmodule "/usr/local/lib/ser/modules/uri.so"
loadmodule "/usr/local/lib/ser/modules/uri_db.so"
loadmodule "/usr/local/lib/ser/modules/exec.so"
loadmodule "/usr/local/lib/ser/modules/pa.so"
# ----------------- setting module-specific parameters ---------------
modparam("usrloc", "db_mode", 2)
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("rr", "enable_full_lr", 1)
# ------------------------- request routing logic -------------------
route{
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
log(1, "Message has too many hops. Message disgarted");
sl_send_reply("483","Too Many Hops");
break;
};
if (msg:len >= 4096 ) {
log(1, "Message too big. Message disgarted");
sl_send_reply("513", "Message too big");
break;
};
#if (method!="REGISTER" ) record_route();
#if (loose_route()) {
# # mark routing logic in request
# append_hf("P-hint: rr-enforced\r\n");
# route(1);
# break;
#};
if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
route(1);
break;
};
if (uri==myself) {
if (method=="REGISTER") {
if (!www_authorize("sip.interlab.ait.ac.th", "subscriber")) {
log(1, "Authentication for REGISTER");
www_challenge("sip.interlab.ait.ac.th", "0");
break;
};
#if(!is_user("replicator") & !check_to() ){
# log(1, "Unregistered user registration attempt\n");
# sl_send_reply("403", "Forbidden - Registered
users only");
# break;
#};
if(!save("location")) {
log(1, "Error saving AOR");
sl_reply_error();
};
break;
};
lookup("aliases");
if (uri!=myself) {
append_hf("P-hint: outbound alias\r\n");
route(1);
break;
};
#Handle local offline or non-existent users
if(method=="INVITE") {
if(!lookup("location") ) {
log(1, "INVITE for an offline user processing");
route(3); #offline and non-existent users
break;
};
};
if(method=="SUBSCRIBE") {
if (!www_authorize("sip.interlab.ait.ac.th", "subscriber")) {
log(1, "Authentication for SUBSCRIBE");
www_challenge("sip.interlab.ait.ac.th", "0");
break;
};
if(!lookup("location") ) {
log(1, "No registered user found for SUBSCRIBE");
sl_send_reply("404", "Not Found");
break;
};
};
# native SIP destinations are handled using our USRLOC DB
if(method=="NOTIFY") {
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
break;
};
log(1, "NOTIFY reveived");
};
};
append_hf("P-hint: usrloc applied\r\n");
route(1);
}
route[1]
{
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}
# ------------ Process offline and non-existent users ----------
route[3] {
# do not continue if it is a retransmission
if(!t_newtran()) {
sl_reply_error();
break;
};
# use external script to send an email notification in case
# user is offline, or just reply back with 404 (Not Found) if
# the user is not a registered user
if(!exec_msg('/home/andrey/sip_email.sh') ) {
t_reply("404", "Not Found - User does not exist");
}
else {
t_reply("404", "Not Found - User offline");
};
break;
}
. . . . . . . .
Here are the traces:
Message 1 from 203.159.32.39:5060 to 203.159.31.36:5060
SUBSCRIBE sip:12345@sip.interlab.ait.ac.th SIP/2.0
Call-ID: 7762edc6f3954c87c8b95a0270653250(a)203.159.32.39
CSeq: 1 SUBSCRIBE
From: "Andrey Kuprianov" <sip:andrey@sip.interlab.ait.ac.th>;tag=15493888
To: <sip:12345@sip.interlab.ait.ac.th>
Via: SIP/2.0/UDP
203.159.32.39:5060;branch=z9hG4bK3ad443c5b49de4b050bd2b028597a868
Max-Forwards: 70
Allow: REGISTER,INVITE,BYE,ACK,CANCEL,SUBSCRIBE,NOTIFY,MESSAGE
User-Agent: IntERLab User Agent 1.0a
Event: presence
Expires: 600
Accept: application/pidf+xml,application/xpidf+xml,application/xvcresource+xml
Contact: <sip:andrey@203.159.32.39:5060>
Content-Length: 0
Message 2 from 203.159.31.36:5060 to 203.159.32.39:5060
SIP/2.0 401 Unauthorized
Call-ID: 7762edc6f3954c87c8b95a0270653250(a)203.159.32.39
CSeq: 1 SUBSCRIBE
From: "Andrey Kuprianov" <sip:andrey@sip.interlab.ait.ac.th>;tag=15493888
To: <sip:12345@sip.interlab.ait.ac.th>;tag=1a5a85ff3e08e000f4c2527642cf14ac.5e75
Via: SIP/2.0/UDP
203.159.32.39:5060;branch=z9hG4bK3ad443c5b49de4b050bd2b028597a868
WWW-Authenticate: Digest
realm="sip.interlab.ait.ac.th",nonce="439ee222efefefbb8cbb78e75d6d15b723a1e1d0"
Server: Sip EXpress router (0.9.3 (i386/freebsd))
Warning: 392 203.159.31.36:5060 "Noisy feedback tells: pid=17754
req_src_ip=203.159.32.39 req_src_port=5060
in_uri=sip:12345@sip.interlab.ait.ac.th
out_uri=sip:12345@sip.interlab.ait.ac.th via_cnt==1"
Content-Length: 0
Message 3 from 203.159.32.39:5060 to 203.159.31.36:5060
SUBSCRIBE sip:12345@sip.interlab.ait.ac.th SIP/2.0
Call-ID: 7762edc6f3954c87c8b95a0270653250(a)203.159.32.39
CSeq: 2 SUBSCRIBE
To: <sip:12345@sip.interlab.ait.ac.th>
Via: SIP/2.0/UDP
203.159.32.39:5060;branch=z9hG4bK991c906a283ca5d57e8856c98097e81c
Max-Forwards: 70
Allow: REGISTER,INVITE,BYE,ACK,CANCEL,SUBSCRIBE,NOTIFY,MESSAGE
User-Agent: IntERLab User Agent 1.0a
Event: presence
Expires: 600
Accept: application/pidf+xml,application/xpidf+xml,application/xvcresource+xml
Contact: <sip:andrey@203.159.32.39:5060>
Authorization: Digest
username="andrey",realm="sip.interlab.ait.ac.th",nonce="439ee222efefefbb8cbb78e75d6d15b723a1e1d0",uri="sip:12345@sip.interlab.ait.ac.th",response="1c7fa7ceb1f654d0e2ea91c54823bb8d"
From: "Andrey Kuprianov" <sip:andrey@sip.interlab.ait.ac.th>;tag=15493888
Content-Length: 0
Message 4 from 203.159.32.39:5060 to 203.159.31.36:5060
SUBSCRIBE sip:12345@sip.interlab.ait.ac.th SIP/2.0
Call-ID: 7762edc6f3954c87c8b95a0270653250(a)203.159.32.39
CSeq: 2 SUBSCRIBE
To: <sip:12345@sip.interlab.ait.ac.th>
Via: SIP/2.0/UDP
203.159.32.39:5060;branch=z9hG4bK991c906a283ca5d57e8856c98097e81c
Max-Forwards: 70
Allow: REGISTER,INVITE,BYE,ACK,CANCEL,SUBSCRIBE,NOTIFY,MESSAGE
User-Agent: IntERLab User Agent 1.0a
Event: presence
Expires: 600
Accept: application/pidf+xml,application/xpidf+xml,application/xvcresource+xml
Contact: <sip:andrey@203.159.32.39:5060>
Authorization: Digest
username="andrey",realm="sip.interlab.ait.ac.th",nonce="439ee222efefefbb8cbb78e75d6d15b723a1e1d0",uri="sip:12345@sip.interlab.ait.ac.th",response="1c7fa7ceb1f654d0e2ea91c54823bb8d"
From: "Andrey Kuprianov" <sip:andrey@sip.interlab.ait.ac.th>;tag=15493888
Content-Length: 0
Message 5 from 203.159.32.39:5060 to 203.159.31.36:5060
SUBSCRIBE sip:12345@sip.interlab.ait.ac.th SIP/2.0
Call-ID: 7762edc6f3954c87c8b95a0270653250(a)203.159.32.39
CSeq: 2 SUBSCRIBE
To: <sip:12345@sip.interlab.ait.ac.th>
Via: SIP/2.0/UDP
203.159.32.39:5060;branch=z9hG4bK991c906a283ca5d57e8856c98097e81c
Max-Forwards: 70
Allow: REGISTER,INVITE,BYE,ACK,CANCEL,SUBSCRIBE,NOTIFY,MESSAGE
User-Agent: IntERLab User Agent 1.0a
Event: presence
Expires: 600
Accept: application/pidf+xml,application/xpidf+xml,application/xvcresource+xml
Contact: <sip:andrey@203.159.32.39:5060>
Authorization: Digest
username="andrey",realm="sip.interlab.ait.ac.th",nonce="439ee222efefefbb8cbb78e75d6d15b723a1e1d0",uri="sip:12345@sip.interlab.ait.ac.th",response="1c7fa7ceb1f654d0e2ea91c54823bb8d"
From: "Andrey Kuprianov" <sip:andrey@sip.interlab.ait.ac.th>;tag=15493888
Content-Length: 0
. . . . . .
And so it goes, until SER replies with Timeout.
Can you tell me what is wrong???
Andrey.
Below is the common configuration of the network.
Telephone -- PSTN -- G/W -- openser -- softphone (eg windows messenger)
I can make call from softphone to Telephone. However, it is failed to
make call from Telephone to softphone. I wonder why it happened and
any reference to trace the problem. Anyone have such experience?
Hello all,
I am trying to integrate SER and Asterisk. So could anybody
please guide me with the changes and the configuration that I need to in
either SER or Asterisk for achieving it.
Like for suppose I want to achieve a call being placed from
a User 1 registered to SER to User 2 who is registered to Asterisk.. So
how do I move ahead to achieve the same.
And are there any other new things that one can come up
with using SER and Asterisk together which can't be achieved using SER
or Asterisk alone? Kindly do let me know.
Thanks and Regards,
Bharat Sarvan
The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy all copies of this message and any attachments.
WARNING: Computer viruses can be transmitted via email. The recipient should check this email and any attachments for the presence of viruses. The company accepts no liability for any damage caused by any virus transmitted by this email.
www.wipro.com
If SER is running, that means fifo is ON.
>From: Ken Rozinsky <xraycharlie(a)gmail.com>
>To: Kapil Dhawan <sersavvy(a)hotmail.com>
>Subject: Re: [Serusers] simple click-to-call
>Date: Tue, 13 Dec 2005 11:24:58 -0700
>
>Thanks for the info.
>
>A question for you if you have the time:
>
>The script checks if it can write to /tmp/ser_fifo and fails.
>The comment mention having to have the fifo server running. How do I
>check if this is running or not?
>
>I see in the documantation a mention of fifo_db but I don;t think I
>need this as am not worried about persistance.
>
>The permissions on /tmp/ser_fifo are currently prw-rw----
>
>I tried running the script as root and get the write error also.
>
>Thanks again.
>
>Regards
>
>Ken
>
>
>On 12/12/05, Kapil Dhawan <sersavvy(a)hotmail.com> wrote:
> > Ken
> >
> > Click-to-dial is present in example directoy as ctd.sh. It takes two
> > arguments From and To. To run it from Web-interface, you need to run
>this
> > command thru script.
> >
> > Regards
> >
> >
> > >From: Ken Rozinsky <xraycharlie(a)gmail.com>
> > >To: serusers(a)lists.iptel.org
> > >Subject: [Serusers] simple click-to-call
> > >Date: Mon, 12 Dec 2005 17:27:18 -0700
> > >
> > >Hello,
> > >
> > >As an exercise in learning how all this stuff works, I'm trying to set
> > >up a simple click-to-call service for our office to use. And
> > >potentialy to allow clients to use vai the web site to save them on
> > >the long distance charges.
> > >
> > >I set up Asterisk with the TACI script and got it to all work with an
> > >account on gafachi but I noticed that it could only handle one call at
> > >a time.
> > >
> > >I was told that openSer would allow more than one call at a time so
> > >I've installed it (basic no mySql) and have it up and running.
> > >
> > >Now, being new to this I have no idea how to connct to gafachi and do
> > >a click-to-call type thing.
> > >
> > >Would anybody be able to help me with this?
> > >
> > >Regards
> > >
> > >_______________________________________________
> > >Serusers mailing list
> > >serusers(a)lists.iptel.org
> > >http://lists.iptel.org/mailman/listinfo/serusers
> >
> > _________________________________________________________________
> > Shah Rukh fan? Know all about the Baadshah of Bollywood. On MSN Search
> > http://server1.msn.co.in/profile/shahrukh.asp
> >
> >
_________________________________________________________________
How good are you in a Formula One car? Play now
http://server1.msn.co.in/sp05/tataracing/onlinegame.asp
Dear All,
I encountered a problem like this.
Case 1:
-------
If UA1 calls UA2 using the following:
Normal call:
UA1 ------invite -------port 30000 -----> UA2
UA1 <--------OK---port 26000--------------UA2
The connection and media is established.
Hold the call:
UA1------invite ---port 30000 (hold)--> UA2
UA1 <----------OK port 26000----------UA2
The media is in hold state.
Unhold the call:
UA1------invite ----port 30000--------->UA2
UA1 <---------OK port 260000----------UA2
Media resume.
The above mentioned work fine with mediaproxy.
Case 2:
-------
If UA1 calls UA2 using the following:
Normal call:
UA1 ------invite -------port 30000 -----> UA2
UA1 <--------OK---port 26000--------------UA2
The connection and media is established.
Hold the call:
UA1------invite ---port 30000 (hold)--> UA2
UA1 <----------OK port 26000----------UA2
The media is in hold state.
Unhold the call:
UA1------invite ----port 30001--------->UA2
UA1 <---------OK port 260000----------UA2
*****Noticed that the reinvite has a different port!
In this situation, media does not resume and mediaproxy has a "stray
hold" session.
I tested case2 without flowing through the mediaproxy and found that the
call can be hold/unhold successfully.
I am not familiar with RFC at all, please help!
(1) I would like to know whether it is valid to reinvite with a
different port as in case 2, i.e., is the UA1 ill-behave in case 2 when
unhold the call with different port?
(2) Is the mediaproxy designed to work using the some port when
hold/unhold.
Thanks you very much for any help available.
Regards,
TC Chan
I am trying to have OpenSER forward registration requests to multiple Asterisk boxes with failover. Each Asterisk box has two ip addresses. My logic tries to relay to the first IP on the first Asterisk box (192.168.10.100). If that fails, it tries to relay to the second IP on the first Asterisk box (192.168.10.17). It then goes on and repeats the process with another Asterisk box who's IP's are 192.168.10.10.101 and 192.168.10.8.
Actually the first IP address on each Asterisk system is fake (100 and 101)... that's how I am testing that it will fail to the second one.
The openser.cfg below is causing this to be logged to messages:
Dec 13 17:50:08 bil-pdev-3 openser[22318]: route10: Asterisk-1, NIC-1
Dec 13 17:50:08 bil-pdev-3 openser[22318]: route20: Asterisk-2, NIC-1
Dec 13 17:50:08 bil-pdev-3 openser[22318]: ERROR: t_newtran: transaction already in process 0xb6126560 < --- Why?
Dec 13 17:50:08 bil-pdev-3 openser[22318]: route20: t_relay returned error <--- Why?
Dec 13 17:50:09 bil-pdev-3 openser[22328]: failure21: Failed to register with Asterisk-2, NIC-1
Dec 13 17:50:09 bil-pdev-3 openser[22328]: route22: Asterisk-2, NIC-2
Dec 13 17:50:09 bil-pdev-3 openser[22328]: route22: End of routine
Dec 13 17:50:10 bil-pdev-3 openser[22322]: User local found
Dec 13 17:50:10 bil-pdev-3 openser[22320]: User local found
Why am I getting the t_newtran and t_relay errors in there? What am I doing wrong? I'm just calling rewritehostport(next-ip), followed by append_branch() and t_relay. In fact something really weird happens. When I have the code there for route[20], failure_route[21] and route[22], it causes the code for the first three routing blocks, route[10], failure_route[11] and route[12] to act differently. It seems to make route20 fail to connect eventhough it comes AFTER it in the code.
I'd really appreciate some help! Am I doing something wrong with rewritehostport and append_branch, because quite frankly the docs are terrible.
if ( method == REGISTER ) {
if ( !www_authorize("voip.com", "subscriber") ) {
www_challenge("voip.com", "0");
};
save("location");
route(10);
route(20);
#
# First Asterisk System.
#
# Try first IP on this system (fake - will fail)
route[10] {
xlog ("L_INFO","route10: Asterisk-1, NIC-1");
t_on_failure("11");
rewritehostport("192.168.10.100:5060");
append_branch();
if ( !t_relay() ) {
xlog ("L_INFO","route10: t_relay returned error");
}
}
failure_route[11] {
xlog ("L_INFO","failure11: Failed to register with Asterisk-1, NIC-1");
route(12);
}
# Try second IP on this system (real - should work)
route[12] {
xlog ("L_INFO","route12: Asterisk-1, NIC-2");
t_on_failure("13");
rewritehostport("192.168.10.17:5060");
append_branch();
if ( !t_relay() ) {
xlog ("L_INFO","route12: t_relay returned error");
}
xlog ("L_INFO","route12: End of routine");
return;
}
#
# Second Asterisk System
#
# Try first IP on this system (fake - will fail)
route[20] {
xlog ("L_INFO","route20: Asterisk-2, NIC-1");
t_on_failure("21");
rewritehostport("192.168.10.101:5060");
append_branch();
if ( !t_relay() ) {
xlog ("L_INFO","route20: t_relay returned error");
}
}
failure_route[21] {
xlog ("L_INFO","failure21: Failed to register with Asterisk-2, NIC-1");
route(22);
}
# Try second IP on this system (real - should work)
route[22] {
xlog ("L_INFO","route22: Asterisk-2, NIC-2");
t_on_failure("23");
rewritehostport("192.168.10.8:5060");
append_branch();
if ( !t_relay() ) {
xlog ("L_INFO","route22: t_relay returned error");
}
xlog ("L_INFO","route22: End of routine");
return;
}
Doug
Hello,
As an exercise in learning how all this stuff works, I'm trying to set
up a simple click-to-call service for our office to use. And
potentialy to allow clients to use vai the web site to save them on
the long distance charges.
I set up Asterisk with the TACI script and got it to all work with an
account on gafachi but I noticed that it could only handle one call at
a time.
I was told that openSer would allow more than one call at a time so
I've installed it (basic no mySql) and have it up and running.
Now, being new to this I have no idea how to connct to gafachi and do
a click-to-call type thing.
Would anybody be able to help me with this?
Regards
Hi All,
I am using ser 0.8.14 +asterisk B2bua.
Currently softphone is registering on standard sip port 5060 .
Is it possibe to use any other port like 5090 or 8069
I tried to do so by changing the listining port to 5090 in ser.cfg but in case the softphone is not getting register.
Here is the ser log
0(11348) SIP Request:
0(11348) method: <REGISTER>
0(11348) uri: <sip:192.168.1.100>
0(11348) version: <SIP/2.0>
0(11348) parse_headers: flags=1
0(11348) end of header reached, state=5
0(11348) parse_headers: Via found, flags=1
0(11348) parse_headers: this is the first via
0(11348) After parse_msg...
0(11348) preparing to run routing scripts...
0(11348) DEBUG : is_maxfwd_present: searching for max_forwards header
0(11348) parse_headers: flags=128
0(11348) DEBUG: is_maxfwd_present: value = 70
0(11348) parse_headers: flags=8
0(11348) DEBUG: add_param: tag=fa37b062306344d68023aed26289e820
0(11348) DEBUG: add_param: epid=f657995ecc
0(11348) end of header reached, state=29
0(11348) parse_headers: flags=256
0(11348) end of header reached, state=9
0(11348) DEBUG: get_hdr_field: <To> [37]; uri=[sip:2851816416@192.168.1.100:5090]
0(11348) DEBUG: to body [<sip:2851816416@192.168.1.100:5090>
]
0(11348) get_hdr_field: cseq <CSeq>: <1> <REGISTER>
0(11348) DEBUG: get_hdr_body : content_length=0
0(11348) found end of header
0(11348) find_first_route(): No Route headers found
0(11348) loose_route(): There is no Route HF
0(11348) parse_headers: flags=64
0(11348) parse_headers: flags=64
0(11348) parse_headers: flags=33554432
0(11348) check_self - checking if host==us: 13==13 && [192.168.1.100] == [192.168.1.100]
0(11348) check_self - checking if port 5090 matches port 5060
0(11348) check_self: host != me
0(11348) DEBUG: t_addifnew: msg id=1 , global msg id=0 , T on entrance=0xffffffff
0(11348) parse_headers: flags=-1
0(11348) parse_headers: flags=60
0(11348) t_lookup_request: start searching: hash=58712, isACK=0
0(11348) DEBUG: proceeding to pre-RFC3261 transaction matching
0(11348) DEBUG: t_lookup_request: no transaction found
0(11348) DEBUG: mk_proxy: doing DNS lookup...
0(11348) check_via_address(192.168.1.2, 192.168.1.2, 0)
0(11348) DEBUG: add_to_tail_of_timer[4]: 0xb6165fe8
0(11348) DEBUG: add_to_tail_of_timer[0]: 0xb6165ffc
0(11348) SER: new transaction fwd'ed
0(11348) DEBUG:destroy_avp_list: destroing list (nil)
0(11348) receive_msg: cleaning up
Please advise.
Thanks In Advance.
---------------------------------
Yahoo! Personals
Single? There's someone we'd like you to meet.
Lots of someones, actually. Yahoo! Personals
Hi All,
I am having trouble when trying to start SER. I am using Ser 0.8.14 on
Redhat ES 3.
When I am trying to start it gives
Segmentation Fault.
Can anybody suggess how to overcome this problem.
Thanks And Regards
Vidhya Sagar Dixit
---------------------------------
Yahoo! Shopping
Find Great Deals on Holiday Gifts at Yahoo! Shopping